]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Adding a VNIC type for physical functions
authorBrent Eagles <beagles@redhat.com>
Mon, 9 Nov 2015 12:56:53 +0000 (09:26 -0330)
committerBrent Eagles <beagles@redhat.com>
Mon, 14 Dec 2015 13:32:40 +0000 (10:02 -0330)
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
neutron/plugins/ml2/drivers/mech_sriov/agent/sriov_nic_agent.py
neutron/plugins/ml2/drivers/mech_sriov/mech_driver/mech_driver.py
neutron/tests/unit/plugins/ml2/drivers/mech_sriov/agent/test_sriov_nic_agent.py
neutron/tests/unit/plugins/ml2/drivers/mech_sriov/mech_driver/test_mech_sriov_nic_switch.py
releasenotes/notes/direct-physical-vnic-878d15bdb758b70e.yaml [new file with mode: 0644]

index 67338c37409a36060799861b587fdf97437f75cf..e9dc8b8261cbc8640104033cd82279422a347f79 100644 (file)
@@ -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': {
index 6268009b8442672894d39c3bf9037bfba208450c..8dfbd34e28d9f0d1c869da4c6b7cd76578a0e3ed 100644 (file)
@@ -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
index b1a63dc44911c88609b28ef9564aca7e368dc08a..9204cc99501e726b8bb24f0d9fe46ea8bfff434b 100644 (file)
@@ -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
index 6ece01e644b6837bd5ad11b909cc7868605a6892..ab31dee21dfe366701a6b0a302ec41e532938b14 100644 (file)
@@ -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
index 4f5b7d9e03613a6d8f2e00b0e59066f4deadf326..df42a57acd2bfd4f94940f8cbed049a135abcd62 100644 (file)
@@ -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 (file)
index 0000000..4a826fa
--- /dev/null
@@ -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.