Fix subnet creation failure on IPv6 valid gateway
Currently a valid IPv6 address gateway of the "*::ffff:ffff:ffff:ffff" pattern is failing due to netaddr.broadcast returning value for both IPv6 and IPv4 addresses. IPv6 has no broadcast address so the fix checks if the gateway is the subnet broadcast address only in the case of IPv4 subnet Change-Id: I849f95b30343d0b1c90cf91203df220bf731d8d5 Closes-Bug: 1466322
This commit is contained in:
parent
acf78cc3c8
commit
ee51ef72d3
@ -126,13 +126,19 @@ class SubnetAllocator(driver.Pool):
|
||||
self._check_subnetpool_tenant_quota(request.tenant_id,
|
||||
request.prefixlen)
|
||||
cidr = request.subnet_cidr
|
||||
gateway = request.gateway_ip
|
||||
if gateway and not ipam_utils.check_subnet_ip(cidr, gateway):
|
||||
msg = _("Cannot allocate requested subnet due to bad gateway "
|
||||
"address")
|
||||
raise n_exc.SubnetAllocationError(reason=msg)
|
||||
|
||||
available = self._get_available_prefix_list()
|
||||
matched = netaddr.all_matching_cidrs(cidr, available)
|
||||
if len(matched) is 1 and matched[0].prefixlen <= cidr.prefixlen:
|
||||
return IpamSubnet(request.tenant_id,
|
||||
request.subnet_id,
|
||||
cidr,
|
||||
gateway_ip=request.gateway_ip,
|
||||
gateway_ip=gateway,
|
||||
allocation_pools=request.allocation_pools)
|
||||
msg = _("Cannot allocate requested subnet from the available "
|
||||
"set of prefixes")
|
||||
|
@ -21,8 +21,9 @@ def check_subnet_ip(cidr, ip_address):
|
||||
ip = netaddr.IPAddress(ip_address)
|
||||
net = netaddr.IPNetwork(cidr)
|
||||
# Check that the IP is valid on subnet. This cannot be the
|
||||
# network or the broadcast address
|
||||
return (ip != net.network and ip != net.broadcast
|
||||
# network or the broadcast address (which exists only in IPv4)
|
||||
return (ip != net.network
|
||||
and (net.version == 6 or ip != net.broadcast)
|
||||
and net.netmask & ip == net.network)
|
||||
|
||||
|
||||
|
@ -146,6 +146,37 @@ class TestSubnetAllocation(testlib_api.SqlTestCase):
|
||||
self.assertEqual(detail.gateway_ip,
|
||||
netaddr.IPAddress('10.1.2.254'))
|
||||
|
||||
def test_allocate_specific_ipv6_subnet_specific_gateway(self):
|
||||
# Same scenario as described in bug #1466322
|
||||
sp = self._create_subnet_pool(self.plugin, self.ctx, 'test-sp',
|
||||
['2210::/64'],
|
||||
64, 6)
|
||||
sp = self.plugin._get_subnetpool(self.ctx, sp['id'])
|
||||
with self.ctx.session.begin(subtransactions=True):
|
||||
sa = subnet_alloc.SubnetAllocator(sp, self.ctx)
|
||||
req = ipam.SpecificSubnetRequest(self._tenant_id,
|
||||
uuidutils.generate_uuid(),
|
||||
'2210::/64',
|
||||
'2210::ffff:ffff:ffff:ffff')
|
||||
res = sa.allocate_subnet(req)
|
||||
detail = res.get_details()
|
||||
self.assertEqual(detail.gateway_ip,
|
||||
netaddr.IPAddress('2210::ffff:ffff:ffff:ffff'))
|
||||
|
||||
def test_allocate_specific_ipv4_subnet_specific_broadcast_gateway(self):
|
||||
# Valid failure in subnet creation due to gateway==broadcast ip
|
||||
sp = self._create_subnet_pool(self.plugin, self.ctx, 'test-sp',
|
||||
['10.1.0.0/24'],
|
||||
24, 4)
|
||||
sa = subnet_alloc.SubnetAllocator(sp, self.ctx)
|
||||
req = ipam.SpecificSubnetRequest(self._tenant_id,
|
||||
uuidutils.generate_uuid(),
|
||||
'10.1.0.0/24',
|
||||
gateway_ip='10.1.0.255')
|
||||
self.assertRaises(n_exc.SubnetAllocationError,
|
||||
sa.allocate_subnet,
|
||||
req)
|
||||
|
||||
def test__allocation_value_for_tenant_no_allocations(self):
|
||||
sp = self._create_subnet_pool(self.plugin, self.ctx, 'test-sp',
|
||||
['10.1.0.0/16', '192.168.1.0/24'],
|
||||
|
Loading…
x
Reference in New Issue
Block a user