From: Vladik Romanovsky Date: Tue, 17 Jan 2017 09:56:47 +0000 (-0500) Subject: libvirt: set vlan tag for macvtap on SR-IOV VFs X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=ce513278f15d251bae96b339fca2ffb2a05b28f6;p=osstest%2Fopenstack-nova.git libvirt: set vlan tag for macvtap on SR-IOV VFs 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) --- diff --git a/nova/tests/unit/virt/libvirt/test_vif.py b/nova/tests/unit/virt/libvirt/test_vif.py index 24fe95a98e..8d3f5e9d7d 100644 --- a/nova/tests/unit/virt/libvirt/test_vif.py +++ b/nova/tests/unit/virt/libvirt/test_vif.py @@ -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) diff --git a/nova/virt/libvirt/designer.py b/nova/virt/libvirt/designer.py index 0d4a6efe67..67514c931b 100644 --- a/nova/virt/libvirt/designer.py +++ b/nova/virt/libvirt/designer.py @@ -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 diff --git a/nova/virt/libvirt/vif.py b/nova/virt/libvirt/vif.py index 094a2a1dad..e3952634d8 100644 --- a/nova/virt/libvirt/vif.py +++ b/nova/virt/libvirt/vif.py @@ -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