From 8ae34afbba9bf24baaad37cf2edf96d570070a53 Mon Sep 17 00:00:00 2001 From: Ad Schellevis Date: Thu, 24 Aug 2017 22:49:04 +0200 Subject: [PATCH] virtual_ip, add optional vhid to support alias ip's on carp. for https://github.com/opnsense/core/issues/1779 --- src/etc/inc/interfaces.inc | 3 ++- src/www/firewall_virtual_ip.php | 25 --------------------- src/www/firewall_virtual_ip_edit.php | 33 ++++++++++++++++++++++++---- 3 files changed, 31 insertions(+), 30 deletions(-) diff --git a/src/etc/inc/interfaces.inc b/src/etc/inc/interfaces.inc index ac6250965..6823df361 100644 --- a/src/etc/inc/interfaces.inc +++ b/src/etc/inc/interfaces.inc @@ -1825,7 +1825,8 @@ function interface_ipalias_configure(&$vip) if (is_ipaddrv6($vip['subnet'])) { $af = "inet6"; } - mwexec("/sbin/ifconfig " . escapeshellarg($if) ." {$af} ". escapeshellarg($vip['subnet']) ."/" . escapeshellarg($vip['subnet_bits']) . " alias"); + $vhid = !empty($vip['vhid']) ? "vhid " . escapeshellarg($vip['vhid']) : ""; + mwexec("/sbin/ifconfig " . escapeshellarg($if) ." {$af} ". escapeshellarg($vip['subnet']) ."/" . escapeshellarg($vip['subnet_bits']) . " alias ". $vhid); } function interface_carp_configure(&$vip) diff --git a/src/www/firewall_virtual_ip.php b/src/www/firewall_virtual_ip.php index 4aff552ea..be161cf03 100644 --- a/src/www/firewall_virtual_ip.php +++ b/src/www/firewall_virtual_ip.php @@ -85,31 +85,6 @@ function deleteVIPEntry($id) { } } - if ($a_vip[$id]['mode'] == "ipalias") { - $subnet = gen_subnet($a_vip[$id]['subnet'], $a_vip[$id]['subnet_bits']) . "/" . $a_vip[$id]['subnet_bits']; - $found_if = false; - $found_carp = false; - $found_other_alias = false; - - if ($subnet == $if_subnet) - $found_if = true; - - $vipiface = $a_vip[$id]['interface']; - foreach ($a_vip as $vip_id => $vip) { - if ($vip_id != $id) { - if ($vip['interface'] == $vipiface && ip_in_subnet($vip['subnet'], $subnet)) { - if ($vip['mode'] == "carp") { - $found_carp = true; - } else if ($vip['mode'] == "ipalias") { - $found_other_alias = true; - } - } - } - } - if ($found_carp === true && $found_other_alias === false && $found_if === false) { - $input_errors[] = sprintf(gettext("This entry cannot be deleted because it is still referenced by a CARP IP with the description %s."), $vip['descr']); - } - } if (count($input_errors) == 0) { // Special case since every proxyarp vip is handled by the same daemon. if ($a_vip[$id]['mode'] == "proxyarp") { diff --git a/src/www/firewall_virtual_ip_edit.php b/src/www/firewall_virtual_ip_edit.php index c030c0319..0b4aa7a70 100644 --- a/src/www/firewall_virtual_ip_edit.php +++ b/src/www/firewall_virtual_ip_edit.php @@ -63,7 +63,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { $configId = $id; } $pconfig = array(); - $pconfig['vhid'] = find_last_used_vhid() + 1; $form_fields = array('mode', 'vhid', 'advskew', 'advbase', 'password', 'subnet', 'subnet_bits' , 'descr' ,'type', 'interface' ); @@ -140,9 +139,9 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { if ($pconfig['mode'] == 'carp') { /* verify against reusage of vhids */ foreach($config['virtualip']['vip'] as $vipId => $vip) { - if(isset($vip['vhid']) && $vip['vhid'] == $pconfig['vhid'] && $vip['interface'] == $pconfig['interface'] && $vipId <> $id) { - $input_errors[] = sprintf(gettext("VHID %s is already in use on interface %s. Pick a unique number on this interface."),$pconfig['vhid'], convert_friendly_interface_to_friendly_descr($pconfig['interface'])); - } + if (isset($vip['vhid']) && $vip['vhid'] == $pconfig['vhid'] && $vip['interface'] == $pconfig['interface'] && $vipId <> $id) { + $input_errors[] = sprintf(gettext("VHID %s is already in use on interface %s. Pick a unique number on this interface."),$pconfig['vhid'], convert_friendly_interface_to_friendly_descr($pconfig['interface'])); + } } if (empty($pconfig['password'])) { $input_errors[] = gettext("You must specify a CARP password that is shared between the two VHID members."); @@ -153,6 +152,16 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') { } } else if ($pconfig['mode'] != 'ipalias' && $pconfig['interface'] == "lo0") { $input_errors[] = gettext("For this type of vip localhost is not allowed."); + } elseif ($pconfig['mode'] == 'ipalias' && !empty($pconfig['vhid'])) { + $carpvip_found = false; + foreach($config['virtualip']['vip'] as $vipId => $vip) { + if ($vip['interface'] == $pconfig['interface'] && $vip['vhid'] == $pconfig['vhid'] && $vip['mode'] == 'carp') { + $carpvip_found = true ; + } + } + if (!$carpvip_found) { + $input_errors[] = sprintf(gettext("VHID %s should be defined on interface %s."),$pconfig['vhid'], convert_friendly_interface_to_friendly_descr($pconfig['interface'])); + } } } @@ -237,10 +246,12 @@ $( document ).ready(function() { $("#advbase").attr('disabled', true); $("#noexpand").attr('disabled', true); $("#noexpandrow").addClass("hidden"); + $("#vhid_none").attr('disabled', false); switch ($(this).val()) { case "ipalias": $("#type").prop("selectedIndex",0); + $("#vhid").attr('disabled', false); $("#subnet_bits").attr('disabled', false); $("#typenote").html(""); break; @@ -251,6 +262,10 @@ $( document ).ready(function() { $("#vhid").attr('disabled', false); $("#advskew").attr('disabled', false); $("#advbase").attr('disabled', false); + $("#vhid_none").attr('disabled', true); + if ($("#vhid").val() == null) { + $("#max_vhid").click(); + } $("#typenote").html(""); break; case "proxyarp": @@ -272,6 +287,12 @@ $( document ).ready(function() { }, 100); }); + $("#max_vhid").click(function(event){ + event.preventDefault(); + $("#vhid").val($(this).data('vhid')); + $("#vhid").selectpicker('refresh'); + }); + // toggle initial mode change $("#mode").change(); @@ -393,12 +414,16 @@ $( document ).ready(function() { +