summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSeth Mos <seth.mos@xs4all.nl>2006-12-30 00:45:25 +0000
committerSeth Mos <seth.mos@xs4all.nl>2006-12-30 00:45:25 +0000
commit401452ec0cdf52246ce0c6623e97583f614576f9 (patch)
treeadd4578ddf1dc26e1e2d4be102d13b0d53389ad3
parent1cea5083d5e51bb46509225c937f0114089af019 (diff)
downloadpfsense-401452ec0cdf52246ce0c6623e97583f614576f9.zip
pfsense-401452ec0cdf52246ce0c6623e97583f614576f9.tar.gz
Merge in new (outbound) load balancing configuration code from HEAD.
* assign interfaces to pool instead of manual IP configuration * Only show interfaces with a gateway * Offer list of monitor IPs including interface gateways. This code is tested for outbound load balancing on a carp cluster and works for me (smos). The server side needs testing. Which I don't know how to. Let's give it a run for a snapshot or 2.
-rw-r--r--etc/inc/filter.inc6
-rw-r--r--etc/inc/vslb.inc10
-rwxr-xr-xetc/rc.newwanip6
-rwxr-xr-xusr/local/www/load_balancer_pool_edit.php264
-rwxr-xr-xusr/local/www/pool.js16
5 files changed, 254 insertions, 48 deletions
diff --git a/etc/inc/filter.inc b/etc/inc/filter.inc
index 1163d7a..d53c21f 100644
--- a/etc/inc/filter.inc
+++ b/etc/inc/filter.inc
@@ -1410,13 +1410,13 @@ function generate_user_filter_rule($rule, $ngcounter) {
foreach ($config['load_balancer']['lbpool'][$i]['servers'] as $lbsvr) {
$lbsvr_split=split("\|", $lbsvr);
if ($lbsvr_split[1] == $server)
- $gateway = $lbsvr_split[0];
+ /* deterimine interface gateway */
+ $int = convert_friendly_interface_to_real_interface_name($lbsvr_split[0]);
+ $gateway = get_interface_gateway($int);
}
}
if($foundlb == 1)
$routeto .= ", ";
- /* determine interface from gateway address */
- $int = guess_interface_from_ip($gateway);
$routeto .= "( {$int} {$gateway} ) ";
if($int == "") {
$line = "# error resolving load balancing {$gateway}";
diff --git a/etc/inc/vslb.inc b/etc/inc/vslb.inc
index dfd54f8..6dddff0 100644
--- a/etc/inc/vslb.inc
+++ b/etc/inc/vslb.inc
@@ -112,12 +112,12 @@ function slbd_configure() {
$lbsvr_split=split("\|", $lbsvr);
$svrtxt .= "\t:{$svrcnt}={$lbsvr_split[1]}:\\\n";
$svrcnt++;
+
/* Add static routes to the monitor IPs */
- $next_hop = exec_command("/sbin/route -n get {$lbsvr_split[1]} | /usr/bin/grep gateway |/usr/bin/awk '{ print \$2; };'");
- if ($next_hop != $lbsvr_split[0]) {
- mwexec("/sbin/route delete -host {$lbsvr_split[1]} 1>/dev/null 2>&1");
- mwexec("/sbin/route add -host {$lbsvr_split[1]} {$lbsvr_split[0]} 1> /dev/null 2>&1");
- }
+ $int = convert_friendly_interface_to_real_interface_name($lbsvr_split[0]);
+ $gateway = get_interface_gateway($int);
+ mwexec("/sbin/route delete -host {$lbsvr_split[1]} 1>/dev/null 2>&1");
+ mwexec("/sbin/route add -host {$lbsvr_split[1]} {$gateway} 1> /dev/null 2>&1");
}
$slbdconf .= "\t:service-port=666:\\\n";
$slbdconf .= "\t:method=round-robin:\\\n";
diff --git a/etc/rc.newwanip b/etc/rc.newwanip
index 90555a1..aa9b5ee 100755
--- a/etc/rc.newwanip
+++ b/etc/rc.newwanip
@@ -112,6 +112,12 @@ enable_rrd_graphing();
/* restart packages */
exec("/etc/rc.start_packages");
+/* reload slbd */
+/* if ($config['load_balancer']['lbpool']['type'] == "gateway") */
+slbd_configure();
+log_error("Configuring slbd");
+
+
return 0;
?> \ No newline at end of file
diff --git a/usr/local/www/load_balancer_pool_edit.php b/usr/local/www/load_balancer_pool_edit.php
index 8baa151..2a1aa97 100755
--- a/usr/local/www/load_balancer_pool_edit.php
+++ b/usr/local/www/load_balancer_pool_edit.php
@@ -31,7 +31,7 @@
require("guiconfig.inc");
if (!is_array($config['load_balancer']['lbpool'])) {
- $config['load_balancer']['lbpool'] = array();
+ $config['load_balancer']['lbpool'] = array();
}
$a_pool = &$config['load_balancer']['lbpool'];
@@ -84,8 +84,8 @@ if ($_POST) {
$input_errors[] = "{$svrent} is not a valid IP address.";
} else {
$split_ip = split("\|", $svrent);
- if(!is_ipaddr($split_ip[0]))
- $input_errors[] = "{$split_ip[0]} is not a valid IP address.";
+ /* if(!is_ipaddr($split_ip[0]))
+ $input_errors[] = "{$split_ip[0]} is not a valid IP address."; */
if(!is_ipaddr($split_ip[1]))
$input_errors[] = "{$split_ip[1]} is not a valid IP address.";
}
@@ -99,12 +99,14 @@ if ($_POST) {
for ($j = 1; isset ($config['interfaces']['opt' . $j]); $j++) {
$ifdescrs['opt' . $j] = "opt" . $j;
}
- foreach($pconfig['servers'] as $svrent) {
- $split_ip = split("\|", $svrent);
- foreach($ifdescrs as $iface) {
- if($config['interfaces'][$iface]['ipaddr'] <> "")
- if($config['interfaces'][$iface]['ipaddr'] == $split_ip[0])
- $input_errors[] = "{$split_ip[0]} is currently being referenced by an interface ip address on {$iface}.";
+ if(is_array($pconfig['servers'])) {
+ foreach($pconfig['servers'] as $svrent) {
+ $split_ip = split("\|", $svrent);
+ foreach($ifdescrs as $iface) {
+ if($config['interfaces'][$iface]['ipaddr'] <> "")
+ if($config['interfaces'][$iface]['ipaddr'] == $split_ip[0])
+ $input_errors[] = "{$split_ip[0]} is currently being referenced by an interface ip address on {$iface}.";
+ }
}
}
}
@@ -132,7 +134,7 @@ if ($_POST) {
update_if_changed("port", $poolent['port'], $_POST['port']);
update_if_changed("servers", $poolent['servers'], $_POST['servers']);
update_if_changed("monitor", $poolent['monitor'], $_POST['monitor']);
-
+
if (isset($id) && $a_pool[$id]) {
/* modify all virtual servers with this name */
for ($i = 0; isset($config['load_balancer']['virtual_server'][$i]); $i++) {
@@ -142,8 +144,7 @@ if ($_POST) {
$a_pool[$id] = $poolent;
} else
$a_pool[] = $poolent;
-
-
+
if ($changecount > 0) {
/* Mark pool dirty */
conf_mount_rw();
@@ -156,6 +157,116 @@ if ($_POST) {
}
}
+function get_interface_info($ifdescr) {
+
+ global $config, $linkinfo, $netstatrninfo;
+
+ $ifinfo = array();
+
+ /* find out interface name */
+ $ifinfo['hwif'] = $config['interfaces'][$ifdescr]['if'];
+ if ($ifdescr == "wan")
+ $ifinfo['if'] = get_real_wan_interface();
+ else
+ $ifinfo['if'] = $ifinfo['hwif'];
+
+ /* run netstat to determine link info */
+
+ unset($linkinfo);
+ exec("/usr/bin/netstat -I " . $ifinfo['hwif'] . " -nWb -f link", $linkinfo);
+ $linkinfo = preg_split("/\s+/", $linkinfo[1]);
+ if (preg_match("/\*$/", $linkinfo[0])) {
+ $ifinfo['status'] = "down";
+ } else {
+ $ifinfo['status'] = "up";
+ }
+
+ /* PPPoE interface? -> get status from virtual interface */
+ if (($ifdescr == "wan") && ($config['interfaces']['wan']['ipaddr'] == "pppoe")) {
+ unset($linkinfo);
+ exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f link", $linkinfo);
+ $linkinfo = preg_split("/\s+/", $linkinfo[1]);
+ if (preg_match("/\*$/", $linkinfo[0])) {
+ $ifinfo['pppoelink'] = "down";
+ } else {
+ /* get PPPoE link status for dial on demand */
+ $ifconfiginfo = "";
+ unset($ifconfiginfo);
+ exec("/sbin/ifconfig " . $ifinfo['if'], $ifconfiginfo);
+
+ $ifinfo['pppoelink'] = "up";
+
+ foreach ($ifconfiginfo as $ici) {
+ if (strpos($ici, 'LINK0') !== false)
+ $ifinfo['pppoelink'] = "down";
+ }
+ }
+ }
+
+ /* PPTP interface? -> get status from virtual interface */
+ if (($ifdescr == "wan") && ($config['interfaces']['wan']['ipaddr'] == "pptp")) {
+ unset($linkinfo);
+ exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f link", $linkinfo);
+ $linkinfo = preg_split("/\s+/", $linkinfo[1]);
+ if (preg_match("/\*$/", $linkinfo[0])) {
+ $ifinfo['pptplink'] = "down";
+ } else {
+ /* get PPTP link status for dial on demand */
+ unset($ifconfiginfo);
+ exec("/sbin/ifconfig " . $ifinfo['if'], $ifconfiginfo);
+
+ $ifinfo['pptplink'] = "up";
+
+ foreach ($ifconfiginfo as $ici) {
+ if (strpos($ici, 'LINK0') !== false)
+ $ifinfo['pptplink'] = "down";
+ }
+ }
+ }
+
+ if ($ifinfo['status'] == "up") {
+ /* try to determine media with ifconfig */
+ $matches = "";
+
+ if ($ifinfo['pppoelink'] != "down" && $ifinfo['pptplink'] != "down") {
+ /* try to determine IP address and netmask with ifconfig */
+ unset($ifconfiginfo);
+ exec("/sbin/ifconfig " . $ifinfo['if'], $ifconfiginfo);
+
+ foreach ($ifconfiginfo as $ici) {
+ if (preg_match("/inet (\S+)/", $ici, $matches)) {
+ $ifinfo['ipaddr'] = $matches[1];
+ }
+ if (preg_match("/netmask (\S+)/", $ici, $matches)) {
+ if (preg_match("/^0x/", $matches[1]))
+ $ifinfo['subnet'] = long2ip(hexdec($matches[1]));
+ }
+ }
+
+ if ($ifdescr == "wan") {
+ /* run netstat to determine the default gateway */
+ unset($netstatrninfo);
+ exec("/usr/bin/netstat -rnf inet", $netstatrninfo);
+
+ foreach ($netstatrninfo as $nsr) {
+ if (preg_match("/^default\s*(\S+)/", $nsr, $matches)) {
+ $ifinfo['gateway'] = $matches[1];
+ }
+ }
+ } else {
+ /* deterimine interface gateway */
+ $int = convert_friendly_interface_to_real_interface_name($ifdescr);
+ $gw = get_interface_gateway($int);
+ if($gw)
+ $ifinfo['gateway'] = $gw;
+ }
+ }
+ }
+
+ return $ifinfo;
+}
+
+
$pgtitle = "Load Balancer: Pool: Edit";
include("head.inc");
@@ -165,40 +276,78 @@ include("head.inc");
<script type="text/javascript" language="javascript" src="pool.js"></script>
<script language="javascript">
+function gateway_change()
+{
+ if (document.iform.gatewayip.options[document.iform.gatewayip.selectedIndex].value == "other")
+ {
+ //document.iform.monitorip.value = "";
+ document.iform.monitorip.style.display = "block";
+ }
+ else
+ {
+ document.iform.monitorip.value = document.iform.gatewayip.options[document.iform.gatewayip.selectedIndex].value;
+ document.iform.monitorip.style.display = "none";
+ }
+
+}
+
function type_change(enable_change) {
switch (document.iform.type.selectedIndex) {
case 0:
+ // Server;
//clearcombo();
+ document.iform.gatewayip.disabled = 1;
+ document.iform.ipaddr.style.display = "block";
+ document.iform.interface.style.display = "none";
document.iform.serversSelect.clear;
document.iform.monitorip.disabled = 1;
- monitorip_text = document.getElementById("monitorip_text");
+ var monitorIpNote = document.getElementById("monitorIpNote");
+ monitorIpNote.disabled = 1;
+ var monitorip_text = document.getElementById("monitorip_text");
monitorip_text.className = "vncell";
- monitorport_text = document.getElementById("monitorport_text");
+ monitorip_text.disabled = 1;
+ var monitorport_text = document.getElementById("monitorport_text");
monitorport_text.className = "vncellreq";
- monitorport_desc = document.getElementById("monitorport_desc");
- monitorport_desc.innerHTML = "This is the port your servers are listening too.";
+ monitorport_text.disabled = 0;
+ document.getElementById("monitorport_desc").disabled = 0;
document.iform.monitorip.value = "";
document.iform.port.disabled = 0;
document.iform.monitor.selectedIndex = 0;
document.iform.monitor.disabled = 0;
+ var interfacename_text = document.getElementById("interfacename_text");
+ interfacename_text.innerHTML = "Server IP Address";
+ var interfacename_desc = document.getElementById("interfacename_desc");
+ interfacename_desc.innerHTML = "Enter the IP Address of the inbound load balanced server here.";
break;
case 1:
+ // Gateway;
//clearcombo();
+ document.iform.gatewayip.disabled = 0;
+ document.iform.ipaddr.style.display = "none";
+ document.iform.interface.style.display = "block";
document.iform.monitorip.disabled = 0;
document.iform.monitorip.value = "";
- monitorip_text = document.getElementById("monitorip_text");
+ var monitorIpNote = document.getElementById("monitorIpNote");
+ monitorIpNote.disabled = 0;
+ var monitorip_text = document.getElementById("monitorip_text");
monitorip_text.className = "vncellreq";
- monitorport_text = document.getElementById("monitorport_text");
+ monitorip_text.disabled = 0;
+ var monitorport_text = document.getElementById("monitorport_text");
monitorport_text.className = "vncell";
- monitorport_desc = document.getElementById("monitorport_desc");
- monitorport_desc.innerHTML = "";
+ monitorport_text.disabled = 1;
+ document.getElementById("monitorport_desc").disabled = 1;
document.iform.port.disabled = 1;
- /* set to ICMP */
+ // set to ICMP
document.iform.monitor.selectedIndex = 1;
document.iform.monitor.disabled = 1;
+ var interfacename_text = document.getElementById("interfacename_text");
+ interfacename_text.innerHTML = "Interface Name";
+ var interfacename_desc = document.getElementById("interfacename_desc");
+ interfacename_desc.innerHTML = "Select the Interface to be used for outbound load balancing.";
break;
}
}
+
function clearcombo(){
for (var i=document.iform.serversSelect.options.length-1; i>=0; i--){
document.iform.serversSelect.options[i] = null;
@@ -239,7 +388,8 @@ function clearcombo(){
<tr align="left">
<td width="22%" valign="top" id="monitorport_text" class="vncellreq">Port</td>
<td width="78%" class="vtable" colspan="2">
- <input name="port" type="text" <?if(isset($pconfig['port'])) echo "value=\"{$pconfig['port']}\"";?> size="16" maxlength="16"><div id="monitorport_desc"></div>
+ <input name="port" type="text" <?if(isset($pconfig['port'])) echo "value=\"{$pconfig['port']}\"";?> size="16" maxlength="16"><br>
+ <div id="monitorport_desc">This is the port your servers are listening too.</div>
</td>
</tr>
<tr align="left">
@@ -255,14 +405,56 @@ function clearcombo(){
<tr align="left">
<td width="22%" valign="top" id="monitorip_text" class="vncell">Monitor IP</td>
<td width="78%" class="vtable" colspan="2">
- <input size="16" id="monitorip" name="monitorip" value="<?php echo $pconfig['monitorip']; ?>">
+ <div style="float: none;">
+ <select id="gatewayip" name="gatewayip" onchange="gateway_change();" style="float: left;">
+<?php
+ $interfaces = array('wan' => 'WAN');
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ $interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
+ }
+ foreach ($interfaces as $iface => $ifacename) {
+ $ifinfo = get_interface_info($iface);
+ if(isset($ifinfo['gateway'])) { ?>
+ <option value="<?=$ifinfo['gateway'];?>"><?=htmlspecialchars($ifacename);?>'s Gateway</option>
+<?php }
+ }
+ $dns_servers = get_dns_servers();
+ $iDns = 1;
+ foreach($dns_servers as $dns) { ?>
+ <option value="<?=$dns;?>">DNS Server <?=$iDns;?> (<?=$dns;?>)</option>
+<?php $iDns++;
+ }
+ /* Would be really nice to actually ping to get these live each time,
+ as they mostly all support round-robin */?>
+ <option value="72.14.209.99">www.google.com</option>
+ <option value="209.191.93.52">www.yahoo.com</option>
+ <option value="69.147.83.33">www.freebsd.org</option>
+ <option value="other" selected>other</option>
+ </select>
+ <input size="16" id="monitorip" name="monitorip" value="<?php echo $pconfig['monitorip']; ?>" style="float: left;">
+ </div><br><br>
+ <div id="monitorIpNote" style="float: none;">Note: Some gateways have ping capability disabled.</div>
</td>
- </tr>
+ </tr>
<tr align="left">
- <td width="22%" valign="top" class="vncellreq">IP</td>
- <td width="78%" class="vtable">
- <input name="ipaddr" type="text" size="16">
- <input class="formbtn" type="button" name="button1" value="Add to pool" onclick="AddServerToPool(document.iform);">
+ <td width="22%" valign="top" class="vncellreq"><div id="interfacename_text"></div></td>
+ <td width="78%" class="vtable" colspan="2">
+ <input name="ipaddr" type="text" size="16" style="float: left;">
+ <select id="interface" name="interface" style="float: left; display: none;">
+<?php
+ $interfaces = array('wan' => 'WAN', 'lan' => 'LAN');
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ $interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
+ }
+ foreach ($interfaces as $iface => $ifacename) {
+ $ifinfo = get_interface_info($iface);
+ if(isset($ifinfo['gateway'])) { ?>
+ <option value="<?=$iface;?>"><?=htmlspecialchars($ifacename);?></option>
+<?php }
+ } ?>
+ </select>
+ <input class="formbtn" type="button" name="button1" value="Add to pool" onclick="AddServerToPool(document.iform);"><br>
+ <div id="interfacename_desc"></div>
</td>
</tr>
<tr>
@@ -275,12 +467,12 @@ function clearcombo(){
<select id="serversSelect" name="servers[]" multiple="true" size="5">
<?php
- if (is_array($pconfig['servers'])) {
- foreach($pconfig['servers'] as $svrent) {
- echo " <option value=\"{$svrent}\">{$svrent}</option>\n";
- }
- }
- echo "</select>";
+if (is_array($pconfig['servers'])) {
+ foreach($pconfig['servers'] as $svrent) {
+ echo " <option value=\"{$svrent}\">{$svrent}</option>\n";
+ }
+}
+echo "</select>";
?>
</td>
<td valign="top">
@@ -292,7 +484,8 @@ function clearcombo(){
</td>
</tr>
<tr align="left">
- <td colspan="2" align="center" align="left" valign="bottom">
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
<input name="Submit" type="submit" class="formbtn" value="Save" onClick="AllServers('serversSelect', true)">
<?php if (isset($id) && $a_pool[$id]): ?>
<input name="id" type="hidden" value="<?=$id;?>">
@@ -304,6 +497,7 @@ function clearcombo(){
<br>
<script language="javascript">
type_change();
+ gateway_change();
</script>
<?php include("fend.inc"); ?>
</body>
diff --git a/usr/local/www/pool.js b/usr/local/www/pool.js
index e5eb8ee..07cb2aa 100755
--- a/usr/local/www/pool.js
+++ b/usr/local/www/pool.js
@@ -32,10 +32,16 @@
*/
function AddServerToPool(form) {
+ var IntOrIp
var theSel = form['servers[]'];
- for(i=theSel.length-1; i>=0; i--)
+ if (form.type.selectedIndex == 0)
+ IntOrIp = form.ipaddr;
+ else
+ IntOrIp = form.interface;
+
+ for(i = theSel.length - 1; i >= 0; i--)
{
- if(theSel.options[i].value == form.ipaddr.value) {
+ if(theSel.options[i].value == IntOrIp.value) {
alert("IP Address Already In List");
return true;
}
@@ -48,11 +54,11 @@ function AddServerToPool(form) {
}
}
- var ServerPort=form.ipaddr.value;
+ var ServerPort = IntOrIp.value;
if(form.type.selectedIndex == 0)
- var ServerPort=form.ipaddr.value;
+ var ServerPort = IntOrIp.value;
else
- var ServerPort=form.ipaddr.value + "|" + form.monitorip.value;
+ var ServerPort = IntOrIp.value + "|" + form.monitorip.value;
form['servers[]'].options[form['servers[]'].options.length] = new Option(ServerPort,ServerPort);
}
OpenPOWER on IntegriCloud