]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Not assign dynamic IPv6 address on dhcp interface
authorXu Han Peng <xuhanp@cn.ibm.com>
Fri, 23 Jan 2015 05:29:47 +0000 (13:29 +0800)
committerXu Han Peng <xuhanp@cn.ibm.com>
Thu, 29 Jan 2015 17:07:35 +0000 (01:07 +0800)
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

neutron/agent/linux/dhcp.py
neutron/tests/unit/test_dhcp_agent.py

index ec10ba64460c5bf0b13b2debaaa4a5d809b5543e..472d7fd3383a80d1663799476201217ed6b3be7f 100644 (file)
@@ -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):
index 415e9cbb678d6e5b1146cc7bd4fcaf4b630aa21c..71849132e01b8cd76e11284a01ce74896ba4c96f 100644 (file)
@@ -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)