mirror of
https://github.com/pfsense/pfsense.git
synced 2025-10-26 11:38:35 +00:00
load balancer: allow IPv4 subnets up to 64 addresses in Pools and Virtual Servers (PEV-394754)
This commit is contained in:
parent
9859b2b553
commit
0917cb214b
@ -1048,6 +1048,43 @@ function alias_expand_urltable($name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function subnet_size ($subnet) {
|
||||
if (is_subnetv4($subnet)) {
|
||||
list ($ip, $bits) = explode("/", $subnet);
|
||||
return round(exp(log(2) * (32 - $bits)));
|
||||
}
|
||||
else if (is_subnetv6($subnet)) {
|
||||
list ($ip, $bits) = explode("/", $subnet);
|
||||
return round(exp(log(2) * (128 - $bits)));
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
function subnet_expand ($subnet) {
|
||||
if (is_subnetv4($subnet)) {
|
||||
return subnetv4_expand($subnet);
|
||||
} else if (is_subnetv6($subnet)) {
|
||||
return subnetv6_expand($subnet);
|
||||
} else {
|
||||
return $subnet;
|
||||
}
|
||||
}
|
||||
|
||||
function subnetv4_expand ($subnet) {
|
||||
$result = array();
|
||||
list ($ip, $bits) = explode("/", $subnet);
|
||||
$net = ip2long($ip);
|
||||
$mask = (0xffffffff << (32 - $bits));
|
||||
$net &= $mask;
|
||||
$size = round(exp(log(2) * (32 - $bits)));
|
||||
for ($i = 0; $i < $size; $i += 1) {
|
||||
$result[] = long2ip($net | $i);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/* find out whether two subnets overlap */
|
||||
function check_subnets_overlap($subnet1, $bits1, $subnet2, $bits2) {
|
||||
|
||||
|
||||
@ -217,11 +217,21 @@ function relayd_configure($kill_first=false) {
|
||||
if(is_array($pool_a[$i]['servers'])) {
|
||||
if (!empty($pool_a[$i]['retry'])) {
|
||||
$retrytext = " retry {$pool_a[$i]['retry']}";
|
||||
$srvtxt = implode("{$retrytext}, ", $pool_a[$i]['servers']) . "{$retrytext}";
|
||||
} else {
|
||||
$srvtxt = implode(", ", $pool_a[$i]['servers']);
|
||||
$retrytext = "";
|
||||
}
|
||||
$conf .= "table <{$pool_a[$i]['name']}> { $srvtxt }\n";
|
||||
$conf .= "table <{$pool_a[$i]['name']}> {\n";
|
||||
foreach ($pool_a[$i]['servers'] as $server) {
|
||||
if (is_subnetv4($server)) {
|
||||
foreach (subnetv4_expand($server) as $ip) {
|
||||
$conf .= "\t{$ip}{$retrytext}\n";
|
||||
}
|
||||
}
|
||||
else {
|
||||
$conf .= "\t{$server}{$retrytext}\n";
|
||||
}
|
||||
}
|
||||
$conf .= "}\n";
|
||||
/* Index by name for easier fetching when we loop through the virtual servers */
|
||||
$pools[$pool_a[$i]['name']] = $pool_a[$i];
|
||||
}
|
||||
@ -244,43 +254,55 @@ function relayd_configure($kill_first=false) {
|
||||
// }
|
||||
|
||||
$conf .= "dns protocol \"dnsproto\" {\n";
|
||||
$conf .= "\ttcp { nodelay, sack, socket buffer 1024, backlog 1000 }\n";
|
||||
$conf .= "\t" . "tcp { nodelay, sack, socket buffer 1024, backlog 1000 }\n";
|
||||
$conf .= "}\n";
|
||||
|
||||
if(is_array($vs_a)) {
|
||||
for ($i = 0; isset($vs_a[$i]); $i++) {
|
||||
if (($vs_a[$i]['mode'] == 'relay') || ($vs_a[$i]['relay_protocol'] == 'dns')) {
|
||||
$conf .= "relay \"{$vs_a[$i]['name']}\" {\n";
|
||||
$conf .= " listen on {$vs_a[$i]['ipaddr']} port {$vs_a[$i]['port']}\n";
|
||||
if (is_subnetv4($vs_a[$i]['ipaddr'])) {
|
||||
$ip_list = subnetv4_expand($vs_a[$i]['ipaddr']);
|
||||
$name_format = "%s_%d";
|
||||
}
|
||||
else {
|
||||
$ip_list = array($vs_a[$i]['ipaddr']);
|
||||
$name_format = "%s"; /* in which case the second arg of the sprintf call below will be silently ignored */
|
||||
}
|
||||
for ($j = 0; $j < count($ip_list); $j += 1) {
|
||||
$ip = $ip_list[$j];
|
||||
$name = sprintf($name_format, $vs_a[$i]['name'], $j);
|
||||
if (($vs_a[$i]['mode'] == 'relay') || ($vs_a[$i]['relay_protocol'] == 'dns')) {
|
||||
$conf .= "relay \"{$name}\" {\n";
|
||||
$conf .= " listen on {$ip} port {$vs_a[$i]['port']}\n";
|
||||
|
||||
if ($vs_a[$i]['relay_protocol'] == "dns") {
|
||||
$conf .= " protocol \"dnsproto\"\n";
|
||||
} else {
|
||||
$conf .= " protocol \"{$vs_a[$i]['relay_protocol']}\"\n";
|
||||
if ($vs_a[$i]['relay_protocol'] == "dns") {
|
||||
$conf .= " protocol \"dnsproto\"\n";
|
||||
} else {
|
||||
$conf .= " protocol \"{$vs_a[$i]['relay_protocol']}\"\n";
|
||||
}
|
||||
$lbmode = "";
|
||||
if ( $pools[$vs_a[$i]['pool']]['mode'] == "loadbalance" ) {
|
||||
$lbmode = "mode loadbalance";
|
||||
}
|
||||
|
||||
$conf .= " forward to <{$vs_a[$i]['pool']}> port {$pools[$vs_a[$i]['pool']]['port']} {$lbmode} {$check_a[$pools[$vs_a[$i]['pool']]['monitor']]} \n";
|
||||
|
||||
if (isset($vs_a[$i]['sitedown']) && strlen($vs_a[$i]['sitedown']) > 0)
|
||||
$conf .= " forward to <{$vs_a[$i]['sitedown']}> port {$pools[$vs_a[$i]['pool']]['port']} {$lbmode} {$check_a[$pools[$vs_a[$i]['pool']]['monitor']]} \n";
|
||||
$conf .= "}\n";
|
||||
} else {
|
||||
$conf .= "redirect \"{$name}\" {\n";
|
||||
$conf .= " listen on {$ip} port {$vs_a[$i]['port']}\n";
|
||||
$conf .= " forward to <{$vs_a[$i]['pool']}> port {$pools[$vs_a[$i]['pool']]['port']} {$check_a[$pools[$vs_a[$i]['pool']]['monitor']]} \n";
|
||||
|
||||
if (isset($config['system']['lb_use_sticky']))
|
||||
$conf .= " sticky-address\n";
|
||||
|
||||
/* sitedown MUST use the same port as the primary pool - sucks, but it's a relayd thing */
|
||||
if (isset($vs_a[$i]['sitedown']) && strlen($vs_a[$i]['sitedown']) > 0)
|
||||
$conf .= " forward to <{$vs_a[$i]['sitedown']}> port {$pools[$vs_a[$i]['pool']]['port']} {$check_a[$pools[$vs_a[$i]['pool']]['monitor']]} \n";
|
||||
|
||||
$conf .= "}\n";
|
||||
}
|
||||
$lbmode = "";
|
||||
if ( $pools[$vs_a[$i]['pool']]['mode'] == "loadbalance" ) {
|
||||
$lbmode = "mode loadbalance";
|
||||
}
|
||||
|
||||
$conf .= " forward to <{$vs_a[$i]['pool']}> port {$pools[$vs_a[$i]['pool']]['port']} {$lbmode} {$check_a[$pools[$vs_a[$i]['pool']]['monitor']]} \n";
|
||||
|
||||
if (isset($vs_a[$i]['sitedown']) && strlen($vs_a[$i]['sitedown']) > 0)
|
||||
$conf .= " forward to <{$vs_a[$i]['sitedown']}> port {$pools[$vs_a[$i]['pool']]['port']} {$lbmode} {$check_a[$pools[$vs_a[$i]['pool']]['monitor']]} \n";
|
||||
$conf .= "}\n";
|
||||
} else {
|
||||
$conf .= "redirect \"{$vs_a[$i]['name']}\" {\n";
|
||||
$conf .= " listen on {$vs_a[$i]['ipaddr']} port {$vs_a[$i]['port']}\n";
|
||||
$conf .= " forward to <{$vs_a[$i]['pool']}> port {$pools[$vs_a[$i]['pool']]['port']} {$check_a[$pools[$vs_a[$i]['pool']]['monitor']]} \n";
|
||||
|
||||
if (isset($config['system']['lb_use_sticky']))
|
||||
$conf .= " sticky-address\n";
|
||||
|
||||
/* sitedown MUST use the same port as the primary pool - sucks, but it's a relayd thing */
|
||||
if (isset($vs_a[$i]['sitedown']) && strlen($vs_a[$i]['sitedown']) > 0)
|
||||
$conf .= " forward to <{$vs_a[$i]['sitedown']}> port {$pools[$vs_a[$i]['pool']]['port']} {$check_a[$pools[$vs_a[$i]['pool']]['monitor']]} \n";
|
||||
|
||||
$conf .= "}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,15 +94,21 @@ if ($_POST) {
|
||||
|
||||
if (is_array($_POST['servers'])) {
|
||||
foreach($pconfig['servers'] as $svrent) {
|
||||
if (!is_ipaddr($svrent)) {
|
||||
$input_errors[] = sprintf(gettext("%s is not a valid IP address (in \"enabled\" list)."), $svrent);
|
||||
if (!is_ipaddr($svrent) && !is_subnetv4($svrent)) {
|
||||
$input_errors[] = sprintf(gettext("%s is not a valid IP address or IPv4 subnet (in \"enabled\" list)."), $svrent);
|
||||
}
|
||||
else if (is_subnetv4($svrent) && subnet_size($svrent) > 64) {
|
||||
$input_errors[] = sprintf(gettext("%s is a subnet containing more than 64 IP addresses (in \"enabled\" list)."), $svrent);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (is_array($_POST['serversdisabled'])) {
|
||||
foreach($pconfig['serversdisabled'] as $svrent) {
|
||||
if (!is_ipaddr($svrent)) {
|
||||
$input_errors[] = sprintf(gettext("%s is not a valid IP address (in \"disabled\" list)."), $svrent);
|
||||
if (!is_ipaddr($svrent) && !is_subnetv4($svrent)) {
|
||||
$input_errors[] = sprintf(gettext("%s is not a valid IP address or IPv4 subnet (in \"disabled\" list)."), $svrent);
|
||||
}
|
||||
else if (is_subnetv4($svrent) && subnet_size($svrent) > 64) {
|
||||
$input_errors[] = sprintf(gettext("%s is a subnet containing more than 64 IP addresses (in \"disabled\" list)."), $svrent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,8 +91,10 @@ if ($_POST) {
|
||||
if (!is_port($_POST['port']))
|
||||
$input_errors[] = gettext("The port must be an integer between 1 and 65535.");
|
||||
|
||||
if(!is_ipaddr($_POST['ipaddr']))
|
||||
$input_errors[] = sprintf(gettext("%s is not a valid IP address."), $_POST['ipaddr']);
|
||||
if (!is_ipaddr($_POST['ipaddr']) && !is_subnetv4($_POST['ipaddr']))
|
||||
$input_errors[] = sprintf(gettext("%s is not a valid IP address or IPv4 subnet."), $_POST['ipaddr']);
|
||||
else if (is_subnetv4($_POST['ipaddr']) && subnet_size($_POST['ipaddr']) > 64)
|
||||
$input_errors[] = sprintf(gettext("%s is a subnet containing more than 64 IP addresses."), $_POST['ipaddr']);
|
||||
|
||||
if (!$input_errors) {
|
||||
$vsent = array();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user