From 9417defcdf97d06caece469b636f79a0f5f5a084 Mon Sep 17 00:00:00 2001 From: Rodolfo Alonso Hernandez Date: Fri, 12 Nov 2021 10:32:25 +0000 Subject: [PATCH] Check interface presence in new namespace When an interface is moved to a new namespace, specially with OVS internal ports, the interface first dissapears from any network namespace and then is added again. ovs-vswitchd service detects this interface change as reported in [1]. This delay is the cause of the related bug, where some interfaces are not present when the L3 agent needs to manipulate them. [1]https://bugs.launchpad.net/neutron/+bug/1948832/comments/3 Conflicts: neutron/tests/functional/agent/linux/test_ip_lib.py Closes-Bug: #1948832 Change-Id: I3af4d0afa784899689ccb595ce6ba64495431eb9 (cherry picked from commit ebc4766990c9f7021f60240de00370bd81bfa1e6) (cherry picked from commit 9c41365041c581c6c742f9a33a470c2b6c33090d) --- neutron/agent/linux/ip_lib.py | 2 ++ neutron/tests/functional/agent/linux/test_ip_lib.py | 11 +++++++++++ neutron/tests/unit/agent/linux/test_ip_lib.py | 3 ++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/neutron/agent/linux/ip_lib.py b/neutron/agent/linux/ip_lib.py index 7b73201d4cb..76b7e375e03 100644 --- a/neutron/agent/linux/ip_lib.py +++ b/neutron/agent/linux/ip_lib.py @@ -456,6 +456,8 @@ class IpLinkCommand(IpDeviceCommandBase): privileged.set_link_attribute( self.name, self._parent.namespace, net_ns_fd=namespace) self._parent.namespace = namespace + common_utils.wait_until_true(lambda: self.exists, timeout=5, + sleep=0.5) def set_name(self, name): privileged.set_link_attribute( diff --git a/neutron/tests/functional/agent/linux/test_ip_lib.py b/neutron/tests/functional/agent/linux/test_ip_lib.py index 478a004e4bb..b296cef9b72 100644 --- a/neutron/tests/functional/agent/linux/test_ip_lib.py +++ b/neutron/tests/functional/agent/linux/test_ip_lib.py @@ -1100,3 +1100,14 @@ class GetDevicesWithIpTestCase(functional_base.BaseSudoTestCase): ip_addresses = self._remove_loopback_interface(ip_addresses) ip_addresses = self._remove_ipv6_scope_link(ip_addresses) self.assertEqual(0, len(ip_addresses)) + + +class IpLinkCommandTestCase(IpLibTestFramework): + + def test_set_netns(self): + device_name = ('int_' + uuidutils.generate_uuid())[ + :constants.DEVICE_NAME_MAX_LEN] + device = ip_lib.IPDevice(device_name, kind='dummy') + device.link.create() + namespace = self.useFixture(net_helpers.NamespaceFixture()) + device.link.set_netns(namespace.name) diff --git a/neutron/tests/unit/agent/linux/test_ip_lib.py b/neutron/tests/unit/agent/linux/test_ip_lib.py index 36899f3f389..3a9fbc91a4b 100644 --- a/neutron/tests/unit/agent/linux/test_ip_lib.py +++ b/neutron/tests/unit/agent/linux/test_ip_lib.py @@ -658,8 +658,9 @@ class TestIpLinkCommand(TestIPCmdBase): set_link_attribute.assert_called_once_with( self.parent.name, self.parent.namespace, state='down') + @mock.patch.object(priv_lib, 'interface_exists', return_value=True) @mock.patch.object(priv_lib, 'set_link_attribute') - def test_set_netns(self, set_link_attribute): + def test_set_netns(self, set_link_attribute, *args): original_namespace = self.parent.namespace self.link_cmd.set_netns('foo') set_link_attribute.assert_called_once_with(