Merge "ovs mech: bind only if user request switchdev"

This commit is contained in:
Jenkins 2017-09-15 11:07:47 +00:00 committed by Gerrit Code Review
commit 5e9651aeac
5 changed files with 62 additions and 19 deletions

View File

@ -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)

View File

@ -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

View File

@ -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):

View File

@ -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',

View File

@ -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()