From 2c60278992d5a217241054444ed0ca6e1d2f3e5c Mon Sep 17 00:00:00 2001 From: Brent Eagles Date: Mon, 9 Nov 2015 09:26:53 -0330 Subject: [PATCH] Adding a VNIC type for physical functions This change adds a new VNIC type to distinguish between virtual and physical functions in SR-IOV. The new VNIC type 'direct-physical' deviates from the behavior of 'direct' VNICs for virtual functions. While neutron tracks the resource as a port, it does not currently perform any management functions. Future changes may extend the segment mapping functionality that is currently based on agent configuration to include direct types. However, the direct-physical VNICs will not have functional parity with the other SR-IOV VNIC types in that quality of service and port security functionality is not available. APIImpact DocImpact: Add description for new 'direct-physical' VNIC type. Closes-Bug: #1500993 Change-Id: If1ab969c2002c649a3d51635ca2765c262e2d37f --- neutron/extensions/portbindings.py | 4 +++- .../mech_sriov/agent/sriov_nic_agent.py | 8 ++++++++ .../mech_sriov/mech_driver/mech_driver.py | 18 ++++++++++++++++-- .../mech_sriov/agent/test_sriov_nic_agent.py | 8 ++++++++ .../mech_driver/test_mech_sriov_nic_switch.py | 13 +++++++++++++ .../direct-physical-vnic-878d15bdb758b70e.yaml | 6 ++++++ 6 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 releasenotes/notes/direct-physical-vnic-878d15bdb758b70e.yaml diff --git a/neutron/extensions/portbindings.py b/neutron/extensions/portbindings.py index 67338c37409..e9dc8b8261c 100644 --- a/neutron/extensions/portbindings.py +++ b/neutron/extensions/portbindings.py @@ -80,7 +80,9 @@ VNIC_NORMAL = 'normal' VNIC_DIRECT = 'direct' VNIC_MACVTAP = 'macvtap' VNIC_BAREMETAL = 'baremetal' -VNIC_TYPES = [VNIC_NORMAL, VNIC_DIRECT, VNIC_MACVTAP, VNIC_BAREMETAL] +VNIC_DIRECT_PHYSICAL = 'direct-physical' +VNIC_TYPES = [VNIC_NORMAL, VNIC_DIRECT, VNIC_MACVTAP, VNIC_BAREMETAL, + VNIC_DIRECT_PHYSICAL] EXTENDED_ATTRIBUTES_2_0 = { 'ports': { diff --git a/neutron/plugins/ml2/drivers/mech_sriov/agent/sriov_nic_agent.py b/neutron/plugins/ml2/drivers/mech_sriov/agent/sriov_nic_agent.py index 6268009b844..8dfbd34e28d 100644 --- a/neutron/plugins/ml2/drivers/mech_sriov/agent/sriov_nic_agent.py +++ b/neutron/plugins/ml2/drivers/mech_sriov/agent/sriov_nic_agent.py @@ -35,6 +35,7 @@ from neutron.common import constants as n_constants from neutron.common import topics from neutron.common import utils as n_utils from neutron import context +from neutron.extensions import portbindings from neutron.plugins.ml2.drivers.mech_sriov.agent.common import config from neutron.plugins.ml2.drivers.mech_sriov.agent.common \ import exceptions as exc @@ -60,6 +61,13 @@ class SriovNicSwitchRpcCallbacks(sg_rpc.SecurityGroupAgentRpcCallbackMixin): def port_update(self, context, **kwargs): LOG.debug("port_update received") port = kwargs.get('port') + + vnic_type = port.get(portbindings.VNIC_TYPE) + if vnic_type and vnic_type == portbindings.VNIC_DIRECT_PHYSICAL: + LOG.debug("The SR-IOV agent doesn't handle %s ports.", + portbindings.VNIC_DIRECT_PHYSICAL) + return + # Put the port mac address in the updated_devices set. # Do not store port details, as if they're used for processing # notifications there is no guarantee the notifications are diff --git a/neutron/plugins/ml2/drivers/mech_sriov/mech_driver/mech_driver.py b/neutron/plugins/ml2/drivers/mech_sriov/mech_driver/mech_driver.py index b1a63dc4491..9204cc99501 100644 --- a/neutron/plugins/ml2/drivers/mech_sriov/mech_driver/mech_driver.py +++ b/neutron/plugins/ml2/drivers/mech_sriov/mech_driver/mech_driver.py @@ -63,7 +63,8 @@ class SriovNicSwitchMechanismDriver(api.MechanismDriver): vif_type=VIF_TYPE_HW_VEB, vif_details={portbindings.CAP_PORT_FILTER: False}, supported_vnic_types=[portbindings.VNIC_DIRECT, - portbindings.VNIC_MACVTAP], + portbindings.VNIC_MACVTAP, + portbindings.VNIC_DIRECT_PHYSICAL], supported_pci_vendor_info=None): """Initialize base class for SriovNicSwitch L2 agent type. @@ -103,6 +104,17 @@ class SriovNicSwitchMechanismDriver(api.MechanismDriver): LOG.debug("Refusing to bind due to unsupported pci_vendor device") return + if vnic_type == portbindings.VNIC_DIRECT_PHYSICAL: + # Physical functions don't support things like QoS properties, + # spoof checking, etc. so we might as well side-step the agent + # for now. The agent also doesn't currently recognize non-VF + # PCI devices so we won't get port status change updates + # either. This should be changed in the future so physical + # functions can use device mapping checks and the plugin can + # get port status updates. + self.try_to_bind(context, None) + return + for agent in context.host_agents(self.agent_type): LOG.debug("Checking agent: %s", agent) if agent['alive']: @@ -115,10 +127,12 @@ class SriovNicSwitchMechanismDriver(api.MechanismDriver): def try_to_bind(self, context, agent): for segment in context.segments_to_bind: if self.check_segment(segment, agent): + port_status = (constants.PORT_STATUS_ACTIVE if agent is None + else constants.PORT_STATUS_DOWN) context.set_binding(segment[api.ID], self.vif_type, self._get_vif_details(segment), - constants.PORT_STATUS_DOWN) + port_status) LOG.debug("Bound using segment: %s", segment) return True return False diff --git a/neutron/tests/unit/plugins/ml2/drivers/mech_sriov/agent/test_sriov_nic_agent.py b/neutron/tests/unit/plugins/ml2/drivers/mech_sriov/agent/test_sriov_nic_agent.py index 6ece01e644b..ab31dee21df 100644 --- a/neutron/tests/unit/plugins/ml2/drivers/mech_sriov/agent/test_sriov_nic_agent.py +++ b/neutron/tests/unit/plugins/ml2/drivers/mech_sriov/agent/test_sriov_nic_agent.py @@ -18,6 +18,7 @@ import mock from oslo_config import cfg from oslo_utils import uuidutils +from neutron.extensions import portbindings from neutron.plugins.ml2.drivers.mech_sriov.agent.common import config # noqa from neutron.plugins.ml2.drivers.mech_sriov.agent.common import exceptions from neutron.plugins.ml2.drivers.mech_sriov.agent import sriov_nic_agent @@ -293,6 +294,13 @@ class TestSriovNicSwitchRpcCallbacks(base.BaseTestCase): self.assertEqual(set([(DEVICE_MAC, PCI_SLOT)]), self.agent.updated_devices) + def test_port_update_with_vnic_physical_direct(self): + port = self._create_fake_port() + port[portbindings.VNIC_TYPE] = portbindings.VNIC_DIRECT_PHYSICAL + kwargs = {'context': self.context, 'port': port} + self.sriov_rpc_callback.port_update(**kwargs) + self.assertEqual(set(), self.agent.updated_devices) + def test_port_update_without_pci_slot(self): port = self._create_fake_port() port['binding:profile'] = None diff --git a/neutron/tests/unit/plugins/ml2/drivers/mech_sriov/mech_driver/test_mech_sriov_nic_switch.py b/neutron/tests/unit/plugins/ml2/drivers/mech_sriov/mech_driver/test_mech_sriov_nic_switch.py index 4f5b7d9e036..df42a57acd2 100644 --- a/neutron/tests/unit/plugins/ml2/drivers/mech_sriov/mech_driver/test_mech_sriov_nic_switch.py +++ b/neutron/tests/unit/plugins/ml2/drivers/mech_sriov/mech_driver/test_mech_sriov_nic_switch.py @@ -148,6 +148,10 @@ class SriovSwitchMechVnicTypeTestCase(SriovNicSwitchMechanismBaseTestCase): self._check_vif_type_for_vnic_type(portbindings.VNIC_MACVTAP, mech_driver.VIF_TYPE_HW_VEB) + def test_vnic_type_direct_physical(self): + self._check_vif_type_for_vnic_type(portbindings.VNIC_DIRECT_PHYSICAL, + mech_driver.VIF_TYPE_HW_VEB) + class SriovSwitchMechProfileTestCase(SriovNicSwitchMechanismBaseTestCase): def _check_vif_for_pci_info(self, pci_vendor_info, expected_vif_type): @@ -233,6 +237,15 @@ class SriovSwitchMechVifDetailsTestCase(SriovNicSwitchMechanismBaseTestCase): self.driver.bind_port(context) self.assertEqual(constants.PORT_STATUS_DOWN, context._bound_state) + def test_get_vif_details_with_agent_direct_physical(self): + context = TestFakePortContext(self.AGENT_TYPE, + self.AGENTS, + self.VLAN_SEGMENTS, + portbindings.VNIC_DIRECT_PHYSICAL) + + self.driver.bind_port(context) + self.assertEqual(constants.PORT_STATUS_ACTIVE, context._bound_state) + class SriovSwitchMechConfigTestCase(SriovNicSwitchMechanismBaseTestCase): def _set_config(self, pci_devs=['aa:bb']): diff --git a/releasenotes/notes/direct-physical-vnic-878d15bdb758b70e.yaml b/releasenotes/notes/direct-physical-vnic-878d15bdb758b70e.yaml new file mode 100644 index 00000000000..4a826fa97a5 --- /dev/null +++ b/releasenotes/notes/direct-physical-vnic-878d15bdb758b70e.yaml @@ -0,0 +1,6 @@ +--- +prelude: > + Add new VNIC type for SR-IOV physical functions. +features: + - Neutron now supports creation of ports for exposing physical functions + as network devices to guests.