From 629d86d480c06569ba6bd5d9cd55a543dbf6221b Mon Sep 17 00:00:00 2001 From: Wenxin Wang Date: Sat, 2 Jan 2016 18:29:21 +0800 Subject: [PATCH] radvd prefix configuration for DHCPV6_Stateful RA When an IPv6 subnet's ipv6_ra_mode is set to DHCPV6_STATEFUL, the hosts on that subnet rely on router advertisement for the prefix length. This is important for subnets where the lengths of the prefixes are not 64. Closes-Bug: #1531093 Change-Id: Ied8d390a05ee1a2e544e39e887abf11c8a56abc3 --- neutron/agent/linux/ra.py | 15 +++++++++++-- neutron/tests/unit/agent/l3/test_agent.py | 26 +++++++++++++++++------ 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/neutron/agent/linux/ra.py b/neutron/agent/linux/ra.py index 8896e8d26c4..433cd0bfdd9 100644 --- a/neutron/agent/linux/ra.py +++ b/neutron/agent/linux/ra.py @@ -60,13 +60,21 @@ CONFIG_TEMPLATE = jinja2.Template("""interface {{ interface_name }} RDNSS {% for dns in dns_servers %} {{ dns }} {% endfor %} {}; {% endif %} - {% for prefix in prefixes %} + {% for prefix in auto_config_prefixes %} prefix {{ prefix }} { AdvOnLink on; AdvAutonomous on; }; {% endfor %} + + {% for prefix in stateful_config_prefixes %} + prefix {{ prefix }} + { + AdvOnLink on; + AdvAutonomous off; + }; + {% endfor %} }; """) @@ -96,6 +104,8 @@ class DaemonMonitor(object): auto_config_prefixes = [subnet['cidr'] for subnet in v6_subnets if subnet['ipv6_ra_mode'] == constants.IPV6_SLAAC or subnet['ipv6_ra_mode'] == constants.DHCPV6_STATELESS] + stateful_config_prefixes = [subnet['cidr'] for subnet in v6_subnets + if subnet['ipv6_ra_mode'] == constants.DHCPV6_STATEFUL] interface_name = self._dev_name_helper(p['id']) slaac_subnets = [subnet for subnet in v6_subnets if subnet['ipv6_ra_mode'] == constants.IPV6_SLAAC] @@ -104,7 +114,8 @@ class DaemonMonitor(object): buf.write('%s' % CONFIG_TEMPLATE.render( ra_modes=list(ra_modes), interface_name=interface_name, - prefixes=auto_config_prefixes, + auto_config_prefixes=auto_config_prefixes, + stateful_config_prefixes=stateful_config_prefixes, dns_servers=dns_servers[0:MAX_RDNSS_ENTRIES], constants=constants)) diff --git a/neutron/tests/unit/agent/l3/test_agent.py b/neutron/tests/unit/agent/l3/test_agent.py index 23d93c4f24c..1fe1c2418ce 100644 --- a/neutron/tests/unit/agent/l3/test_agent.py +++ b/neutron/tests/unit/agent/l3/test_agent.py @@ -1238,8 +1238,7 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework): ri = self._process_router_ipv6_interface_added(router) self._assert_ri_process_enabled(ri) # Expect radvd configured without prefix - self.assertNotIn('prefix', - self.utils_replace_file.call_args[0][1].split()) + self.assertNotIn('prefix', self.utils_replace_file.call_args[0][1]) def test_process_router_ipv6_slaac_interface_added(self): router = l3_test_common.prepare_router_data() @@ -1247,8 +1246,19 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework): router, ra_mode=l3_constants.IPV6_SLAAC) self._assert_ri_process_enabled(ri) # Expect radvd configured with prefix - self.assertIn('prefix', - self.utils_replace_file.call_args[0][1].split()) + radvd_config_str = self.utils_replace_file.call_args[0][1] + self.assertIn('prefix', radvd_config_str) + self.assertIn('AdvAutonomous on', radvd_config_str) + + def test_process_router_ipv6_dhcpv6_stateful_interface_added(self): + router = l3_test_common.prepare_router_data() + ri = self._process_router_ipv6_interface_added( + router, ra_mode=l3_constants.DHCPV6_STATEFUL) + self._assert_ri_process_enabled(ri) + # Expect radvd configured with prefix + radvd_config_str = self.utils_replace_file.call_args[0][1] + self.assertIn('prefix', radvd_config_str) + self.assertIn('AdvAutonomous off', radvd_config_str) def test_process_router_ipv6_subnets_added(self): router = l3_test_common.prepare_router_data() @@ -1260,11 +1270,13 @@ class TestBasicRouterOperations(BasicRouterOperationsFramework): {'ra_mode': l3_constants.DHCPV6_STATEFUL, 'address_mode': l3_constants.DHCPV6_STATEFUL}]) self._assert_ri_process_enabled(ri) - radvd_config = self.utils_replace_file.call_args[0][1].split() + radvd_config_str = self.utils_replace_file.call_args[0][1] # Assert we have a prefix from IPV6_SLAAC and a prefix from # DHCPV6_STATELESS on one interface - self.assertEqual(2, radvd_config.count("prefix")) - self.assertEqual(1, radvd_config.count("interface")) + self.assertEqual(3, radvd_config_str.count("prefix")) + self.assertEqual(1, radvd_config_str.count("interface")) + self.assertEqual(2, radvd_config_str.count("AdvAutonomous on")) + self.assertEqual(1, radvd_config_str.count("AdvAutonomous off")) def test_process_router_ipv6_subnets_added_to_existing_port(self): agent = l3_agent.L3NATAgent(HOSTNAME, self.conf)