diff --git a/neutron/agent/linux/interface.py b/neutron/agent/linux/interface.py index c763b03a30..24d7c2c448 100644 --- a/neutron/agent/linux/interface.py +++ b/neutron/agent/linux/interface.py @@ -90,6 +90,10 @@ class LinuxInterfaceDriver(object): for ip_cidr in ip_cidrs: net = netaddr.IPNetwork(ip_cidr) + # Convert to compact IPv6 address because the return values of + # "ip addr list" are compact. + if net.version == 6: + ip_cidr = str(net) if ip_cidr in previous: del previous[ip_cidr] continue diff --git a/neutron/tests/unit/test_linux_interface.py b/neutron/tests/unit/test_linux_interface.py index 43ebd093a3..0ea878a94f 100644 --- a/neutron/tests/unit/test_linux_interface.py +++ b/neutron/tests/unit/test_linux_interface.py @@ -109,6 +109,46 @@ class TestABCDriver(TestBase): mock.call().addr.add(4, '192.168.1.2/24', '192.168.1.255')]) self.assertFalse(self.ip_dev().addr.delete.called) + def test_l3_init_with_ipv6(self): + addresses = [dict(ip_version=6, + scope='global', + dynamic=False, + cidr='2001:db8:a::123/64')] + self.ip_dev().addr.list = mock.Mock(return_value=addresses) + bc = BaseChild(self.conf) + ns = '12345678-1234-5678-90ab-ba0987654321' + bc.init_l3('tap0', ['2001:db8:a::124/64'], namespace=ns) + self.ip_dev.assert_has_calls( + [mock.call('tap0', 'sudo', namespace=ns), + mock.call().addr.list(scope='global', filters=['permanent']), + mock.call().addr.add(6, '2001:db8:a::124/64', + '2001:db8:a:0:ffff:ffff:ffff:ffff'), + mock.call().addr.delete(6, '2001:db8:a::123/64')]) + + def test_l3_init_with_duplicated_ipv6(self): + addresses = [dict(ip_version=6, + scope='global', + dynamic=False, + cidr='2001:db8:a::123/64')] + self.ip_dev().addr.list = mock.Mock(return_value=addresses) + bc = BaseChild(self.conf) + ns = '12345678-1234-5678-90ab-ba0987654321' + bc.init_l3('tap0', ['2001:db8:a::123/64'], namespace=ns) + self.assertFalse(self.ip_dev().addr.add.called) + + def test_l3_init_with_duplicated_ipv6_uncompact(self): + addresses = [dict(ip_version=6, + scope='global', + dynamic=False, + cidr='2001:db8:a::123/64')] + self.ip_dev().addr.list = mock.Mock(return_value=addresses) + bc = BaseChild(self.conf) + ns = '12345678-1234-5678-90ab-ba0987654321' + bc.init_l3('tap0', + ['2001:db8:a:0000:0000:0000:0000:0123/64'], + namespace=ns) + self.assertFalse(self.ip_dev().addr.add.called) + class TestOVSInterfaceDriver(TestBase):