Skip to content

Commit cd7b334

Browse files
committed
[WIP] Do not allocate subnet router anycast for IPv6 prefixes
1 parent 517d015 commit cd7b334

File tree

2 files changed

+19
-8
lines changed

2 files changed

+19
-8
lines changed

netbox/ipam/models/ip.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -507,16 +507,20 @@ def get_available_ips(self):
507507
child_ranges.add(iprange.range)
508508
available_ips = prefix - child_ips - child_ranges
509509

510-
# IPv6, pool, or IPv4 /31-/32 sets are fully usable
511-
if self.family == 6 or self.is_pool or (self.family == 4 and self.prefix.prefixlen >= 31):
510+
# IPv6 /127's, pool, or IPv4 /31-/32 sets are fully usable
511+
if (self.family == 6 and self.prefix.prefixlen >= 127) or self.is_pool or (self.family == 4 and self.prefix.prefixlen >= 31):
512512
return available_ips
513513

514-
# For "normal" IPv4 prefixes, omit first and last addresses
515-
available_ips -= netaddr.IPSet([
516-
netaddr.IPAddress(self.prefix.first),
517-
netaddr.IPAddress(self.prefix.last),
518-
])
519-
514+
if self.family == 4:
515+
# For "normal" IPv4 prefixes, omit first and last addresses
516+
available_ips -= netaddr.IPSet([
517+
netaddr.IPAddress(self.prefix.first),
518+
netaddr.IPAddress(self.prefix.last),
519+
])
520+
else:
521+
# For IPv6 prefixes, omit the Subnet-Router anycast address
522+
# per RFC 4291
523+
available_ips -= netaddr.IPAddress(self.prefix.first)
520524
return available_ips
521525

522526
def get_first_available_ip(self):

netbox/ipam/tests/test_models.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,13 @@ def test_get_first_available_ip(self):
185185
IPAddress.objects.create(address=IPNetwork('10.0.0.4/24'))
186186
self.assertEqual(parent_prefix.get_first_available_ip(), '10.0.0.5/24')
187187

188+
def test_get_first_available_ip_ipv6(self):
189+
parent_prefix = Prefix.objects.create(prefix=IPNetwork(
190+
'2001:DB8:500::/64'))
191+
192+
self.assertEqual(parent_prefix.get_first_available_ip(),
193+
'2001:DB8:500::1/128')
194+
188195
def test_get_utilization_container(self):
189196
prefixes = (
190197
Prefix(prefix=IPNetwork('10.0.0.0/24'), status=PrefixStatusChoices.STATUS_CONTAINER),

0 commit comments

Comments
 (0)