diff --git a/CHANGELOG.md b/CHANGELOG.md index 46cba5041..d6e42781a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ v2.5.3 (FUTURE) ## Bug Fixes * [#2742](https://github.com/digitalocean/netbox/issues/2742) - Preserve cluster assignment when editing a device +* [#2757](https://github.com/digitalocean/netbox/issues/2757) - Always treat first/last IPs within a /31 or /127 as usable * [#2762](https://github.com/digitalocean/netbox/issues/2762) - Add missing DCIM field values to API `_choices` endpoint diff --git a/netbox/ipam/models.py b/netbox/ipam/models.py index 6f7a21236..a14e1c7ed 100644 --- a/netbox/ipam/models.py +++ b/netbox/ipam/models.py @@ -438,12 +438,23 @@ class Prefix(ChangeLoggedModel, CustomFieldModel): child_ips = netaddr.IPSet([ip.address.ip for ip in self.get_child_ips()]) available_ips = prefix - child_ips - # Remove unusable IPs from non-pool prefixes - if not self.is_pool: - available_ips -= netaddr.IPSet([ - netaddr.IPAddress(self.prefix.first), - netaddr.IPAddress(self.prefix.last), - ]) + # All IP addresses within a pool are considered usable + if self.is_pool: + return available_ips + + # All IP addresses within a point-to-point prefix (IPv4 /31 or IPv6 /127) are considered usable + if ( + self.family == 4 and self.prefix.prefixlen == 31 # RFC 3021 + ) or ( + self.family == 6 and self.prefix.prefixlen == 127 # RFC 6164 + ): + return available_ips + + # Omit first and last IP address from the available set + available_ips -= netaddr.IPSet([ + netaddr.IPAddress(self.prefix.first), + netaddr.IPAddress(self.prefix.last), + ]) return available_ips