diff --git a/src/opnsense/mvc/app/models/OPNsense/Interfaces/Vip.php b/src/opnsense/mvc/app/models/OPNsense/Interfaces/Vip.php index 1aca7dc8b..25f5e8772 100644 --- a/src/opnsense/mvc/app/models/OPNsense/Interfaces/Vip.php +++ b/src/opnsense/mvc/app/models/OPNsense/Interfaces/Vip.php @@ -41,21 +41,33 @@ class Vip extends BaseModel public function performValidation($validateFullModel = false) { $messages = parent::performValidation($validateFullModel); - $vips = []; + + $unqiue_addrs = []; $carp_vhids = []; + $vips = []; // collect changed VIP entries $vip_fields = ['mode', 'subnet', 'subnet_bits', 'password', 'vhid', 'interface']; foreach ($this->getFlatNodes() as $key => $node) { $tagName = $node->getInternalXMLTagName(); $parentNode = $node->getParentNode(); + if ($validateFullModel || $node->isFieldChanged()) { if ($parentNode->getInternalXMLTagName() === 'vip' && in_array($tagName, $vip_fields)) { - $parentKey = $parentNode->__reference; - $vips[$parentKey] = $parentNode; + $vips[$parentNode->__reference] = $parentNode; } } + + if ($parentNode->getInternalXMLTagName() === 'vip' && $tagName == 'subnet') { + $addr = (string)$parentNode->subnet; + if (Util::isLinkLocal($addr)) { + $addr .= '@' . (string)$parentNode->interface; + } + $unique_addrs[$parentNode->__reference] = $addr; + } + $vhid_key = sprintf("%s_%s", $parentNode->interface, $parentNode->vhid); + if ((string)$parentNode->mode == 'carp' && !isset($carp_vhids[$vhid_key])) { $carp_vhids[$vhid_key] = $parentNode; } @@ -151,6 +163,17 @@ class Vip extends BaseModel ) ); } + + /* ensure address is unique; for link-local we test with scope attached */ + $addr = (string)$node->subnet; + if (Util::isLinkLocal($addr)) { + $addr .= '@' . (string)$node->interface; + } + foreach ($unique_addrs as $refKey => $refAddr) { + if ($refKey != $key && $refAddr === $addr) { + $messages->appendMessage(new Message(gettext('Address already assigned.'), $key . '.subnet')); + } + } } return $messages; diff --git a/src/opnsense/mvc/app/models/OPNsense/Interfaces/Vip.xml b/src/opnsense/mvc/app/models/OPNsense/Interfaces/Vip.xml index 0c5a7ede0..d7e1a6e25 100644 --- a/src/opnsense/mvc/app/models/OPNsense/Interfaces/Vip.xml +++ b/src/opnsense/mvc/app/models/OPNsense/Interfaces/Vip.xml @@ -21,12 +21,6 @@ - - - Address already assigned. - UniqueConstraint - -