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")
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)
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'],