From 7e8f9d490c1cb7f843497eb13637e3209d2e9fdf Mon Sep 17 00:00:00 2001 From: Jakub Libosvar Date: Thu, 10 Nov 2016 08:37:06 -0500 Subject: [PATCH] sanity check: Check that ip_nonlocal_bind works with namespaces Change-Id: Iddde234b871f1e4cd06a56cb019598e586db6250 --- neutron/cmd/sanity/checks.py | 33 +++++++++++++++++++ neutron/cmd/sanity_check.py | 15 ++++++++- .../tests/functional/sanity/test_sanity.py | 3 ++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/neutron/cmd/sanity/checks.py b/neutron/cmd/sanity/checks.py index da34ce411e2..c4b26880fb8 100644 --- a/neutron/cmd/sanity/checks.py +++ b/neutron/cmd/sanity/checks.py @@ -434,3 +434,36 @@ def dibbler_version_supported(): LOG.debug("Exception while checking minimal dibbler version. " "Exception: %s", e) return False + + +def _fix_ip_nonlocal_bind_root_value(original_value): + current_value = ip_lib.get_ip_nonlocal_bind(namespace=None) + if current_value != original_value: + ip_lib.set_ip_nonlocal_bind(value=original_value, namespace=None) + + +def ip_nonlocal_bind(): + ipw = ip_lib.IPWrapper() + nsname1 = "ipnonlocalbind1-" + uuidutils.generate_uuid() + nsname2 = "ipnonlocalbind2-" + uuidutils.generate_uuid() + + ipw.netns.add(nsname1) + try: + ipw.netns.add(nsname2) + try: + original_value = ip_lib.get_ip_nonlocal_bind(namespace=None) + try: + ip_lib.set_ip_nonlocal_bind(value=0, namespace=nsname1) + ip_lib.set_ip_nonlocal_bind(value=1, namespace=nsname2) + ns1_value = ip_lib.get_ip_nonlocal_bind(namespace=nsname1) + finally: + _fix_ip_nonlocal_bind_root_value(original_value) + except RuntimeError as e: + LOG.debug("Exception while checking ip_nonlocal_bind. " + "Exception: %s", e) + return False + finally: + ipw.netns.delete(nsname2) + finally: + ipw.netns.delete(nsname1) + return ns1_value == 0 diff --git a/neutron/cmd/sanity_check.py b/neutron/cmd/sanity_check.py index 9e56c75f182..ef1e5cfd9b1 100644 --- a/neutron/cmd/sanity_check.py +++ b/neutron/cmd/sanity_check.py @@ -263,6 +263,15 @@ def check_bridge_firewalling_enabled(): return result +def check_ip_nonlocal_bind(): + result = checks.ip_nonlocal_bind() + if not result: + LOG.error(_LE('This kernel does not isolate ip_nonlocal_bind kernel ' + 'option in namespaces. Please update to kernel ' + 'version > 3.19.')) + return result + + # Define CLI opts to test specific features, with a callback for the test OPTS = [ BoolOptCallback('ovs_vxlan', check_ovs_vxlan, default=False, @@ -308,7 +317,10 @@ OPTS = [ BoolOptCallback('bridge_firewalling', check_bridge_firewalling_enabled, help=_('Check bridge firewalling'), default=False), - + BoolOptCallback('ip_nonlocal_bind', check_ip_nonlocal_bind, + help=_('Check ip_nonlocal_bind kernel option works with ' + 'network namespaces.'), + default=False), ] @@ -346,6 +358,7 @@ def enable_tests_from_config(): cfg.CONF.set_default('ovsdb_native', True) if cfg.CONF.l3_ha: cfg.CONF.set_default('keepalived_ipv6_support', True) + cfg.CONF.set_default('ip_nonlocal_bind', True) if cfg.CONF.SECURITYGROUP.enable_ipset: cfg.CONF.set_default('ipset_installed', True) if cfg.CONF.SECURITYGROUP.enable_security_group: diff --git a/neutron/tests/functional/sanity/test_sanity.py b/neutron/tests/functional/sanity/test_sanity.py index 76b31e3f3d7..bb9744ec196 100644 --- a/neutron/tests/functional/sanity/test_sanity.py +++ b/neutron/tests/functional/sanity/test_sanity.py @@ -88,3 +88,6 @@ class SanityTestCaseRoot(functional_base.BaseSudoTestCase): def test_bridge_firewalling_enabled(self): checks.bridge_firewalling_enabled() + + def test_ip_nonlocal_bind(self): + checks.ip_nonlocal_bind()