From bdcf4c4154bcfc73f3c09c7f8cbc558af22e125c Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 29 Feb 2024 16:03:54 -0500 Subject: [PATCH] Fixes #15220: Move IP mask validation logic from form to model --- netbox/ipam/forms/model_forms.py | 14 -------------- netbox/ipam/models/ip.py | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/netbox/ipam/forms/model_forms.py b/netbox/ipam/forms/model_forms.py index c7e3f92a3..71aa32d52 100644 --- a/netbox/ipam/forms/model_forms.py +++ b/netbox/ipam/forms/model_forms.py @@ -367,20 +367,6 @@ class IPAddressForm(TenancyForm, NetBoxModelForm): 'primary_for_parent', _("Only IP addresses assigned to an interface can be designated as primary IPs.") ) - # 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 = _("{ip} is a network ID, which may not be assigned to an interface.").format(ip=address.ip) - 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 = _("{ip} is a broadcast address, which may not be assigned to an interface.").format( - ip=address.ip - ) - raise ValidationError(msg) - def save(self, *args, **kwargs): ipaddress = super().save(*args, **kwargs) diff --git a/netbox/ipam/models/ip.py b/netbox/ipam/models/ip.py index 76fae2990..ca9592d6e 100644 --- a/netbox/ipam/models/ip.py +++ b/netbox/ipam/models/ip.py @@ -844,6 +844,25 @@ class IPAddress(PrimaryModel): 'address': _("Cannot create IP address with /0 mask.") }) + # Do not allow assigning a network ID or broadcast address to an interface. + if self.assigned_object: + if self.address.ip == self.address.network: + msg = _("{ip} is a network ID, which may not be assigned to an interface.").format( + ip=self.address.ip + ) + if self.address.version == 4 and self.address.prefixlen not in (31, 32): + raise ValidationError(msg) + if self.address.version == 6 and self.address.prefixlen not in (127, 128): + raise ValidationError(msg) + if ( + self.address.version == 4 and self.address.ip == self.address.broadcast and + self.address.prefixlen not in (31, 32) + ): + msg = _("{ip} is a broadcast address, which may not be assigned to an interface.").format( + ip=self.address.ip + ) + raise ValidationError(msg) + # Enforce unique IP space (if applicable) if (self.vrf is None and get_config().ENFORCE_GLOBAL_UNIQUE) or (self.vrf and self.vrf.enforce_unique): duplicate_ips = self.get_duplicates()