Commit 610013dc authored by Ad Schellevis's avatar Ad Schellevis

(firewall, nat) add address family for portforwards, https://github.com/opnsense/core/issues/807

parent ebe341ec
......@@ -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);
}
}
......
......@@ -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');
});
</script>
......@@ -571,6 +587,23 @@ $( document ).ready(function() {
</div>
</td>
</tr>
<tr>
<td><a id="help_for_ipv46" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("TCP/IP Version");?></td>
<td>
<select name="ipprotocol" class="selectpicker" data-width="auto" data-live-search="true" data-size="5" >
<?php
foreach (array('inet' => 'IPv4','inet6' => 'IPv6') as $proto => $name): ?>
<option value="<?=$proto;?>" <?= $proto == $pconfig['ipprotocol'] ? "selected=\"selected\"" : "";?>>
<?=$name;?>
</option>
<?php
endforeach; ?>
</select>
<div class="hidden" for="help_for_ipv46">
<?=gettext("Select the Internet Protocol version this rule applies to");?>
</div>
</td>
</tr>
<tr>
<td><a id="help_for_proto" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Protocol"); ?></td>
<td>
......@@ -635,9 +668,9 @@ $( document ).ready(function() {
<td>
<div class="input-group">
<!-- updates to "other" option in src -->
<input type="text" for="src" value="<?=$pconfig['src'];?>" aria-label="<?=gettext("Source address");?>"/>
<select name="srcmask" class="selectpicker" data-size="5" id="srcmask" data-width="auto" for="src" >
<?php for ($i = 32; $i > 0; $i--): ?>
<input type="text" id="src_address" for="src" value="<?=$pconfig['src'];?>" aria-label="<?=gettext("Source address");?>"/>
<select name="srcmask" data-network-id="src_address" class="selectpicker ipv4v6net" data-size="5" id="srcmask" data-width="auto" for="src" >
<?php for ($i = 128; $i > 0; $i--): ?>
<option value="<?=$i;?>" <?= $i == $pconfig['srcmask'] ? "selected=\"selected\"" : ""; ?>><?=$i;?></option>
<?php endfor; ?>
</select>
......@@ -779,9 +812,9 @@ $( document ).ready(function() {
<td>
<div class="input-group">
<!-- updates to "other" option in src -->
<input type="text" for="dst" value="<?= !is_specialnet($pconfig['dst']) ? $pconfig['dst'] : "";?>" aria-label="<?=gettext("Destination address");?>"/>
<select name="dstmask" class="selectpicker" data-size="5" id="dstmask" data-width="auto" for="dst" >
<?php for ($i = 32; $i > 0; $i--): ?>
<input type="text" id="dst_address" for="dst" value="<?= !is_specialnet($pconfig['dst']) ? $pconfig['dst'] : "";?>" aria-label="<?=gettext("Destination address");?>"/>
<select name="dstmask" data-network-id="dst_address" class="selectpicker ipv4v6net" data-size="5" id="dstmask" data-width="auto" for="dst" >
<?php for ($i = 128; $i > 0; $i--): ?>
<option value="<?=$i;?>" <?= $i == $pconfig['dstmask'] ? "selected=\"selected\"" : ""; ?>><?=$i;?></option>
<?php endfor; ?>
</select>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment