diff --git a/src/etc/inc/filter.inc b/src/etc/inc/filter.inc index 869775b63..f91d0a61d 100644 --- a/src/etc/inc/filter.inc +++ b/src/etc/inc/filter.inc @@ -1945,6 +1945,7 @@ function filter_nat_rules_generate(&$FilterIflist) $localport = ""; break; } + $address_family = !empty($rule['ipprotocol']) ? $rule['ipprotocol'] : "inet"; $target = alias_expand($rule['target']); if (!$target && !isset($rule['nordr'])) { @@ -2045,8 +2046,7 @@ function filter_nat_rules_generate(&$FilterIflist) if ($srcaddr <> "" && $dstaddr <> "" && $natif) { - $natrules .= "{$nordr}rdr {$rdrpass}on {$natif} proto {$protocol} from {$srcaddr} to {$dstaddr}" . ($nordr == "" ? " -> {$target}{$localport}" : ""); - + $natrules .= "{$nordr}rdr {$rdrpass}on {$natif} {$address_family} proto {$protocol} from {$srcaddr} to {$dstaddr}" . ($nordr == "" ? " -> {$target}{$localport}" : ""); /* Does this rule redirect back to a internal host? */ if (isset($rule['destination']['any']) && !isset($rule['nordr']) && !isset($config['system']['enablenatreflectionhelper']) && !interface_has_gateway($rule['interface'])) { $rule_interface_ip = find_interface_ip($natif); @@ -2072,7 +2072,7 @@ function filter_nat_rules_generate(&$FilterIflist) $rdr_if_list = "{ {$rdr_if_list} }"; } $natrules .= "\n# Reflection redirect\n"; - $natrules .= "{$nordr}rdr {$rdrpass}on {$rdr_if_list} proto {$protocol} from {$srcaddr} to {$dstaddr_reflect}" . ($nordr == "" ? " -> {$target}{$localport}" : ""); + $natrules .= "{$nordr}rdr {$rdrpass}on {$rdr_if_list} {$address_family} proto {$protocol} from {$srcaddr} to {$dstaddr_reflect}" . ($nordr == "" ? " -> {$target}{$localport}" : ""); $nat_if_list = array_merge(array($natif), $nat_if_list); } } diff --git a/src/www/firewall_nat_edit.php b/src/www/firewall_nat_edit.php index d68b56aed..20f93487c 100644 --- a/src/www/firewall_nat_edit.php +++ b/src/www/firewall_nat_edit.php @@ -121,6 +121,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { // initialize form and set defaults $pconfig = array(); $pconfig['protocol'] = "tcp"; + $pconfig['ipprotocol'] = "inet"; $pconfig['srcbeginport'] = "any"; $pconfig['srcendport'] = "any"; $pconfig['interface'] = "wan"; @@ -130,7 +131,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { if (isset($configId)) { // copy 1-on-1 foreach (array('protocol','target','local-port','descr','interface','associated-rule-id','nosync' - ,'natreflection','created','updated') as $fieldname) { + ,'natreflection','created','updated','ipprotocol') as $fieldname) { if (isset($a_nat[$configId][$fieldname])) { $pconfig[$fieldname] = $a_nat[$configId][$fieldname]; } @@ -235,6 +236,16 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { if (!is_specialnet($pconfig['src']) && !is_ipaddroralias($pconfig['src'])) { $input_errors[] = sprintf(gettext("%s is not a valid source IP address or alias."), $pconfig['src']); } + + // validate ipv4/v6, addresses should use selected address family + foreach (array('src', 'dst', 'target') as $fieldname) { + if (is_ipaddrv6($pconfig[$fieldname]) && $pconfig['ipprotocol'] != 'inet6') { + $input_errors[] = sprintf(gettext("%s is not a valid IPv4 address."), $pconfig[$fieldname]); + } + if (is_ipaddrv4($pconfig[$fieldname]) && $pconfig['ipprotocol'] != 'inet') { + $input_errors[] = sprintf(gettext("%s is not a valid IPv6 address."), $pconfig[$fieldname]); + } + } if (!empty($pconfig['srcmask']) && !is_numericint($pconfig['srcmask'])) { $input_errors[] = gettext("A valid source bit count must be specified."); } @@ -260,6 +271,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { // 1-on-1 copy $natent['protocol'] = $pconfig['protocol']; $natent['interface'] = $pconfig['interface']; + $natent['ipprotocol'] = $pconfig['ipprotocol']; $natent['descr'] = $pconfig['descr']; if (!empty($pconfig['associated-rule-id'])) { $natent['associated-rule-id'] = $pconfig['associated-rule-id']; @@ -349,6 +361,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { // Update interface, protocol and destination $filterent['interface'] = $pconfig['interface']; $filterent['protocol'] = $pconfig['protocol']; + $filterent['ipprotocol'] = $pconfig['ipprotocol']; if (!isset($filterent['destination'])) { $filterent['destination'] = array(); } @@ -513,6 +526,9 @@ $( document ).ready(function() { $('#dstendport').change(); }); + // IPv4/IPv6 select + hook_ipv4v6('ipv4v6net', 'network-id'); + }); @@ -571,6 +587,23 @@ $( document ).ready(function() { +