diff --git a/netbox/ipam/forms/model_forms.py b/netbox/ipam/forms/model_forms.py index b0b08e4e0..d4be14dc4 100644 --- a/netbox/ipam/forms/model_forms.py +++ b/netbox/ipam/forms/model_forms.py @@ -362,15 +362,25 @@ class IPAddressForm(TenancyForm, NetBoxModelForm): # Do not allow assigning a network ID or broadcast address to an interface. if interface and (address := self.cleaned_data.get('address')): - if address.ip == address.network: - msg = f"{address} is a network ID, which may not be assigned to an interface." - if address.version == 4 and address.prefixlen not in (31, 32): + prefix_str = f"{self.instance.address.network}/{self.instance.address.prefixlen}" + allow_assignment_error = True + if self.instance.vrf is None: + prefix_obj = Prefix.objects.get(prefix=prefix_str) + else: + prefix_obj = Prefix.objects.get(prefix=prefix_str, vrf=self.vrf) + if prefix_obj and prefix_obj.is_pool: + allow_assignment_error = False + + if allow_assignment_error: + if address.ip == address.network: + msg = f"{address} is a network ID, which may not be assigned to an interface unless the prefix is a pool." + if address.version == 4 and address.prefixlen not in (31, 32): + raise ValidationError(msg) + if address.version == 6 and address.prefixlen not in (127, 128): + raise ValidationError(msg) + if address.version == 4 and address.ip == address.broadcast and address.prefixlen not in (31, 32): + msg = f"{address} is a broadcast address, which may not be assigned to an interface unless the prefix is a pool." raise ValidationError(msg) - if address.version == 6 and address.prefixlen not in (127, 128): - raise ValidationError(msg) - if address.version == 4 and address.ip == address.broadcast and address.prefixlen not in (31, 32): - msg = f"{address} is a broadcast address, which may not be assigned to an interface." - raise ValidationError(msg) def save(self, *args, **kwargs): ipaddress = super().save(*args, **kwargs)