Exclude fallback tunnel devices from netns cleanup

When a namespace gets created, if the fb_tunnels_only_for_init_net
sysctl configuration is set to 0, the fallback tunnels will be
automatically created if the corresponding tunnel is present
in the initial network namespace. Source [0].

This is being observed in some systems where namespaces are not
getting cleaned up due to the presence of such devices as
ip_lib.namespace_is_empty() is returning False.

This patch is adding such devices as per the kernel documentation
to the list of excluded devices by default.

[0] https://www.kernel.org/doc/Documentation/sysctl/net.txt

Closes-Bug: #1797084
Change-Id: I94415a0da5367e2d98d792a5eb4ba3919b838326
Signed-off-by: Daniel Alvarez <dalvarez@redhat.com>
(cherry picked from commit 8e60531d11)
This commit is contained in:
Daniel Alvarez 2018-10-10 10:25:17 +02:00 committed by Slawek Kaplonski
parent d6bfd8385b
commit 2cf477df17
2 changed files with 6 additions and 5 deletions

View File

@ -41,7 +41,8 @@ LOG = logging.getLogger(__name__)
IP_NONLOCAL_BIND = 'net.ipv4.ip_nonlocal_bind' IP_NONLOCAL_BIND = 'net.ipv4.ip_nonlocal_bind'
LOOPBACK_DEVNAME = 'lo' LOOPBACK_DEVNAME = 'lo'
GRE_TUNNEL_DEVICE_NAMES = ['gre0', 'gretap0'] FB_TUNNEL_DEVICE_NAMES = ['gre0', 'gretap0', 'tunl0', 'erspan0', 'sit0',
'ip6tnl0', 'ip6gre0']
SYS_NET_PATH = '/sys/class/net' SYS_NET_PATH = '/sys/class/net'
DEFAULT_GW_PATTERN = re.compile(r"via (\S+)") DEFAULT_GW_PATTERN = re.compile(r"via (\S+)")
@ -116,7 +117,7 @@ class IPWrapper(SubProcessBase):
def device(self, name): def device(self, name):
return IPDevice(name, namespace=self.namespace) return IPDevice(name, namespace=self.namespace)
def get_devices(self, exclude_loopback=True, exclude_gre_devices=True): def get_devices(self, exclude_loopback=True, exclude_fb_tun_devices=True):
retval = [] retval = []
if self.namespace: if self.namespace:
# we call out manually because in order to avoid screen scraping # we call out manually because in order to avoid screen scraping
@ -145,7 +146,7 @@ class IPWrapper(SubProcessBase):
for name in output: for name in output:
if (exclude_loopback and name == LOOPBACK_DEVNAME or if (exclude_loopback and name == LOOPBACK_DEVNAME or
exclude_gre_devices and name in GRE_TUNNEL_DEVICE_NAMES): exclude_fb_tun_devices and name in FB_TUNNEL_DEVICE_NAMES):
continue continue
retval.append(IPDevice(name, namespace=self.namespace)) retval.append(IPDevice(name, namespace=self.namespace))

View File

@ -308,9 +308,9 @@ class TestIpWrapper(base.BaseTestCase):
@mock.patch('neutron.agent.common.utils.execute') @mock.patch('neutron.agent.common.utils.execute')
def test_get_devices_exclude_loopback_and_gre(self, mocked_execute): def test_get_devices_exclude_loopback_and_gre(self, mocked_execute):
device_name = 'somedevice' device_name = 'somedevice'
mocked_execute.return_value = 'lo gre0 gretap0 ' + device_name mocked_execute.return_value = 'lo gre0 sit0 ip6gre0 ' + device_name
devices = ip_lib.IPWrapper(namespace='foo').get_devices( devices = ip_lib.IPWrapper(namespace='foo').get_devices(
exclude_loopback=True, exclude_gre_devices=True) exclude_loopback=True, exclude_fb_tun_devices=True)
somedevice = devices.pop() somedevice = devices.pop()
self.assertEqual(device_name, somedevice.name) self.assertEqual(device_name, somedevice.name)
self.assertFalse(devices) self.assertFalse(devices)