Rename ipv6_utils.is_enabled()
IPv6 utils is_enabled() doesn't actually determine if IPv6 is enabled on the host. It checks if /proc/sys/net/ipv6/conf/default/disable_ipv6 is present and is set to 0. This kernel configuration option controls if the kernel will automatically assign IPv6 link-local addresses to newly created network interfaces when their link state changes to up. The existence of this /proc files does indicate that the Linux kernel has the ipv6 module loaded or ipv6 was compiled in. Having this /proc file set to zero does not indicate IPv6 is not available on the system, just that newly created interfaces will inherit this configuration and will not have IPv6 addresses bound to them unless the administrator changes the interfaces specific /proc/sys/net/ipv6/conf/$IFACE/disable_ipv6 configuration. This check was added to Neutron so it could operate with distributions which didn't load the ipv6 kernel module, preventing errors when attempting to make IPv6 specific configurations in the iptables firewall driver and the L3 agent. Removing it would break existing deployments. Renaming this function to provide clarity for complex conditions tested by this function. In fact it is a good security practice to set this default disable_ipv6 option to 1, and explicitly enable IPv6 by setting disable_ipv6=0 on individual interfaces which the administrator intends to bind IPv6 addresses on. This establishes parity with IPv4 behavior where interfaces are not active in an address family until the administrator explicitly configures them to be active in that address family. This practice does not currently work as expected with the Neutron, since setting /proc/sys/net/ipv6/conf/default/disable_ipv6 to 1 unexpectedly disables creating IPv6 security group rules leaving instances completely exposed via IPv6 regardless of security group rules. Change-Id: I844b992240a5db642766ec9c04e3b5fcab8e2e23
This commit is contained in:
parent
571e873427
commit
4f0caa0ece
@ -250,7 +250,7 @@ class L3NATAgent(ha.AgentMixin,
|
||||
super(L3NATAgent, self).__init__(host=self.conf.host)
|
||||
|
||||
self.target_ex_net_id = None
|
||||
self.use_ipv6 = ipv6_utils.is_enabled()
|
||||
self.use_ipv6 = ipv6_utils.is_enabled_and_bind_by_default()
|
||||
|
||||
self.pd = pd.PrefixDelegation(self.context, self.process_monitor,
|
||||
self.driver,
|
||||
|
@ -66,7 +66,7 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
|
||||
|
||||
def __init__(self, namespace=None):
|
||||
self.iptables = iptables_manager.IptablesManager(
|
||||
use_ipv6=ipv6_utils.is_enabled(),
|
||||
use_ipv6=ipv6_utils.is_enabled_and_bind_by_default(),
|
||||
namespace=namespace)
|
||||
# TODO(majopela, shihanzhang): refactor out ipset to a separate
|
||||
# driver composed over this one
|
||||
|
@ -18,6 +18,7 @@ IPv6-related utilities and helper functions.
|
||||
"""
|
||||
import os
|
||||
|
||||
from debtcollector import moves
|
||||
from debtcollector import removals
|
||||
import netaddr
|
||||
from neutron_lib import constants as const
|
||||
@ -53,7 +54,10 @@ def get_ipv6_addr_by_EUI64(prefix, mac):
|
||||
'EUI-64: %s') % prefix)
|
||||
|
||||
|
||||
def is_enabled():
|
||||
def is_enabled_and_bind_by_default():
|
||||
"""Check if host has the IPv6 support and is configured to bind IPv6
|
||||
address to new interfaces by default.
|
||||
"""
|
||||
global _IS_IPV6_ENABLED
|
||||
|
||||
if _IS_IPV6_ENABLED is None:
|
||||
@ -65,10 +69,18 @@ def is_enabled():
|
||||
else:
|
||||
_IS_IPV6_ENABLED = False
|
||||
if not _IS_IPV6_ENABLED:
|
||||
LOG.info(_LI("IPv6 is not enabled on this system."))
|
||||
LOG.info(_LI("IPv6 not present or configured not to bind to new "
|
||||
"interfaces on this system. Please ensure IPv6 is "
|
||||
"enabled and /proc/sys/net/ipv6/conf/default/"
|
||||
"disable_ipv6 is set to 1 to enable IPv6."))
|
||||
return _IS_IPV6_ENABLED
|
||||
|
||||
|
||||
is_enabled = moves.moved_function(is_enabled_and_bind_by_default,
|
||||
'is_enabled', __name__, version='Ocata',
|
||||
removal_version='Pike')
|
||||
|
||||
|
||||
def is_auto_address_subnet(subnet):
|
||||
"""Check if subnet is an auto address subnet."""
|
||||
modes = [const.IPV6_SLAAC, const.DHCPV6_STATELESS]
|
||||
|
@ -74,7 +74,7 @@ class RouterWithMetering(object):
|
||||
namespace=self.ns_name,
|
||||
binary_name=WRAP_NAME,
|
||||
state_less=True,
|
||||
use_ipv6=ipv6_utils.is_enabled())
|
||||
use_ipv6=ipv6_utils.is_enabled_and_bind_by_default())
|
||||
self.metering_labels = {}
|
||||
|
||||
|
||||
|
@ -98,7 +98,8 @@ class L3HATestCase(framework.L3AgentTestFramework):
|
||||
self._router_lifecycle(enable_ha=True, dual_stack=True,
|
||||
v6_ext_gw_with_sub=False)
|
||||
|
||||
@testtools.skipUnless(ipv6_utils.is_enabled(), "IPv6 is not enabled")
|
||||
@testtools.skipUnless(ipv6_utils.is_enabled_and_bind_by_default(),
|
||||
"IPv6 is not enabled")
|
||||
def test_ipv6_router_advts_after_router_state_change(self):
|
||||
# Schedule router to l3 agent, and then add router gateway. Verify
|
||||
# that router gw interface is configured to receive Router Advts.
|
||||
|
@ -55,10 +55,10 @@ class IPv6byEUI64TestCase(base.BaseTestCase):
|
||||
ipv6_utils.get_ipv6_addr_by_EUI64(prefix, mac))
|
||||
|
||||
|
||||
class TestIsEnabled(base.BaseTestCase):
|
||||
class TestIsEnabledAndBindByDefault(base.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestIsEnabled, self).setUp()
|
||||
super(TestIsEnabledAndBindByDefault, self).setUp()
|
||||
|
||||
def reset_detection_flag():
|
||||
ipv6_utils._IS_IPV6_ENABLED = None
|
||||
@ -70,25 +70,25 @@ class TestIsEnabled(base.BaseTestCase):
|
||||
|
||||
def test_enabled(self):
|
||||
self.useFixture(tools.OpenFixture(self.proc_path, '0'))
|
||||
enabled = ipv6_utils.is_enabled()
|
||||
enabled = ipv6_utils.is_enabled_and_bind_by_default()
|
||||
self.assertTrue(enabled)
|
||||
|
||||
def test_disabled(self):
|
||||
self.useFixture(tools.OpenFixture(self.proc_path, '1'))
|
||||
enabled = ipv6_utils.is_enabled()
|
||||
enabled = ipv6_utils.is_enabled_and_bind_by_default()
|
||||
self.assertFalse(enabled)
|
||||
|
||||
def test_disabled_non_exists(self):
|
||||
mo = self.useFixture(tools.OpenFixture(self.proc_path, '1')).mock_open
|
||||
self.mock_exists.return_value = False
|
||||
enabled = ipv6_utils.is_enabled()
|
||||
enabled = ipv6_utils.is_enabled_and_bind_by_default()
|
||||
self.assertFalse(enabled)
|
||||
self.assertFalse(mo.called)
|
||||
|
||||
def test_memoize(self):
|
||||
mo = self.useFixture(tools.OpenFixture(self.proc_path, '0')).mock_open
|
||||
ipv6_utils.is_enabled()
|
||||
enabled = ipv6_utils.is_enabled()
|
||||
ipv6_utils.is_enabled_and_bind_by_default()
|
||||
enabled = ipv6_utils.is_enabled_and_bind_by_default()
|
||||
self.assertTrue(enabled)
|
||||
mo.assert_called_once_with(self.proc_path, 'r')
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user