diff --git a/neutron/agent/linux/interface.py b/neutron/agent/linux/interface.py index 51bb058c4e4..f6dd43f7728 100644 --- a/neutron/agent/linux/interface.py +++ b/neutron/agent/linux/interface.py @@ -106,7 +106,13 @@ class LinuxInterfaceDriver(object): del previous[ip_cidr] continue - device.addr.add(net.version, ip_cidr, str(net.broadcast)) + # Make sure the format of this network, if IPv6, is zero-filled. + # The Linux netaddr library seems to do this by default (bug?), + # and the test verifies it, but we should force it just in case + # the behavior changes. It also makes sure that non-Linux-based + # libraries also work correctly (e.g. OSX). + device.addr.add(net.version, ip_cidr, + str(net.broadcast.format(netaddr.ipv6_full))) # clean up any old addresses for ip_cidr, ip_version in previous.items(): diff --git a/neutron/tests/unit/test_linux_interface.py b/neutron/tests/unit/test_linux_interface.py index e1947a80307..ee6967e0675 100644 --- a/neutron/tests/unit/test_linux_interface.py +++ b/neutron/tests/unit/test_linux_interface.py @@ -127,15 +127,20 @@ class TestABCDriver(TestBase): dynamic=False, cidr='2001:db8:a::123/64')] self.ip_dev().addr.list = mock.Mock(return_value=addresses) + self.ip_dev().route.list_onlink_routes.return_value = [] + bc = BaseChild(self.conf) ns = '12345678-1234-5678-90ab-ba0987654321' - bc.init_l3('tap0', ['2001:db8:a::124/64'], namespace=ns) + bc.init_l3('tap0', ['2001:db8:a::124/64'], namespace=ns, + extra_subnets=[{'cidr': '2001:db8:b::/64'}]) 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')]) + mock.call().addr.delete(6, '2001:db8:a::123/64'), + mock.call().route.list_onlink_routes(), + mock.call().route.add_onlink_route('2001:db8:b::/64')]) def test_l3_init_with_duplicated_ipv6(self): addresses = [dict(ip_version=6,