From 09315582d74add9e42a45e1f2b2a80c8e802423f Mon Sep 17 00:00:00 2001 From: jim-p Date: Wed, 29 Dec 2010 14:01:40 -0500 Subject: [PATCH] Add address pool support to outbound NAT. Allow specifying a subnet for outbound NAT rules (via a subnet of proxy arp VIPs) or a host-type alias for outbound NAT rules, and give the user a choice of pool options for address selection from within the pool. --- etc/inc/filter.inc | 27 ++++++---- usr/local/www/firewall_nat_out_edit.php | 70 ++++++++++++++++++++++--- 2 files changed, 80 insertions(+), 17 deletions(-) diff --git a/etc/inc/filter.inc b/etc/inc/filter.inc index 7564a2398c..ee63e433b1 100644 --- a/etc/inc/filter.inc +++ b/etc/inc/filter.inc @@ -1087,13 +1087,18 @@ function filter_generate_reflection($rule, $nordr, $rdr_ifs, $srcaddr, $dstaddr_ } /* Generate a 'nat on' or 'no nat on' rule for given interface */ -function filter_nat_rules_generate_if($if, $src = "any", $srcport = "", $dst = "any", $dstport = "", $natip = "", $natport = "", $nonat = false, $staticnatport = false, $proto = "") { +function filter_nat_rules_generate_if($if, $src = "any", $srcport = "", $dst = "any", $dstport = "", $natip = "", $natport = "", $nonat = false, $staticnatport = false, $proto = "", $poolopts = "") { global $config, $FilterIflist; /* XXX: billm - any idea if this code is needed? */ if($src == "/32" || $src{0} == "/") return "# src incorrectly specified\n"; if($natip != "") { - $tgt = "{$natip}/32"; + if (is_subnet($natip)) + $tgt = $natip; + elseif (is_alias($natip)) + $tgt = "\${$natip}"; + else + $tgt = "{$natip}/32"; } else { $natip = get_interface_ip($if); if(is_ipaddr($natip)) @@ -1125,18 +1130,17 @@ function filter_nat_rules_generate_if($if, $src = "any", $srcport = "", $dst = " if($dstport != "") $dst .= " port {$dstport}"; /* outgoing static-port option, hamachi, Grandstream, VOIP, etc */ + $staticnatport_txt = ""; if($staticnatport) - $staticnatport_txt = " static-port"; - else - if(!$natport) - $staticnatport_txt = " port 1024:65535"; // set source port range - else - $staticnatport_txt = ""; + $staticnatport_txt = "static-port"; + elseif(!$natport) + $tgt .= " port 1024:65535"; // set source port range /* Allow for negating NAT entries */ if($nonat) { $nat = "no nat"; $target = ""; $staticnatport_txt = ""; + $poolopts = ""; } else { $nat = "nat"; $target = "-> {$tgt}"; @@ -1144,7 +1148,7 @@ function filter_nat_rules_generate_if($if, $src = "any", $srcport = "", $dst = " $if_friendly = $FilterIflist[$if]['descr']; /* Put all the pieces together */ if($if_friendly) - $natrule = "{$nat} on \${$if_friendly} {$protocol} from {$src} to {$dst} {$target}{$staticnatport_txt}\n"; + $natrule = "{$nat} on \${$if_friendly} {$protocol} from {$src} to {$dst} {$target} {$poolopts} {$staticnatport_txt}\n"; else $natrule .= "# Could not convert {$if} to friendly name(alias)\n"; return $natrule; @@ -1237,6 +1241,8 @@ function filter_nat_rules_generate() { else $natif = $obent['interface']; + $poolopts = (is_subnet($obent['target']) || is_alias($obent['target'])) ? $obent['poolopts'] : ""; + if (!isset($FilterIflist[$natif])) continue; @@ -1249,7 +1255,8 @@ function filter_nat_rules_generate() { $obent['natport'], isset($obent['nonat']), isset($obent['staticnatport']), - $obent['protocol'] + $obent['protocol'], + $poolopts ); } } diff --git a/usr/local/www/firewall_nat_out_edit.php b/usr/local/www/firewall_nat_out_edit.php index e00994ba73..7734d9ec10 100755 --- a/usr/local/www/firewall_nat_out_edit.php +++ b/usr/local/www/firewall_nat_out_edit.php @@ -54,6 +54,10 @@ if (!is_array($config['nat']['advancedoutbound']['rule'])) { $a_out = &$config['nat']['advancedoutbound']['rule']; +if (!is_array($config['aliases']['alias'])) + $config['aliases']['alias'] = array(); +$a_aliases = &$config['aliases']['alias']; + $id = $_GET['id']; if (isset($_POST['id'])) { $id = $_POST['id']; @@ -75,6 +79,7 @@ if (isset($id) && $a_out[$id]) { $pconfig['dstport'] = $a_out[$id]['dstport']; $pconfig['natport'] = $a_out[$id]['natport']; $pconfig['target'] = $a_out[$id]['target']; + $pconfig['poolopts'] = $a_out[$id]['poolopts']; $pconfig['interface'] = $a_out[$id]['interface']; if (!$pconfig['interface']) { $pconfig['interface'] = "wan"; @@ -149,10 +154,23 @@ if ($_POST) { } } - if ($_POST['target'] && !is_ipaddr($_POST['target']) && !isset($_POST['nonat'])) { + if ($_POST['target'] && !is_ipaddr($_POST['target']) && !is_subnet($_POST['target']) && !is_alias($_POST['target']) && !isset($_POST['nonat'])) { $input_errors[] = gettext("A valid target IP address must be specified."); } + /* Verify Pool Options */ + $poolopts = ""; + if ($_POST['poolopts']) { + if (is_subnet($_POST['target'])) + $poolopts = $_POST['poolopts']; + elseif (is_alias($_POST['target'])) { + if (substr($_POST['poolopts'], 0, 11) == "round-robin") + $poolopts = $_POST['poolopts']; + else + $input_errors[] = gettext("Only Round Robin pool options may be chosen when selecting an alias."); + } + } + /* if user has selected any as source, set it here */ if($_POST['source_type'] == "any") { $osn = "any"; @@ -184,6 +202,7 @@ if ($_POST) { $natent['descr'] = $_POST['descr']; $natent['target'] = (!isset($_POST['nonat'])) ? $_POST['target'] : ""; $natent['interface'] = $_POST['interface']; + $natent['poolopts'] = $poolopts; /* static-port */ if(isset($_POST['staticnatport']) && $protocol_uses_ports && !isset($_POST['nonat'])) { @@ -320,6 +339,16 @@ function proto_change() { document.getElementById("tportstatic_tr").style.display = 'none'; } } +function poolopts_change() { + if ($('target').options[$('target').selectedIndex].text.substring(0,4) == "Host") { + $('poolopts_tr').style.display = ''; + } else if ($('target').options[$('target').selectedIndex].text.substring(0,6) == "Subnet") { + $('poolopts_tr').style.display = ''; + } else { + $('poolopts').selectedIndex = 0; + $('poolopts_tr').style.display = 'none'; + } +} //--> @@ -467,7 +496,7 @@ any)");?> - if ($sn['mode'] == "proxyarp" && $sn['type'] == "network"): $start = ip2long32(gen_subnet($sn['subnet'], $sn['subnet_bits'])); $end = ip2long32(gen_subnet_max($sn['subnet'], $sn['subnet_bits'])); - $len = $end - $start; - - for ($i = 0; $i <= $len; $i++): + $len = $end - $start; ?> + + @@ -487,7 +516,11 @@ any)");?> + foreach ($a_aliases as $alias): + if ($alias['type'] != "host") + continue; ?> + + @@ -497,8 +530,30 @@ any)");?> - +
+ + + + @@ -545,6 +600,7 @@ typesel_change(); staticportchange(); nonat_change(); proto_change(); +poolopts_change(); //-->
  
Pool Options +
+ +
+ *
+ *
+ *
+ *
+ *
+

+