Add support for vrouter HW datapath offloads

Add plumbing for Contrail/Tungsten Fabric datapath offloads

* This change expands the VNIC type support for the vrouter VIF type by
  adding 'direct' and 'virtio-forwarder' plugging support.

* After this change, the vrouter VIF type will support the following modes:
  * 'normal': the 'classic' tap-style VNIC plugged into the instance,
  * 'direct': a PCI Virtual Function is passed through to the instance,
  * 'virtio-forwarder': a PCI Virtual Function is proxied to the
    instance via a vhost-user virtio forwarder.

* The os-vif conversion function was extended to support the two new
  plugging modes.

* Unit tests were added for the os-vif conversion functions.

* OpenContrail / Tungsten Fabric is planning to consume this
  functionality for the 5.1 release.

* os-vif 1.14.0 is required to pass the metadata

Change-Id: I327894839a892a976cf314d4292b22ce247b0afa
Depends-On: I401ee6370dad68e62bc2d089e786a840d91d0267
Signed-off-by: Jan Gutter <jan.gutter@netronome.com>
blueprint: vrouter-hw-offloads
This commit is contained in:
Jan Gutter 2018-06-04 11:46:21 +02:00 committed by Matt Riedemann
parent 172855f293
commit 4d32b45c15
6 changed files with 183 additions and 2 deletions

View File

@ -70,7 +70,7 @@ os-brick==2.6.1
os-client-config==1.29.0
os-service-types==1.2.0
os-traits==0.4.0
os-vif==1.7.0
os-vif==1.14.0
os-win==3.0.0
os-xenapi==0.3.3
osc-lib==1.10.0

View File

@ -436,6 +436,38 @@ def _nova_to_osvif_vif_vrouter(vif):
plugin="vrouter",
vif_name=_get_vif_name(vif)
)
elif vnic_type == model.VNIC_TYPE_DIRECT:
datapath_offload = objects.vif.DatapathOffloadRepresentor(
representor_name=_get_vif_name(vif),
representor_address=vif["profile"]["pci_slot"]
)
profile = objects.vif.VIFPortProfileBase(
datapath_offload=datapath_offload
)
obj = _get_vif_instance(
vif,
objects.vif.VIFHostDevice,
port_profile=profile,
plugin="vrouter",
dev_address=vif["profile"]["pci_slot"],
dev_type=objects.fields.VIFHostDeviceDevType.ETHERNET
)
elif vnic_type == model.VNIC_TYPE_VIRTIO_FORWARDER:
datapath_offload = objects.vif.DatapathOffloadRepresentor(
representor_name=_get_vif_name(vif),
representor_address=vif["profile"]["pci_slot"]
)
profile = objects.vif.VIFPortProfileBase(
datapath_offload=datapath_offload
)
obj = _get_vif_instance(
vif,
objects.vif.VIFVHostUser,
port_profile=profile,
plugin="vrouter",
vif_name=_get_vif_name(vif)
)
_set_vhostuser_settings(vif, obj)
else:
raise NotImplementedError()
return obj

View File

@ -1128,3 +1128,91 @@ class OSVIFUtilTestCase(test.NoDBTestCase):
objects=[])))
self.assertObjEqual(expect, actual)
def test_nova_to_osvif_vrouter_direct(self):
"""Test for Contrail / Tungsten Fabric direct offloaded datapath."""
vif = model.VIF(
id="dc065497-3c8d-4f44-8fb4-e1d33c16a536",
type=model.VIF_TYPE_VROUTER,
address="22:52:25:62:e2:aa",
profile={
"pci_slot": "0000:08:08.5",
},
network=model.Network(
id="b82c1929-051e-481d-8110-4669916c7915",
label="Demo Net",
subnets=[]),
vnic_type=model.VNIC_TYPE_DIRECT,
)
actual = os_vif_util.nova_to_osvif_vif(vif)
expect = osv_objects.vif.VIFHostDevice(
id="dc065497-3c8d-4f44-8fb4-e1d33c16a536",
active=False,
has_traffic_filtering=False,
address="22:52:25:62:e2:aa",
dev_type=osv_objects.fields.VIFHostDeviceDevType.ETHERNET,
dev_address="0000:08:08.5",
plugin="vrouter",
port_profile=osv_objects.vif.VIFPortProfileBase(
datapath_offload=osv_objects.vif.DatapathOffloadRepresentor(
representor_name="nicdc065497-3c",
representor_address="0000:08:08.5")
),
preserve_on_delete=False,
vif_name="nicdc065497-3c",
network=osv_objects.network.Network(
id="b82c1929-051e-481d-8110-4669916c7915",
bridge_interface=None,
label="Demo Net",
subnets=osv_objects.subnet.SubnetList(
objects=[])))
self.assertObjEqual(expect, actual)
def test_nova_to_osvif_vrouter_forwarder(self):
"""Test for Contrail / Tungsten Fabric indirect offloaded datapath."""
vif = model.VIF(
id="dc065497-3c8d-4f44-8fb4-e1d33c16a536",
type=model.VIF_TYPE_VROUTER,
address="22:52:25:62:e2:aa",
profile={
"pci_slot": "0000:08:08.5",
},
network=model.Network(
id="b82c1929-051e-481d-8110-4669916c7915",
label="Demo Net",
subnets=[]),
details={
model.VIF_DETAILS_VHOSTUSER_MODE: 'client',
model.VIF_DETAILS_VHOSTUSER_SOCKET: '/fake/socket',
},
vnic_type=model.VNIC_TYPE_VIRTIO_FORWARDER,
)
actual = os_vif_util.nova_to_osvif_vif(vif)
expect = osv_objects.vif.VIFVHostUser(
id="dc065497-3c8d-4f44-8fb4-e1d33c16a536",
active=False,
address="22:52:25:62:e2:aa",
plugin="vrouter",
vif_name="nicdc065497-3c",
path='/fake/socket',
mode='client',
has_traffic_filtering=False,
port_profile=osv_objects.vif.VIFPortProfileBase(
datapath_offload=osv_objects.vif.DatapathOffloadRepresentor(
representor_address="0000:08:08.5",
representor_name="nicdc065497-3c")
),
preserve_on_delete=False,
network=osv_objects.network.Network(
id="b82c1929-051e-481d-8110-4669916c7915",
bridge_interface=None,
label="Demo Net",
subnets=osv_objects.subnet.SubnetList(
objects=[])))
self.assertObjEqual(expect, actual)

