From e0f498aae93a70e93e7ffb0769aed73893ab1d20 Mon Sep 17 00:00:00 2001 From: Rodolfo Alonso Hernandez Date: Wed, 4 Sep 2019 09:00:42 +0000 Subject: [PATCH] Veth pair "IFLA_LINK" populated since kernel 4.15.0-60-generic Since kernel_version=4.15.0-60-generic, "iproute2" provides the veth pair index, even if the pair interface is in other namespace. In previous versions, the parameter 'IFLA_LINK' was not present. We need to handle both cases NOTE: this patch is merged in master combined with another bug resolution [1] due to the existing problems in the CI. However, this patch can be pushed alone in stable releases. Conflicts: neutron/tests/functional/privileged/agent/linux/test_ip_lib.py [1] https://review.opendev.org/#/c/680001/ Change-Id: Id161423737189bf822716be953c0db9c1f09589d Closes-Bug: #1842482 (cherry picked from commit fc2a4becd04cf951c0de2ad66ddaa3bbf73f20e3) --- .../privileged/agent/linux/test_ip_lib.py | 43 +++++++++++-------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/neutron/tests/functional/privileged/agent/linux/test_ip_lib.py b/neutron/tests/functional/privileged/agent/linux/test_ip_lib.py index e0d32e256b2..7acddb17b01 100644 --- a/neutron/tests/functional/privileged/agent/linux/test_ip_lib.py +++ b/neutron/tests/functional/privileged/agent/linux/test_ip_lib.py @@ -12,6 +12,8 @@ # License for the specific language governing permissions and limitations # under the License. +import random + from oslo_utils import uuidutils import testtools @@ -183,42 +185,45 @@ class GetDevicesInfoTestCase(functional_base.BaseSudoTestCase): self.assertEqual(sorted(interfaces_tested), sorted(self.interfaces + vxlan_interfaces)) + def _retrieve_interface(self, interface_name, namespace): + for device in priv_ip_lib.get_link_devices(namespace): + if interface_name == ip_lib.get_attr(device, 'IFLA_IFNAME'): + return device + else: + self.fail('Interface "%s" not found' % interface_name) + def test_get_devices_info_veth_different_namespaces(self): namespace2 = 'ns_test-' + uuidutils.generate_uuid() priv_ip_lib.create_netns(namespace2) self.addCleanup(self._remove_ns, namespace2) + # Create a random number of dummy interfaces in namespace2, in order + # to increase the 'veth1_2' interface index in its namespace. + for idx in range(5, random.randint(15, 20)): + priv_ip_lib.create_interface('int_%s' % idx, namespace2, 'dummy') + ip_wrapper = ip_lib.IPWrapper(self.namespace) ip_wrapper.add_veth('veth1_1', 'veth1_2', namespace2) - devices = priv_ip_lib.get_link_devices(self.namespace) - for device in devices: - name = ip_lib.get_attr(device, 'IFLA_IFNAME') - if name == 'veth1_1': - veth1_1 = device - break - else: - self.fail('Interface "veth1_1" not found') + veth1_1 = self._retrieve_interface('veth1_1', self.namespace) + veth1_2 = self._retrieve_interface('veth1_2', namespace2) ifla_linkinfo = ip_lib.get_attr(veth1_1, 'IFLA_LINKINFO') self.assertEqual(ip_lib.get_attr(ifla_linkinfo, 'IFLA_INFO_KIND'), 'veth') - self.assertIsNone(ip_lib.get_attr(veth1_1, 'IFLA_LINK')) + # NOTE(ralonsoh): since kernel_version=4.15.0-60-generic, iproute2 + # provides the veth pair index, even if the pair interface is in other + # namespace. In previous versions, the parameter 'IFLA_LINK' was not + # present. We need to handle both cases. + self.assertIn(ip_lib.get_attr(veth1_1, 'IFLA_LINK'), + [None, veth1_2['index']]) def test_get_devices_info_veth_same_namespaces(self): ip_wrapper = ip_lib.IPWrapper(self.namespace) ip_wrapper.add_veth('veth1_1', 'veth1_2') - devices = priv_ip_lib.get_link_devices(self.namespace) - veth1_1 = veth1_2 = None - for device in devices: - name = ip_lib.get_attr(device, 'IFLA_IFNAME') - if name == 'veth1_1': - veth1_1 = device - elif name == 'veth1_2': - veth1_2 = device + veth1_1 = self._retrieve_interface('veth1_1', self.namespace) + veth1_2 = self._retrieve_interface('veth1_2', self.namespace) - self.assertIsNotNone(veth1_1) - self.assertIsNotNone(veth1_2) veth1_1_link = ip_lib.get_attr(veth1_1, 'IFLA_LINK') veth1_2_link = ip_lib.get_attr(veth1_2, 'IFLA_LINK') self.assertEqual(veth1_1['index'], veth1_2_link)