Fix unshortened IPv6 address caused DHCP crash

When unshortened IPv6 address provided to allocation pool, DHCP
agent crashed because OpenStack is trying to add same IPv6 addresses
to dhcp tap device.

The root cause is that current code compares provided unshortened
IPv6 address with the returned result of "ip addr list", which is
shortened. So the same IPv6 address is treated as different ones.

The fix is trying to shorten the provided address before comparison.

Change-Id: If1e183e65c5ab785b73771d9a3d4b525d38284a9
Closes-Bug: 1266780
This commit is contained in:
Xuhan Peng 2014-02-12 03:41:23 -05:00
parent 59bf3d7389
commit 597288b1d1
2 changed files with 44 additions and 0 deletions

View File

@ -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

View File

@ -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):