]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Consider all address scopes in init_l3
authorAndrew Boik <dboik@cisco.com>
Fri, 27 Mar 2015 20:21:29 +0000 (16:21 -0400)
committerAndrew Boik <dboik@cisco.com>
Wed, 8 Apr 2015 14:36:34 +0000 (10:36 -0400)
Currently init_l3 retrieves the list of global addresses from the kernel
on a specific device in a network namespace. If any of the addresses are
not in the ip_cidrs argument to init_l3, they will be deleted. The
problem with only listing global addresses is that if a site-local or
link-local address is added during a subnet-create, and the user wishes
to later delete the address, init_l3 will never consider that address
for deletion.

To fix this, init_l3 should not limit its scope when listing addresses
on an interface. It should, however, ignore the default IPv6 link-local
address assigned by the operating system as this address is not known to
Neutron and should not be deleted.

Change-Id: I3d7a3e318e32acae3836c51e4e2e95ae756e645b
Closes-Bug: #1437499

neutron/agent/linux/interface.py
neutron/tests/unit/agent/linux/test_interface.py

index 99654cfc8f47d2b77f112f2268a3db5afbf1fd96..0f5741b97471b519e8bcc1fbbdd5224130ca4dad 100644 (file)
@@ -89,9 +89,12 @@ class LinuxInterfaceDriver(object):
         """
         device = ip_lib.IPDevice(device_name, namespace=namespace)
 
-        previous = set()
-        for address in device.addr.list(scope='global', filters=['permanent']):
-            previous.add(address['cidr'])
+        # The LLA generated by the operating system is not known to
+        # Neutron, so it would be deleted if we added it to the 'previous'
+        # list here
+        default_ipv6_lla = ip_lib.get_ipv6_lladdr(device.link.address)
+        previous = {addr['cidr'] for addr in device.addr.list(
+            filters=['permanent'])} - {default_ipv6_lla}
 
         # add new addresses
         for ip_cidr in ip_cidrs:
index df605eb57cb34e1707310bbdd31ce6c727be2a53..bae30a6a9774a48616a80b6ce4cc2a099397362d 100644 (file)
@@ -70,6 +70,11 @@ class TestBase(base.BaseTestCase):
 
 
 class TestABCDriver(TestBase):
+    def setUp(self):
+        super(TestABCDriver, self).setUp()
+        mock_link_addr = mock.PropertyMock(return_value='aa:bb:cc:dd:ee:ff')
+        type(self.ip_dev().link).address = mock_link_addr
+
     def test_get_device_name(self):
         bc = BaseChild(self.conf)
         device_name = bc.get_device_name(FakePort())
@@ -87,7 +92,7 @@ class TestABCDriver(TestBase):
                    extra_subnets=[{'cidr': '172.20.0.0/24'}])
         self.ip_dev.assert_has_calls(
             [mock.call('tap0', namespace=ns),
-             mock.call().addr.list(scope='global', filters=['permanent']),
+             mock.call().addr.list(filters=['permanent']),
              mock.call().addr.add('192.168.1.2/24'),
              mock.call().addr.delete('172.16.77.240/24'),
              mock.call().route.list_onlink_routes(constants.IP_VERSION_4),
@@ -119,7 +124,7 @@ class TestABCDriver(TestBase):
                    preserve_ips=['192.168.1.3/32'])
         self.ip_dev.assert_has_calls(
             [mock.call('tap0', namespace=ns),
-             mock.call().addr.list(scope='global', filters=['permanent']),
+             mock.call().addr.list(filters=['permanent']),
              mock.call().addr.add('192.168.1.2/24')])
         self.assertFalse(self.ip_dev().addr.delete.called)
 
@@ -140,7 +145,7 @@ class TestABCDriver(TestBase):
         bc.init_l3('tap0', [new_cidr], **kwargs)
         expected_calls = (
             [mock.call('tap0', namespace=ns),
-             mock.call().addr.list(scope='global', filters=['permanent']),
+             mock.call().addr.list(filters=['permanent']),
              mock.call().addr.add('2001:db8:a::124/64'),
              mock.call().addr.delete('2001:db8:a::123/64')])
         if include_gw_ip:
@@ -172,7 +177,7 @@ class TestABCDriver(TestBase):
                    extra_subnets=[{'cidr': '172.20.0.0/24'}])
         self.ip_dev.assert_has_calls(
             [mock.call('tap0', namespace=ns),
-             mock.call().addr.list(scope='global', filters=['permanent']),
+             mock.call().addr.list(filters=['permanent']),
              mock.call().addr.add('192.168.1.2/24'),
              mock.call().addr.add('2001:db8:a::124/64'),
              mock.call().addr.delete('172.16.77.240/24'),