diff options
author | Ermal <eri@pfsense.org> | 2010-08-26 16:37:38 +0000 |
---|---|---|
committer | Ermal <eri@pfsense.org> | 2010-08-26 16:38:12 +0000 |
commit | e19b7d1ea849f40f1de194cadeefb3c289812442 (patch) | |
tree | 3cca6a4f1865575e039bb63c63a1084c8ff6486a | |
parent | 1bd4b4dcd97c2c77aa8900e3113d5050d44af469 (diff) | |
download | pfsense-e19b7d1ea849f40f1de194cadeefb3c289812442.zip pfsense-e19b7d1ea849f40f1de194cadeefb3c289812442.tar.gz |
Allow carp interfaces to sit on top of aliases. Also add safety belts to ipalias deletion for this to avoid breakage. Trigered-by: http://forum.pfsense.org/index.php/topic,27834.0.html
-rw-r--r-- | etc/inc/interfaces.inc | 21 | ||||
-rwxr-xr-x | usr/local/www/firewall_virtual_ip.php | 9 | ||||
-rwxr-xr-x | usr/local/www/firewall_virtual_ip_edit.php | 2 |
3 files changed, 30 insertions, 2 deletions
diff --git a/etc/inc/interfaces.inc b/etc/inc/interfaces.inc index ab917fd..8259fec 100644 --- a/etc/inc/interfaces.inc +++ b/etc/inc/interfaces.inc @@ -1689,7 +1689,7 @@ function interface_carp_configure(&$vip) { /* Ensure CARP IP really exists prior to loading up. */ $ww_subnet_ip = find_interface_ip($realif); $ww_subnet_bits = find_interface_subnet($realif); - if (!ip_in_subnet($vip['subnet'], gen_subnet($ww_subnet_ip, $ww_subnet_bits) . "/" . $ww_subnet_bits)) { + if (!ip_in_subnet($vip['subnet'], gen_subnet($ww_subnet_ip, $ww_subnet_bits) . "/" . $ww_subnet_bits) && !ip_in_interface_alias_subnet($vip['interface'], $vip['subnet'])) { file_notice("CARP", "Sorry but we could not find a matching real interface subnet for the virtual IP address {$vip['subnet']}.", "Firewall: Virtual IP", ""); return; } @@ -3100,6 +3100,25 @@ function find_interface_subnet($interface, $flush = false) return $interface_sn_arr_cache[$interface]; } +function ip_in_interface_alias_subnet($interface, $ipalias) { + global $config; + + if (empty($interface) || !is_ipaddr($ipalias)) + return 0; + if (is_array($config['virtualip']['vip'])) { + foreach ($config['virtualip']['vip'] as $vip) { + switch ($vip['mode']) { + case "ipalias": + if ($vip['interface'] <> $interface) + continue; + if (ip_in_subnet($ipalias, gen_subnet($vip['subnet'], $vip['subnet_bits']) . "/" . $vip['subnet_bits'])) + return 1; + break; + } + } + } +} + function get_interface_ip($interface = "wan") { $realif = get_real_interface($interface); diff --git a/usr/local/www/firewall_virtual_ip.php b/usr/local/www/firewall_virtual_ip.php index 1ccfc2a..ec15fdf 100755 --- a/usr/local/www/firewall_virtual_ip.php +++ b/usr/local/www/firewall_virtual_ip.php @@ -108,6 +108,15 @@ if ($_GET['act'] == "del") { } } + if ($a_vip[$_GET['id']]['mode'] == "proxyarp") { + $vipiface = $a_vip[$_GET['id']]['interface']; + foreach ($a_vip as $vip) { + if ($vip['interface'] == $vipiface && $vip['mode'] == "carp") + if (ip_in_subnet($vip['subnet'], gen_subnet($a_vip[$_GET['id']]['subnet'], $a_vip[$_GET['id']]['subnet_bits']) . "/" . $a_vip[$_GET['id']]['subnet_bits'])) + $input_errors[] = gettext("This entry cannot be deleted because it is still referenced by CARP") . " {$vip['descr']}."; + } + } + if (!$input_errors) { // Special case since every proxyarp vip is handled by the same daemon. if ($a_vip[$_GET['id']]['mode'] == "proxyarp") { diff --git a/usr/local/www/firewall_virtual_ip_edit.php b/usr/local/www/firewall_virtual_ip_edit.php index ffddef7..bdad11a 100755 --- a/usr/local/www/firewall_virtual_ip_edit.php +++ b/usr/local/www/firewall_virtual_ip_edit.php @@ -143,7 +143,7 @@ if ($_POST) { $parent_ip = get_interface_ip($_POST['interface']); $parent_sn = get_interface_subnet($_POST['interface']); - if (!ip_in_subnet($_POST['subnet'], gen_subnet($parent_ip, $parent_sn) . "/" . $parent_sn)) { + if (!ip_in_subnet($_POST['subnet'], gen_subnet($parent_ip, $parent_sn) . "/" . $parent_sn) && !ip_in_interface_alias_subnet($_POST['interface'], $_POST['subnet'])) { $cannot_find = $_POST['subnet'] . "/" . $_POST['subnet_bits'] ; $input_errors[] = sprintf(gettext("Sorry, we could not locate an interface with a matching subnet for %s. Please add an IP alias in this subnet on this interface."),$cannot_find); } else if ($parent_sn != $_POST['subnet_bits']) |