summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2017-06-15 07:04:12 +0000
committerGerrit Code Review <review@openstack.org>2017-06-15 07:04:12 +0000
commit18d241db6db0f947bcf5a4790c10ec754a275964 (patch)
tree00bab6a18738740b0460e4f1a886ba6bda8fb32f
parentaad90b005c270adfe83d81973d42e30498711db6 (diff)
parent16942945aeb3f341ae7df1a574a32b4c3ee6c055 (diff)
Merge "Disable 'accept_ra' in DHCP agent namespace" into stable/newton
-rw-r--r--neutron/agent/l3/router_info.py3
-rw-r--r--neutron/agent/linux/dhcp.py17
-rw-r--r--neutron/agent/linux/interface.py11
-rw-r--r--neutron/common/constants.py12
-rw-r--r--neutron/tests/functional/agent/test_dhcp_agent.py6
-rw-r--r--neutron/tests/unit/agent/dhcp/test_agent.py6
6 files changed, 44 insertions, 11 deletions
diff --git a/neutron/agent/l3/router_info.py b/neutron/agent/l3/router_info.py
index d671d3f..09a41f5 100644
--- a/neutron/agent/l3/router_info.py
+++ b/neutron/agent/l3/router_info.py
@@ -646,7 +646,8 @@ class RouterInfo(object):
646 return 646 return
647 647
648 # There is no IPv6 gw_ip, use RouterAdvt for default route. 648 # There is no IPv6 gw_ip, use RouterAdvt for default route.
649 self.driver.configure_ipv6_ra(ns_name, interface_name) 649 self.driver.configure_ipv6_ra(ns_name, interface_name,
650 n_const.ACCEPT_RA_WITH_FORWARDING)
650 651
651 def _external_gateway_added(self, ex_gw_port, interface_name, 652 def _external_gateway_added(self, ex_gw_port, interface_name,
652 ns_name, preserve_ips): 653 ns_name, preserve_ips):
diff --git a/neutron/agent/linux/dhcp.py b/neutron/agent/linux/dhcp.py
index 0fef935..44f123e 100644
--- a/neutron/agent/linux/dhcp.py
+++ b/neutron/agent/linux/dhcp.py
@@ -38,7 +38,6 @@ from neutron.agent.linux import iptables_manager
38from neutron.cmd.sanity import checks 38from neutron.cmd.sanity import checks
39from neutron.common import constants as n_const 39from neutron.common import constants as n_const
40from neutron.common import exceptions as n_exc 40from neutron.common import exceptions as n_exc
41from neutron.common import ipv6_utils
42from neutron.common import utils as common_utils 41from neutron.common import utils as common_utils
43from neutron.extensions import extra_dhcp_opt as edo_ext 42from neutron.extensions import extra_dhcp_opt as edo_ext
44from neutron.ipam import utils as ipam_utils 43from neutron.ipam import utils as ipam_utils
@@ -1364,6 +1363,15 @@ class DeviceManager(object):
1364 1363
1365 def plug(self, network, port, interface_name): 1364 def plug(self, network, port, interface_name):
1366 """Plug device settings for the network's DHCP on this host.""" 1365 """Plug device settings for the network's DHCP on this host."""
1366 # Disable acceptance of RAs in the namespace so we don't
1367 # auto-configure an IPv6 address since we explicitly configure
1368 # them on the device. This must be done before any interfaces
1369 # are plugged since it could receive an RA by the time
1370 # plug() returns, so we have to create the namespace first.
1371 if network.namespace:
1372 ip_lib.IPWrapper().ensure_namespace(network.namespace)
1373 self.driver.configure_ipv6_ra(network.namespace, 'default',
1374 n_const.ACCEPT_RA_DISABLED)
1367 self.driver.plug(network.id, 1375 self.driver.plug(network.id,
1368 port.id, 1376 port.id,
1369 interface_name, 1377 interface_name,
@@ -1400,10 +1408,9 @@ class DeviceManager(object):
1400 ip_cidrs = [] 1408 ip_cidrs = []
1401 for fixed_ip in port.fixed_ips: 1409 for fixed_ip in port.fixed_ips:
1402 subnet = fixed_ip.subnet 1410 subnet = fixed_ip.subnet
1403 if not ipv6_utils.is_auto_address_subnet(subnet): 1411 net = netaddr.IPNetwork(subnet.cidr)
1404 net = netaddr.IPNetwork(subnet.cidr) 1412 ip_cidr = '%s/%s' % (fixed_ip.ip_address, net.prefixlen)
1405 ip_cidr = '%s/%s' % (fixed_ip.ip_address, net.prefixlen) 1413 ip_cidrs.append(ip_cidr)
1406 ip_cidrs.append(ip_cidr)
1407 1414
1408 if self.driver.use_gateway_ips: 1415 if self.driver.use_gateway_ips:
1409 # For each DHCP-enabled subnet, add that subnet's gateway 1416 # For each DHCP-enabled subnet, add that subnet's gateway
diff --git a/neutron/agent/linux/interface.py b/neutron/agent/linux/interface.py
index 311e043..0ba91f2 100644
--- a/neutron/agent/linux/interface.py
+++ b/neutron/agent/linux/interface.py
@@ -219,11 +219,14 @@ class LinuxInterfaceDriver(object):
219 return (self.DEV_NAME_PREFIX + port.id)[:self.DEV_NAME_LEN] 219 return (self.DEV_NAME_PREFIX + port.id)[:self.DEV_NAME_LEN]
220 220
221 @staticmethod 221 @staticmethod
222 def configure_ipv6_ra(namespace, dev_name): 222 def configure_ipv6_ra(namespace, dev_name, value):
223 """Configure acceptance of IPv6 route advertisements on an intf.""" 223 """Configure handling of IPv6 Router Advertisements on an
224 # Learn the default router's IP address via RAs 224 interface. See common/constants.py for possible values.
225 """
225 ip_lib.IPWrapper(namespace=namespace).netns.execute( 226 ip_lib.IPWrapper(namespace=namespace).netns.execute(
226 ['sysctl', '-w', 'net.ipv6.conf.%s.accept_ra=2' % dev_name]) 227 ['sysctl', '-w', 'net.ipv6.conf.%(dev)s.accept_ra=%(value)s' % {
228 'dev': dev_name,
229 'value': value}])
227 230
228 @abc.abstractmethod 231 @abc.abstractmethod
229 def plug_new(self, network_id, port_id, device_name, mac_address, 232 def plug_new(self, network_id, port_id, device_name, mac_address,
diff --git a/neutron/common/constants.py b/neutron/common/constants.py
index 759950f..11eaccf 100644
--- a/neutron/common/constants.py
+++ b/neutron/common/constants.py
@@ -128,6 +128,18 @@ IP_ALLOWED_VERSIONS = [lib_constants.IP_VERSION_4, lib_constants.IP_VERSION_6]
128PORT_RANGE_MIN = 1 128PORT_RANGE_MIN = 1
129PORT_RANGE_MAX = 65535 129PORT_RANGE_MAX = 65535
130 130
131# Configuration values for accept_ra sysctl, copied from linux kernel
132# networking (netdev) tree, file Documentation/networking/ip-sysctl.txt
133#
134# Possible values are:
135# 0 Do not accept Router Advertisements.
136# 1 Accept Router Advertisements if forwarding is disabled.
137# 2 Overrule forwarding behaviour. Accept Router Advertisements
138# even if forwarding is enabled.
139ACCEPT_RA_DISABLED = 0
140ACCEPT_RA_WITHOUT_FORWARDING = 1
141ACCEPT_RA_WITH_FORWARDING = 2
142
131# Some components communicate using private address ranges, define 143# Some components communicate using private address ranges, define
132# them all here. These address ranges should not cause any issues 144# them all here. These address ranges should not cause any issues
133# even if they overlap since they are used in disjoint namespaces, 145# even if they overlap since they are used in disjoint namespaces,
diff --git a/neutron/tests/functional/agent/test_dhcp_agent.py b/neutron/tests/functional/agent/test_dhcp_agent.py
index 4ad1412..5063be0 100644
--- a/neutron/tests/functional/agent/test_dhcp_agent.py
+++ b/neutron/tests/functional/agent/test_dhcp_agent.py
@@ -166,12 +166,18 @@ class DHCPAgentOVSTestFramework(base.BaseSudoTestCase):
166 iface_name = self.get_interface_name(network, port) 166 iface_name = self.get_interface_name(network, port)
167 self.assertEqual(dhcp_enabled, ovs.port_exists(iface_name)) 167 self.assertEqual(dhcp_enabled, ovs.port_exists(iface_name))
168 self.assert_dhcp_namespace(network.namespace, dhcp_enabled) 168 self.assert_dhcp_namespace(network.namespace, dhcp_enabled)
169 self.assert_accept_ra_disabled(network.namespace)
169 self.assert_dhcp_device(network.namespace, iface_name, dhcp_enabled) 170 self.assert_dhcp_device(network.namespace, iface_name, dhcp_enabled)
170 171
171 def assert_dhcp_namespace(self, namespace, dhcp_enabled): 172 def assert_dhcp_namespace(self, namespace, dhcp_enabled):
172 ip = ip_lib.IPWrapper() 173 ip = ip_lib.IPWrapper()
173 self.assertEqual(dhcp_enabled, ip.netns.exists(namespace)) 174 self.assertEqual(dhcp_enabled, ip.netns.exists(namespace))
174 175
176 def assert_accept_ra_disabled(self, namespace):
177 actual = ip_lib.IPWrapper(namespace=namespace).netns.execute(
178 ['sysctl', '-b', 'net.ipv6.conf.default.accept_ra'])
179 self.assertEqual('0', actual)
180
175 def assert_dhcp_device(self, namespace, dhcp_iface_name, dhcp_enabled): 181 def assert_dhcp_device(self, namespace, dhcp_iface_name, dhcp_enabled):
176 dev = ip_lib.IPDevice(dhcp_iface_name, namespace) 182 dev = ip_lib.IPDevice(dhcp_iface_name, namespace)
177 self.assertEqual(dhcp_enabled, ip_lib.device_exists( 183 self.assertEqual(dhcp_enabled, ip_lib.device_exists(
diff --git a/neutron/tests/unit/agent/dhcp/test_agent.py b/neutron/tests/unit/agent/dhcp/test_agent.py
index accbc14..3596d9a 100644
--- a/neutron/tests/unit/agent/dhcp/test_agent.py
+++ b/neutron/tests/unit/agent/dhcp/test_agent.py
@@ -1500,7 +1500,8 @@ class TestDeviceManager(base.BaseTestCase):
1500 'device_id': mock.ANY}})]) 1500 'device_id': mock.ANY}})])
1501 1501
1502 if port == fake_ipv6_port: 1502 if port == fake_ipv6_port:
1503 expected_ips = ['169.254.169.254/16'] 1503 expected_ips = ['2001:db8::a8bb:ccff:fedd:ee99/64',
1504 '169.254.169.254/16']
1504 else: 1505 else:
1505 expected_ips = ['172.9.9.9/24', '169.254.169.254/16'] 1506 expected_ips = ['172.9.9.9/24', '169.254.169.254/16']
1506 expected = [ 1507 expected = [
@@ -1512,6 +1513,9 @@ class TestDeviceManager(base.BaseTestCase):
1512 1513
1513 if not device_is_ready: 1514 if not device_is_ready:
1514 expected.insert(1, 1515 expected.insert(1,
1516 mock.call.configure_ipv6_ra(net.namespace,
1517 'default', 0))
1518 expected.insert(2,
1515 mock.call.plug(net.id, 1519 mock.call.plug(net.id,
1516 port.id, 1520 port.id,
1517 'tap12345678-12', 1521 'tap12345678-12',