From 516114406bd88d6eda76c958f40c38aac263a4a1 Mon Sep 17 00:00:00 2001 From: Ermal Date: Wed, 18 May 2011 21:03:50 +0000 Subject: Ticket #1534, #1433. Properly merge carp interfaces and do not reload carp interfaces that have not change any configuration parameter. Also make merge_config_section_xmlrpc() an alias for restore_config_section_xmlrpc() since that what it is. --- usr/local/www/xmlrpc.php | 98 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 68 insertions(+), 30 deletions(-) (limited to 'usr/local/www/xmlrpc.php') diff --git a/usr/local/www/xmlrpc.php b/usr/local/www/xmlrpc.php index 9deffcc..55fac86 100755 --- a/usr/local/www/xmlrpc.php +++ b/usr/local/www/xmlrpc.php @@ -159,25 +159,85 @@ function restore_config_section_xmlrpc($raw_params) { if(!xmlrpc_auth($params)) return $xmlrpc_g['return']['authfail']; $vipbackup = array(); + $oldvips = array(); if (isset($params[0]['virtualip'])) { if(is_array($config['virtualip']['vip'])) { - foreach ($config['virtualip']['vip'] as $vip) - interface_vip_bring_down($vip); + foreach ($config['virtualip']['vip'] as $vipindex => $vip) { + if ($vip['mode'] == "carp") + $oldvips[$vip['vhid']] = "{$vip['password']}{$vip['advskew']}{$vip['subnet']}{$vip['subnet_bits']}{$vip['advbase']}"; + if ((($vip['mode'] == 'ipalias') || ($vip['mode'] == 'proxyarp')) && substr($vip['interface'], 0, 3) != "vip") + $vipbackup[] = $vip; + } } - $vipbackup = $config['virtualip']['vip']; } // For vip section, first keep items sent from the master $config = array_merge($config, $params[0]); - // Then add ipalias and proxyarp types already defined on the backup + + /* + * NOTE: Do not rely on array_merge since it might keep vips in there if there were + * many vips previously and only a reduced list is sent for synching. + */ + if (is_array($params[0]['virtualip']) && is_array($params[0]['virtualip']['vip'])) { + if (!is_array($config['virtualip'])) + $config['virtualip'] = array(); + $config['virtualip'] = $params[0]['virtualip']; + } else + $config['virtualip'] = array(); // Reset + + /* Then add ipalias and proxyarp types already defined on the backup */ if (is_array($vipbackup)) { foreach ($vipbackup as $vip) { - if ((($vip['mode'] == 'ipalias') || ($vip['mode'] == 'proxyarp')) && substr($vip['interface'], 0, 3) != "vip") - array_unshift($config['virtualip']['vip'], $vip); + array_unshift($config['virtualip']['vip'], $vip); } } + + /* Log what happened */ $mergedkeys = implode(",", array_keys($params[0])); write_config(sprintf(gettext("Merged in config (%s sections) from XMLRPC client."),$mergedkeys)); - interfaces_vips_configure(); + + /* + * The real work on handling the vips specially + * This is a copy of intefaces_vips_configure with addition of not reloading existing/not changed carps + */ + if (is_array($config['virtualip']) && is_array($config['virtualip']['vip'])) { + $carp_setuped = false; + $anyproxyarp = false; + foreach ($config['virtualip']['vip'] as $vip) { + if (isset($oldvips[$vip['vhid']])) { + if ($oldvips[$vip['vhid']] == "{$vip['password']}{$vip['advskew']}{$vip['subnet']}{$vip['subnet_bits']}{$vip['advbase']}") { + if (does_interface_exist("vip{$vip['vhid']}")) + continue; // Skip reconfiguring this vips since nothing has changed. + } else + unset($oldvips['vhid']); + } + + switch ($vip['mode']) { + case "proxyarp": + $anyproxyarp = true; + break; + case "ipalias": + interface_ipalias_configure(&$vip); + break; + case "carp": + if ($carp_setuped == false) + $carp_setuped = true; + interface_carp_configure($vip); + break; + case "carpdev-dhcp": + interface_carpdev_configure($vip); + break; + } + } + /* Cleanup remaining old carps */ + foreach ($oldvips as $oldvipif => $oldvippar) { + if (does_interface_exist("vip{$oldvipif}")) + pfSense_interface_destroy("vip{$oldvipif}"); + } + if ($carp_setuped == true) + interfaces_carp_setup(); + if ($anyproxyarp == true) + interface_proxyarp_configure(); + } return $xmlrpc_g['return']['true']; } @@ -218,29 +278,7 @@ $merge_config_section_sig = array( function merge_config_section_xmlrpc($raw_params) { global $config, $xmlrpc_g; - $params = xmlrpc_params_to_php($raw_params); - if(!xmlrpc_auth($params)) - return $xmlrpc_g['return']['authfail']; - if (isset($params[0]['virtualip'])) { - if(is_array($config['virtualip']['vip'])) { - foreach ($config['virtualip']['vip'] as $vip) - interface_vip_bring_down($vip); - } - $vipbackup = $config['virtualip']['vip']; - } - $config = array_merge_recursive_unique($config, $params[0]); - // Then add ipalias and proxyarp types already defined on the backup - if (is_array($vipbackup)) { - foreach ($vipbackup as $vip) { - if ((($vip['mode'] == 'ipalias') || ($vip['mode'] == 'proxyarp')) && substr($vip['interface'], 0, 3) != "vip") - array_unshift($config['virtualip']['vip'], $vip); - } - } - $mergedkeys = implode(",", array_keys($params[0])); - write_config("Merged in config ({$mergedkeys} sections) from XMLRPC client."); - interfaces_vips_configure(); - - return $xmlrpc_g['return']['true']; + return restore_config_section_xmlrpc($raw_params); } /*****************************/ -- cgit v1.1