Merge "ovs mech: bind only if user request switchdev"
This commit is contained in:
commit
5e9651aeac
@ -76,8 +76,17 @@ class SriovNicSwitchMechanismDriver(mech_agent.SimpleAgentMechanismDriverBase):
|
||||
"network %(network)s",
|
||||
{'port': context.current['id'],
|
||||
'network': context.network.current['id']})
|
||||
profile = context.current.get(portbindings.PROFILE)
|
||||
vnic_type = context.current.get(portbindings.VNIC_TYPE,
|
||||
portbindings.VNIC_NORMAL)
|
||||
capabilities = []
|
||||
if profile:
|
||||
capabilities = profile.get('capabilities', [])
|
||||
if (vnic_type == portbindings.VNIC_DIRECT and
|
||||
'switchdev' in capabilities):
|
||||
LOG.debug("Refusing to bind due to unsupported vnic_type: %s "
|
||||
"with switchdev capability", portbindings.VNIC_DIRECT)
|
||||
return
|
||||
if vnic_type not in self.supported_vnic_types:
|
||||
LOG.debug("Refusing to bind due to unsupported vnic_type: %s",
|
||||
vnic_type)
|
||||
|
@ -20,6 +20,7 @@ from neutron_lib.callbacks import events
|
||||
from neutron_lib.callbacks import registry
|
||||
from neutron_lib import constants
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log
|
||||
|
||||
from neutron.agent import securitygroups_rpc
|
||||
from neutron.plugins.common import constants as p_constants
|
||||
@ -28,6 +29,7 @@ from neutron.plugins.ml2.drivers.openvswitch.agent.common \
|
||||
import constants as a_const
|
||||
from neutron.services.qos.drivers.openvswitch import driver as ovs_qos_driver
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
IPTABLES_FW_DRIVER_FULL = ("neutron.agent.linux.iptables_firewall."
|
||||
"OVSHybridIptablesFirewallDriver")
|
||||
@ -74,6 +76,20 @@ class OpenvswitchMechanismDriver(mech_agent.SimpleAgentMechanismDriverBase):
|
||||
"""Currently Openvswitch driver doesn't support vlan transparency."""
|
||||
return False
|
||||
|
||||
def bind_port(self, context):
|
||||
vnic_type = context.current.get(portbindings.VNIC_TYPE,
|
||||
portbindings.VNIC_NORMAL)
|
||||
profile = context.current.get(portbindings.PROFILE)
|
||||
capabilities = []
|
||||
if profile:
|
||||
capabilities = profile.get('capabilities', [])
|
||||
if (vnic_type == portbindings.VNIC_DIRECT and
|
||||
'switchdev' not in capabilities):
|
||||
LOG.debug("Refusing to bind due to unsupported vnic_type: %s with "
|
||||
"no switchdev capability", portbindings.VNIC_DIRECT)
|
||||
return
|
||||
super(OpenvswitchMechanismDriver, self).bind_port(context)
|
||||
|
||||
def get_vif_type(self, context, agent, segment):
|
||||
caps = agent['configurations'].get('ovs_capabilities', {})
|
||||
if (any(x in caps.get('iface_types', []) for x
|
||||
|
@ -43,11 +43,12 @@ class FakeNetworkContext(api.NetworkContext):
|
||||
class FakePortContext(api.PortContext):
|
||||
def __init__(self, agent_type, agents, segments,
|
||||
vnic_type=portbindings.VNIC_NORMAL,
|
||||
original=None):
|
||||
original=None, profile=None):
|
||||
self._agent_type = agent_type
|
||||
self._agents = agents
|
||||
self._network_context = FakeNetworkContext(segments)
|
||||
self._bound_vnic_type = vnic_type
|
||||
self._bound_profile = profile
|
||||
self._bound_segment_id = None
|
||||
self._bound_vif_type = None
|
||||
self._bound_vif_details = None
|
||||
@ -56,7 +57,8 @@ class FakePortContext(api.PortContext):
|
||||
@property
|
||||
def current(self):
|
||||
return {'id': PORT_ID,
|
||||
portbindings.VNIC_TYPE: self._bound_vnic_type}
|
||||
portbindings.VNIC_TYPE: self._bound_vnic_type,
|
||||
portbindings.PROFILE: self._bound_profile}
|
||||
|
||||
@property
|
||||
def original(self):
|
||||
|
@ -13,6 +13,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import mock
|
||||
from neutron_lib.api.definitions import portbindings
|
||||
from neutron_lib import constants
|
||||
from neutron_lib.plugins.ml2 import api
|
||||
@ -24,25 +25,16 @@ from neutron.plugins.ml2.drivers.mech_sriov.mech_driver \
|
||||
from neutron.plugins.ml2.drivers.mech_sriov.mech_driver import mech_driver
|
||||
from neutron.tests.unit.plugins.ml2 import _test_mech_agent as base
|
||||
|
||||
MELLANOX_CONNECTX3_PCI_INFO = '15b3:1004'
|
||||
|
||||
|
||||
class TestFakePortContext(base.FakePortContext):
|
||||
def __init__(self, agent_type, agents, segments,
|
||||
vnic_type=portbindings.VNIC_NORMAL,
|
||||
profile={'pci_vendor_info':
|
||||
MELLANOX_CONNECTX3_PCI_INFO}):
|
||||
profile=None):
|
||||
super(TestFakePortContext, self).__init__(agent_type,
|
||||
agents,
|
||||
segments,
|
||||
vnic_type)
|
||||
self._bound_profile = profile
|
||||
|
||||
@property
|
||||
def current(self):
|
||||
return {'id': base.PORT_ID,
|
||||
portbindings.VNIC_TYPE: self._bound_vnic_type,
|
||||
portbindings.PROFILE: self._bound_profile}
|
||||
vnic_type=vnic_type,
|
||||
profile=profile)
|
||||
|
||||
def set_binding(self, segment_id, vif_type, vif_details, state):
|
||||
self._bound_segment_id = segment_id
|
||||
@ -145,6 +137,18 @@ class SriovSwitchMechVnicTypeTestCase(SriovNicSwitchMechanismBaseTestCase):
|
||||
self._check_vif_type_for_vnic_type(portbindings.VNIC_DIRECT_PHYSICAL,
|
||||
portbindings.VIF_TYPE_HOSTDEV_PHY)
|
||||
|
||||
@mock.patch.object(mech_driver.SriovNicSwitchMechanismDriver,
|
||||
'try_to_bind_segment_for_agent')
|
||||
def test_vnic_type_direct_with_switchdev_cap(self, mocked_bind_segment):
|
||||
profile = {'capabilities': ['switchdev']}
|
||||
context = TestFakePortContext(self.AGENT_TYPE,
|
||||
self.AGENTS,
|
||||
self.VLAN_SEGMENTS,
|
||||
portbindings.VNIC_DIRECT,
|
||||
profile)
|
||||
self.driver.bind_port(context)
|
||||
mocked_bind_segment.assert_not_called()
|
||||
|
||||
|
||||
class SriovSwitchMechVifDetailsTestCase(SriovNicSwitchMechanismBaseTestCase):
|
||||
VLAN_SEGMENTS = [{api.ID: 'vlan_segment_id',
|
||||
|
@ -13,6 +13,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
from neutron_lib.api.definitions import portbindings
|
||||
from neutron_lib.callbacks import events
|
||||
from neutron_lib.callbacks import registry
|
||||
@ -243,12 +244,23 @@ class OpenvswitchMechanismDPDKTestCase(OpenvswitchMechanismBaseTestCase):
|
||||
|
||||
class OpenvswitchMechanismSRIOVTestCase(OpenvswitchMechanismBaseTestCase):
|
||||
|
||||
def _make_port_ctx(self, agents):
|
||||
def _make_port_ctx(self, agents, profile=None):
|
||||
segments = [{api.ID: 'local_segment_id', api.NETWORK_TYPE: 'local'}]
|
||||
return base.FakePortContext(self.AGENT_TYPE, agents, segments,
|
||||
vnic_type=portbindings.VNIC_DIRECT)
|
||||
vnic_type=portbindings.VNIC_DIRECT,
|
||||
profile=profile)
|
||||
|
||||
def test_get_vif_type(self):
|
||||
@mock.patch('neutron.plugins.ml2.drivers.mech_agent.'
|
||||
'SimpleAgentMechanismDriverBase.bind_port')
|
||||
def test_bind_port_sriov_legacy(self, mocked_bind_port):
|
||||
context = self._make_port_ctx(self.AGENTS)
|
||||
result = self.driver.get_vif_type(context, self.AGENTS[0], None)
|
||||
self.assertEqual(self.VIF_TYPE, result)
|
||||
self.driver.bind_port(context)
|
||||
mocked_bind_port.assert_not_called()
|
||||
|
||||
@mock.patch('neutron.plugins.ml2.drivers.mech_agent.'
|
||||
'SimpleAgentMechanismDriverBase.bind_port')
|
||||
def test_bind_port_sriov_switchdev(self, mocked_bind_port):
|
||||
profile = {'capabilities': ['switchdev']}
|
||||
context = self._make_port_ctx(self.AGENTS, profile=profile)
|
||||
self.driver.bind_port(context)
|
||||
mocked_bind_port.assert_called()
|
||||
|
Loading…
Reference in New Issue
Block a user