From a0a022373b90835059b8949a57b097030bcbc37e Mon Sep 17 00:00:00 2001 From: John Davidge Date: Tue, 7 Jul 2015 17:00:01 +0100 Subject: [PATCH] Fix issues with allocation pool generation for ::/64 cidr Passing a ::/64 cidr to certain netaddr functions without specifying the ip_version causes errors. Fix this by specifying ip_version. Change-Id: I31aaf9f5dabe4dd0845507f245387cd4186c410c Closes-Bug: 1472304 --- neutron/ipam/utils.py | 13 ++++++++----- neutron/tests/unit/ipam/test_utils.py | 7 +++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/neutron/ipam/utils.py b/neutron/ipam/utils.py index 1cb894fc808..6a4d96e8715 100644 --- a/neutron/ipam/utils.py +++ b/neutron/ipam/utils.py @@ -43,16 +43,19 @@ def generate_pools(cidr, gateway_ip): """ # Auto allocate the pool around gateway_ip net = netaddr.IPNetwork(cidr) - if net.first == net.last: + ip_version = net.version + first = netaddr.IPAddress(net.first, ip_version) + last = netaddr.IPAddress(net.last, ip_version) + if first == last: # handle single address subnet case - return [netaddr.IPRange(net.first, net.last)] - first_ip = net.first + 1 + return [netaddr.IPRange(first, last)] + first_ip = first + 1 # last address is broadcast in v4 - last_ip = net.last - (net.version == 4) + last_ip = last - (ip_version == 4) if first_ip >= last_ip: # /31 lands here return [] ipset = netaddr.IPSet(netaddr.IPRange(first_ip, last_ip)) if gateway_ip: - ipset.remove(netaddr.IPAddress(gateway_ip)) + ipset.remove(netaddr.IPAddress(gateway_ip, ip_version)) return list(ipset.iter_ipranges()) diff --git a/neutron/tests/unit/ipam/test_utils.py b/neutron/tests/unit/ipam/test_utils.py index 6cfb50fe8a3..db2ee9c5135 100644 --- a/neutron/tests/unit/ipam/test_utils.py +++ b/neutron/tests/unit/ipam/test_utils.py @@ -80,3 +80,10 @@ class TestIpamUtils(base.BaseTestCase): cidr = 'F111::0/64' expected = [netaddr.IPRange('F111::1', 'F111::FFFF:FFFF:FFFF:FFFF')] self.assertEqual(expected, utils.generate_pools(cidr, None)) + + def test_generate_pools_v6_empty(self): + # We want to be sure the range will begin and end with an IPv6 + # address, even if an ambiguous ::/64 cidr is given. + cidr = '::/64' + expected = [netaddr.IPRange('::1', '::FFFF:FFFF:FFFF:FFFF')] + self.assertEqual(expected, utils.generate_pools(cidr, None))