]> xenbits.xensource.com Git - osstest/openstack-nova.git/commitdiff
libvirt: set vlan tag for macvtap on SR-IOV VFs
authorVladik Romanovsky <vromanso@redhat.com>
Tue, 17 Jan 2017 09:56:47 +0000 (04:56 -0500)
committerMatt Riedemann <mriedem.os@gmail.com>
Tue, 21 Mar 2017 18:59:09 +0000 (14:59 -0400)
Starting from version 1.3.5, Libvirt allows to set a vlan tag for macvtap
passthrough mode on SR-IOV VFs. Libvirt also removes any vlan tags that
has been set externally, by the ip link command.

In order to support the older libvirt versions, this code will make
the behaviour backward compatible by checking the libvirt version.
This can be completely removed once the minimum libvirt version will increase.

Change-Id: Ia14e78e0eda81b8d29d5aa6e07e68777665d0710
Closes-Bug: #1657035
(cherry picked from commit bf3ba76a91e362c0b3b8094964adc06f6a4ec62e)

nova/tests/unit/virt/libvirt/test_vif.py
nova/virt/libvirt/designer.py
nova/virt/libvirt/vif.py

index 24fe95a98efb962fd3f2aabce7b61b659fe8b9bd..8d3f5e9d7d3b269038642e5f903b0a3240d6067e 100644 (file)
@@ -1206,7 +1206,26 @@ class LibvirtVifTestCase(test.NoDBTestCase):
 
     @mock.patch.object(pci_utils, 'get_ifname_by_pci_address',
                        return_value='eth1')
-    def test_hw_veb_driver_macvtap(self, mock_get_ifname):
+    @mock.patch.object(host.Host, "has_min_version", return_value=True)
+    def test_hw_veb_driver_macvtap(self, ver_mock, mock_get_ifname):
+        d = vif.LibvirtGenericVIFDriver()
+        xml = self._get_instance_xml(d, self.vif_hw_veb_macvtap)
+        node = self._get_node(xml)
+        self.assertEqual(node.get("type"), "direct")
+        self._assertTypeEquals(node, "direct", "source",
+                               "dev", "eth1")
+        self._assertTypeEquals(node, "direct", "source",
+                               "mode", "passthrough")
+        self._assertMacEquals(node, self.vif_hw_veb_macvtap)
+        vlan = node.find("vlan").find("tag").get("id")
+        vlan_want = self.vif_hw_veb["details"]["vlan"]
+        self.assertEqual(int(vlan), vlan_want)
+
+    @mock.patch.object(pci_utils, 'get_ifname_by_pci_address',
+                       return_value='eth1')
+    @mock.patch.object(host.Host, "has_min_version", return_value=False)
+    def test_hw_veb_driver_macvtap_pre_vlan_support(self, ver_mock,
+                                                    mock_get_ifname):
         d = vif.LibvirtGenericVIFDriver()
         xml = self._get_instance_xml(d, self.vif_hw_veb_macvtap)
         node = self._get_node(xml)
index 0d4a6efe67423718f72dc9ae5176d6a20f5464de..67514c931bb6786c5a0bf87b1ab0ebdda5215cd7 100644 (file)
@@ -107,14 +107,14 @@ def set_vif_host_backend_hw_veb(conf, net_type, devname, vlan,
     """
 
     conf.net_type = net_type
+    conf.vlan = vlan
     if net_type == 'direct':
         conf.source_mode = 'passthrough'
         conf.source_dev = pci_utils.get_ifname_by_pci_address(devname)
         conf.driver_name = 'vhost'
-    else:
+    else:  # net_type == network_model.VNIC_TYPE_DIRECT
         conf.source_dev = devname
         conf.model = None
-        conf.vlan = vlan
     if tapname:
         conf.target_dev = tapname
 
index 094a2a1dad2c8d260b70dd1f78cca3437f843522..e3952634d880404a1b0ba29ad45ed8a530da2bdf 100644 (file)
@@ -46,6 +46,8 @@ CONF = nova.conf.CONF
 
 # vhostuser queues support
 MIN_LIBVIRT_VHOSTUSER_MQ = (1, 2, 17)
+#  vlan tag for macvtap passthrough mode on SRIOV VFs
+MIN_LIBVIRT_MACVTAP_PASSTHROUGH_VLAN = (1, 3, 5)
 
 
 def is_vif_model_valid_for_virt(virt_type, vif_model):
@@ -327,6 +329,11 @@ class LibvirtGenericVIFDriver(object):
             conf, net_type, profile['pci_slot'],
             vif_details[network_model.VIF_DETAILS_VLAN])
 
+        # NOTE(vladikr): Not setting vlan tags for macvtap on SR-IOV VFs
+        # as vlan tag is not supported in Libvirt until version 1.3.5
+        if (vif['vnic_type'] == network_model.VNIC_TYPE_MACVTAP and not
+                host.has_min_version(MIN_LIBVIRT_MACVTAP_PASSTHROUGH_VLAN)):
+            conf.vlan = None
         designer.set_vif_bandwidth_config(conf, inst_type)
 
         return conf
@@ -636,6 +643,8 @@ class LibvirtGenericVIFDriver(object):
         pass
 
     def plug_hw_veb(self, instance, vif):
+        # TODO(vladikr): This code can be removed once the minimum version of
+        # Libvirt is incleased above 1.3.5, as vlan will be set by libvirt
         if vif['vnic_type'] == network_model.VNIC_TYPE_MACVTAP:
             linux_net.set_vf_interface_vlan(
                 vif['profile']['pci_slot'],
@@ -859,6 +868,8 @@ class LibvirtGenericVIFDriver(object):
         pass
 
     def unplug_hw_veb(self, instance, vif):
+        # TODO(vladikr): This code can be removed once the minimum version of
+        # Libvirt is incleased above 1.3.5, as vlan will be set by libvirt
         if vif['vnic_type'] == network_model.VNIC_TYPE_MACVTAP:
             # The ip utility doesn't accept the MAC 00:00:00:00:00:00.
             # Therefore, keep the MAC unchanged.  Later operations on