View File

@ -273,6 +273,25 @@ class LibvirtVifTestCase(test.NoDBTestCase):
type=network_model.VIF_TYPE_VROUTER,
devname='tap-xxx-yyy-zzz')
vif_vrouter_direct = network_model.VIF(id=uuids.vif,
address='ca:fe:de:ad:be:ef',
network=network_vrouter,
type=network_model.VIF_TYPE_VROUTER,
vnic_type=network_model.VNIC_TYPE_DIRECT,
profile={'pci_slot': '0000:0a:00.1'},
devname='tap-xxx-yyy-zzz')
vif_vrouter_forwarder = network_model.VIF(id=uuids.vif,
address='ca:fe:de:ad:be:ef',
network=network_vrouter,
type=network_model.VIF_TYPE_VROUTER,
vnic_type=network_model.VNIC_TYPE_VIRTIO_FORWARDER,
profile={'pci_slot': '0000:0a:00.1'},
details={
network_model.VIF_DETAILS_VHOSTUSER_MODE: 'server',
network_model.VIF_DETAILS_VHOSTUSER_SOCKET: '/tmp/usv-xxx-yyy-zzz',
network_model.VIF_DETAILS_VHOSTUSER_VROUTER_PLUG: True})
vif_contrail_vrouter = network_model.VIF(id=uuids.vif,
address='ca:fe:de:ad:be:ef',
network=network_vrouter,
@ -1400,6 +1419,34 @@ class LibvirtVifTestCase(test.NoDBTestCase):
self._assertTypeAndMacEquals(node, "ethernet", "target", "dev",
self.vif_vrouter, dev_want)
def test_vrouter_direct(self):
"""Test for Contrail / Tungsten Fabric direct offloaded datapath."""
d = vif.LibvirtGenericVIFDriver()
xml = self._get_instance_xml(d, self.vif_vrouter_direct)
node = self._get_node(xml)
self._assertTypeAndPciEquals(node,
"hostdev",
self.vif_vrouter_direct)
self._assertMacEquals(node, self.vif_vrouter_direct)
def test_vrouter_forwarder(self):
"""Test for Contrail / Tungsten Fabric indirect offloaded datapath."""
d = vif.LibvirtGenericVIFDriver()
xml = self._get_instance_xml(d,
self.vif_vrouter_forwarder)
node = self._get_node(xml)
self.assertEqual(node.get("type"),
network_model.VIF_TYPE_VHOSTUSER)
self._assertTypeEquals(node, network_model.VIF_TYPE_VHOSTUSER,
"source", "mode", "server")
self._assertTypeEquals(node, network_model.VIF_TYPE_VHOSTUSER,
"source", "path", "/tmp/usv-xxx-yyy-zzz")
self._assertTypeEquals(node, network_model.VIF_TYPE_VHOSTUSER,
"source", "type", "unix")
self._assertMacEquals(node, self.vif_vrouter_forwarder)
self._assertModel(xml, network_model.VIF_MODEL_VIRTIO)
def test_contrail_vrouter(self):
"""Test for the Contrail / Tungsten Fabric DPDK datapath."""
d = vif.LibvirtGenericVIFDriver()

View File

@ -0,0 +1,14 @@
---
features:
- |
This release adds support for ``direct`` and ``virtio-forwarder`` VNIC
types to the ``vrouter`` VIF type. In order to use these VNIC types,
support is required from the version of OpenContrail, Contrail or Tungsten
Fabric that is installed, as well the required hardware. At this time, the
reference os-vif plugin is hosted on OpenContrail at
https://github.com/Juniper/contrail-nova-vif-driver but is expected to
transition to Tungsten Fabric in the future. Version 5.1 or later of the
plugin is required to use these new VNIC types. Consult the `Tungsten
Fabric documentation <https://tungstenfabric.github.io/website/>`_ for
release notes, when available, about hardware support. For commercial
support, consult the release notes from a downstream vendor.

View File

@ -57,7 +57,7 @@ psutil>=3.2.2 # BSD
oslo.versionedobjects>=1.33.3 # Apache-2.0
os-brick>=2.6.1 # Apache-2.0
os-traits>=0.4.0 # Apache-2.0
os-vif!=1.8.0,>=1.7.0 # Apache-2.0
os-vif>=1.14.0 # Apache-2.0
os-win>=3.0.0 # Apache-2.0
castellan>=0.16.0 # Apache-2.0
microversion-parse>=0.2.1 # Apache-2.0