diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Firewall/forms/dialogFilterRule.xml b/src/opnsense/mvc/app/controllers/OPNsense/Firewall/forms/dialogFilterRule.xml index dadce138db8..3ff39eae3ac 100644 --- a/src/opnsense/mvc/app/controllers/OPNsense/Firewall/forms/dialogFilterRule.xml +++ b/src/opnsense/mvc/app/controllers/OPNsense/Firewall/forms/dialogFilterRule.xml @@ -659,6 +659,31 @@ false + + header + + true + + + rule.af-to-source + + text + Source address used after translating the packet to the opposite address family. Address family translation is only valid for inbound pass rules using an explicit IPv4 or IPv6 version. + true + + false + + + + rule.af-to-destination + + text + Optional destination address or network used after translating the packet to the opposite address family. + true + + false + + rule.statistics diff --git a/src/opnsense/mvc/app/library/OPNsense/Firewall/FilterRule.php b/src/opnsense/mvc/app/library/OPNsense/Firewall/FilterRule.php index 8004e3206dd..ba11d97db95 100644 --- a/src/opnsense/mvc/app/library/OPNsense/Firewall/FilterRule.php +++ b/src/opnsense/mvc/app/library/OPNsense/Firewall/FilterRule.php @@ -67,6 +67,7 @@ class FilterRule extends Rule 'dn' => 'parsePlain', 'divert-to' => 'parsePlain,divert-to ', 'label' => 'parsePlain,label ",",63', + 'af-to' => 'parsePlain, af-to ', // af-to always appears after the label in pfctl 'descr' => 'parseComment' ); @@ -305,6 +306,14 @@ private function parseFilterRules() $rule['dn'] = sprintf('%s %s', $shaper1['type'], $shaper1['id']); } } + // restructure address family translation + if (!empty($rule['af-to-source'])) { + $address_family = $rule['ipprotocol'] === 'inet' ? 'inet6' : 'inet'; + $rule['af-to'] = sprintf('%s from %s', $address_family, $rule['af-to-source']); + if (!empty($rule['af-to-destination'])) { + $rule['af-to'] .= sprintf(' to %s', $rule['af-to-destination']); + } + } yield $rule; } diff --git a/src/opnsense/mvc/app/models/OPNsense/Firewall/Filter.php b/src/opnsense/mvc/app/models/OPNsense/Firewall/Filter.php index 5372a8de594..646e535279c 100644 --- a/src/opnsense/mvc/app/models/OPNsense/Firewall/Filter.php +++ b/src/opnsense/mvc/app/models/OPNsense/Firewall/Filter.php @@ -285,6 +285,52 @@ public function performValidation($validateFullModel = false) $rule->replyto->__reference )); } + // af-to validation + if (!$rule->{'af-to-destination'}->isEmpty() && $rule->{'af-to-source'}->isEmpty()) { + $messages->appendMessage( + new Message( + gettext("Translation destination requires a translation source."), + $rule->{'af-to-source'}->__reference + ) + ); + } elseif (!$rule->{'af-to-source'}->isEmpty()) { + if ($rule->action != 'pass') { + $messages->appendMessage(new Message( + gettext("Address family translation is only valid for pass rules."), + $rule->{'af-to-source'}->__reference + )); + } + if ($rule->direction != 'in') { + $messages->appendMessage(new Message( + gettext("Address family translation is only valid for inbound rules."), + $rule->{'af-to-source'}->__reference + )); + } + if (!in_array((string)$rule->ipprotocol, ['inet', 'inet6'], true)) { + $messages->appendMessage(new Message( + gettext("An address family must be selected when using address family translation."), + $rule->ipprotocol->__reference + )); + } + if ($rule->statetype == 'none') { + $messages->appendMessage(new Message( + gettext("Address family translation requires state tracking."), + $rule->{'af-to-source'}->__reference + )); + } + if (!$rule->gateway->isEmpty()) { + $messages->appendMessage(new Message( + gettext("Address family translation cannot be combined with route-to."), + $rule->gateway->__reference + )); + } + if (!$rule->replyto->isEmpty()) { + $messages->appendMessage(new Message( + gettext("Address family translation cannot be combined with reply-to."), + $rule->replyto->__reference + )); + } + } } } } diff --git a/src/opnsense/mvc/app/models/OPNsense/Firewall/Filter.xml b/src/opnsense/mvc/app/models/OPNsense/Firewall/Filter.xml index 793a66d24c1..a8a1ec4a1fd 100644 --- a/src/opnsense/mvc/app/models/OPNsense/Firewall/Filter.xml +++ b/src/opnsense/mvc/app/models/OPNsense/Firewall/Filter.xml @@ -192,6 +192,13 @@ filter list diverts Specify a valid divert-to target. + + N + + + Y + Y + interface gateways list -g Specify a valid gateway from the list matching the networks ip protocol.