From: Xu Han Peng Date: Fri, 23 Jan 2015 05:29:47 +0000 (+0800) Subject: Not assign dynamic IPv6 address on dhcp interface X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=5595956b88d9b7bb8f1f293be83c44e766be2917;p=openstack-build%2Fneutron-build.git Not assign dynamic IPv6 address on dhcp interface When SLAAC IPv6 subnet using external router advertisement (ipv6_ra_mode=None, ipv6_address_mode=slaac) is added to a dual-stack network, the device of dnsmasq or router gateway may already be assigned with dynamic SLAAC IPv6 address. Current code only checks for permanent address on a device when initilizing the l3 address of that device. This results assigning duplicated address to dhcp tap device, which leads to dhcp agent failure. This fix changes dhcp code to not init dynamic IPv6 address on dhcp device so dynamic address can be auto-configured by either internal or external RA device. Change-Id: I72b85eb93d1849299d523eedf563ab201b4a0352 Closes-Bug:1409634 --- diff --git a/neutron/agent/linux/dhcp.py b/neutron/agent/linux/dhcp.py index ec10ba644..472d7fd33 100644 --- a/neutron/agent/linux/dhcp.py +++ b/neutron/agent/linux/dhcp.py @@ -30,6 +30,7 @@ from neutron.agent.linux import ip_lib from neutron.agent.linux import utils from neutron.common import constants from neutron.common import exceptions +from neutron.common import ipv6_utils from neutron.common import utils as commonutils from neutron.i18n import _LE from neutron.openstack.common import log as logging @@ -966,9 +967,10 @@ class DeviceManager(object): ip_cidrs = [] for fixed_ip in port.fixed_ips: subnet = fixed_ip.subnet - net = netaddr.IPNetwork(subnet.cidr) - ip_cidr = '%s/%s' % (fixed_ip.ip_address, net.prefixlen) - ip_cidrs.append(ip_cidr) + if not ipv6_utils.is_auto_address_subnet(subnet): + net = netaddr.IPNetwork(subnet.cidr) + ip_cidr = '%s/%s' % (fixed_ip.ip_address, net.prefixlen) + ip_cidrs.append(ip_cidr) if (self.conf.enable_isolated_metadata and self.conf.use_namespaces): diff --git a/neutron/tests/unit/test_dhcp_agent.py b/neutron/tests/unit/test_dhcp_agent.py index 415e9cbb6..71849132e 100644 --- a/neutron/tests/unit/test_dhcp_agent.py +++ b/neutron/tests/unit/test_dhcp_agent.py @@ -53,6 +53,7 @@ fake_subnet1 = dhcp.DictModel(dict(id='bbbbbbbb-bbbb-bbbb-bbbbbbbbbbbb', tenant_id=fake_tenant_id, gateway_ip='172.9.9.1', host_routes=[], dns_nameservers=[], ip_version=4, + ipv6_ra_mode=None, ipv6_address_mode=None, allocation_pools=fake_subnet1_allocation_pools)) fake_subnet2_allocation_pools = dhcp.DictModel(dict(id='', start='172.9.8.2', @@ -70,9 +71,10 @@ fake_subnet3 = dhcp.DictModel(dict(id='bbbbbbbb-1111-2222-bbbbbbbbbbbb', fake_ipv6_subnet = dhcp.DictModel(dict(id='bbbbbbbb-1111-2222-bbbbbbbbbbbb', network_id='12345678-1234-5678-1234567890ab', - cidr='2001:0db8::1:0:0:1/128', enable_dhcp=True, + cidr='2001:0db8::0/64', enable_dhcp=True, tenant_id=fake_tenant_id, - gateway_ip='2001:0db8::1:0:0:1', ip_version=6)) + gateway_ip='2001:0db8::1', ip_version=6, + ipv6_ra_mode='slaac', ipv6_address_mode=None)) fake_meta_subnet = dhcp.DictModel(dict(id='bbbbbbbb-1111-2222-bbbbbbbbbbbb', network_id='12345678-1234-5678-1234567890ab', @@ -84,6 +86,8 @@ fake_fixed_ip1 = dhcp.DictModel(dict(id='', subnet_id=fake_subnet1.id, ip_address='172.9.9.9')) fake_fixed_ip2 = dhcp.DictModel(dict(id='', subnet_id=fake_subnet1.id, ip_address='172.9.9.10')) +fake_fixed_ipv6 = dhcp.DictModel(dict(id='', subnet_id=fake_ipv6_subnet.id, + ip_address='2001:db8::a8bb:ccff:fedd:ee99')) fake_meta_fixed_ip = dhcp.DictModel(dict(id='', subnet=fake_meta_subnet, ip_address='169.254.169.254')) fake_allocation_pool_subnet1 = dhcp.DictModel(dict(id='', start='172.9.9.2', @@ -103,6 +107,12 @@ fake_port2 = dhcp.DictModel(dict(id='12345678-1234-aaaa-123456789000', network_id='12345678-1234-5678-1234567890ab', fixed_ips=[fake_fixed_ip2])) +fake_ipv6_port = dhcp.DictModel(dict(id='12345678-1234-aaaa-123456789000', + device_owner='', + mac_address='aa:bb:cc:dd:ee:99', + network_id='12345678-1234-5678-1234567890ab', + fixed_ips=[fake_fixed_ipv6])) + fake_meta_port = dhcp.DictModel(dict(id='12345678-1234-aaaa-1234567890ab', mac_address='aa:bb:cc:dd:ee:ff', network_id='12345678-1234-5678-1234567890ab', @@ -127,7 +137,8 @@ fake_network_ipv6 = dhcp.NetModel(True, dict( id='12345678-1234-5678-1234567890ab', tenant_id='aaaaaaaa-aaaa-aaaa-aaaaaaaaaaaa', admin_state_up=True, - subnets=[fake_ipv6_subnet])) + subnets=[fake_ipv6_subnet], + ports=[fake_ipv6_port])) fake_network_ipv6_ipv4 = dhcp.NetModel(True, dict( id='12345678-1234-5678-1234567890ab', @@ -1204,10 +1215,13 @@ class TestDeviceManager(base.BaseTestCase): {'port': {'name': '', 'admin_state_up': True, 'network_id': net.id, 'tenant_id': net.tenant_id, 'fixed_ips': - [{'subnet_id': fake_fixed_ip1.subnet_id}], + [{'subnet_id': port.fixed_ips[0].subnet_id}], 'device_id': mock.ANY}})]) - expected_ips = ['172.9.9.9/24', '169.254.169.254/16'] + if port == fake_ipv6_port: + expected_ips = ['169.254.169.254/16'] + else: + expected_ips = ['172.9.9.9/24', '169.254.169.254/16'] expected = [ mock.call.get_device_name(port), mock.call.init_l3( @@ -1232,6 +1246,10 @@ class TestDeviceManager(base.BaseTestCase): cfg.CONF.set_override('enable_metadata_network', True) self._test_setup_helper(False) + def test_setup_ipv6(self): + self._test_setup_helper(True, net=fake_network_ipv6, + port=fake_ipv6_port) + def test_setup_device_is_ready(self): self._test_setup_helper(True)