summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRenato Botelho <renato@netgate.com>2016-02-19 08:28:44 -0200
committerRenato Botelho <renato@netgate.com>2016-02-19 10:57:32 -0200
commit2bf455caa3aaca83287309b6a7629c7d3a328652 (patch)
treed86087d0db6abc692d570e9f2dde7067675b0ffb /src
parent934b8a98b29b01978f6d36d9487423df1b2f7339 (diff)
downloadpfsense-2bf455caa3aaca83287309b6a7629c7d3a328652.zip
pfsense-2bf455caa3aaca83287309b6a7629c7d3a328652.tar.gz
Ticket #3029
Import patch from @Robert-Nelson to enable DHCPv6 Server/RA to interfaces configured to track DHCP-PD This patch only works for PD with length 64
Diffstat (limited to 'src')
-rw-r--r--src/etc/inc/pfsense-utils.inc8
-rw-r--r--src/etc/inc/services.inc46
-rw-r--r--src/etc/inc/system.inc23
-rw-r--r--src/usr/local/www/services_dhcpv6.php37
-rw-r--r--src/usr/local/www/services_dhcpv6_edit.php9
-rw-r--r--src/usr/local/www/services_router_advertisements.php5
6 files changed, 100 insertions, 28 deletions
diff --git a/src/etc/inc/pfsense-utils.inc b/src/etc/inc/pfsense-utils.inc
index 5090a94..67cf1bc 100644
--- a/src/etc/inc/pfsense-utils.inc
+++ b/src/etc/inc/pfsense-utils.inc
@@ -2823,6 +2823,14 @@ function calculate_ipv6_delegation_length($if) {
return($pdlen);
}
+function merge_ipv6_delegated_prefix($prefix, $suffix) {
+ $prefix_array = explode(':', Net_IPv6::uncompress($prefix));
+ $suffix_array = explode(':', Net_IPv6::uncompress($suffix));
+ return Net_IPv6::compress(implode(':',
+ array_merge(array_slice($prefix_array, 0, 4),
+ array_slice($suffix_array, 4))));
+}
+
function huawei_rssi_to_string($rssi) {
$dbm = array();
$i = 0;
diff --git a/src/etc/inc/services.inc b/src/etc/inc/services.inc
index e07601d..4e121e9 100644
--- a/src/etc/inc/services.inc
+++ b/src/etc/inc/services.inc
@@ -1237,13 +1237,17 @@ function services_dhcpdv6_configure($blacklist = array()) {
sleep(1);
}
- /* we add a fake entry for interfaces that are set to track6 another WAN */
+ /*
+ * We add a fake entry for interfaces that are set to track6
+ * another WAN unless DHCP has been configured
+ */
foreach ($Iflist as $ifname) {
/* Do not put in the config an interface which is down */
if (isset($blacklist[$ifname])) {
continue;
}
- if (!empty($config['interfaces'][$ifname]['track6-interface'])) {
+ if (!empty($config['interfaces'][$ifname]['track6-interface']) &&
+ (empty($dhcpdv6cfg[$ifname]) || !isset($dhcpdv6cfg[$ifname]['enable']))) {
$realif = get_real_interface($ifname, "inet6");
$ifcfgipv6 = get_interface_ipv6($ifname);
if (!is_ipaddrv6($ifcfgipv6)) {
@@ -1416,8 +1420,15 @@ EOD;
$dhcpdv6conf .= " {\n";
+ $range_from = $dhcpv6ifconf['range']['from'];
+ $range_to = $dhcpv6ifconf['range']['to'];
+ if ($ifcfgv6['ipaddrv6'] == 'track6') {
+ $range_from = merge_ipv6_delegated_prefix($ifcfgipv6, $range_from);
+ $range_to = merge_ipv6_delegated_prefix($ifcfgipv6, $range_to);
+ }
+
$dhcpdv6conf .= <<<EOD
- range6 {$dhcpv6ifconf['range']['from']} {$dhcpv6ifconf['range']['to']};
+ range6 {$range_from} {$range_to};
$dnscfgv6
EOD;
@@ -1426,7 +1437,12 @@ EOD;
$dhcpdv6conf .= " prefix6 {$dhcpv6ifconf['prefixrange']['from']} {$dhcpv6ifconf['prefixrange']['to']} /{$dhcpv6ifconf['prefixrange']['prefixlength']};\n";
}
if (is_ipaddrv6($dhcpv6ifconf['dns6ip'])) {
- $dhcpdv6conf .= " option dhcp6.name-servers {$dhcpv6ifconf['dns6ip']};\n";
+ $dns6ip = $dhcpv6ifconf['dns6ip'];
+ if ($ifcfgv6['ipaddrv6'] == 'track6' &&
+ Net_IPv6::isInNetmask($dns6ip, '::', 64)) {
+ $dns6ip = merge_ipv6_delegated_prefix($ifcfgipv6, $dns6ip);
+ }
+ $dhcpdv6conf .= " option dhcp6.name-servers {$dns6ip};\n";
}
// default-lease-time
if ($dhcpv6ifconf['defaultleasetime']) {
@@ -1442,9 +1458,14 @@ EOD;
if (is_array($dhcpv6ifconf['ntpserver']) && $dhcpv6ifconf['ntpserver'][0]) {
$ntpservers = array();
foreach ($dhcpv6ifconf['ntpserver'] as $ntpserver) {
- if (is_ipaddrv6($ntpserver)) {
- $ntpservers[] = $ntpserver;
+ if (!is_ipaddrv6($ntpserver)) {
+ continue;
+ }
+ if ($ifcfgv6['ipaddrv6'] == 'track6' &&
+ Net_IPv6::isInNetmask($ntpserver, '::', 64)) {
+ $ntpserver =merge_ipv6_delegated_prefix($ifcfgipv6, $ntpserver);
}
+ $ntpservers[] = $ntpserver;
}
if (count($ntpservers) > 0) {
$dhcpdv6conf .= " option dhcp6.sntp-servers " . join(",", $dhcpv6ifconf['ntpserver']) . ";\n";
@@ -1468,7 +1489,12 @@ EOD;
// ldap-server
if ($dhcpv6ifconf['ldap'] <> "") {
- $dhcpdv6conf .= " option ldap-server \"{$dhcpv6ifconf['ldap']}\";\n";
+ $ldapserver = $dhcpv6ifconf['ldap'];
+ if ($ifcfgv6['ipaddrv6'] == 'track6' &&
+ Net_IPv6::isInNetmask($ldapserver, '::', 64)) {
+ $ldapserver = merge_ipv6_delegated_prefix($ifcfgipv6, $ldapserver);
+ }
+ $dhcpdv6conf .= " option ldap-server \"{$ldapserver}\";\n";
}
// net boot information
@@ -1491,7 +1517,11 @@ host s_{$dhcpv6if}_{$i} {
EOD;
if ($sm['ipaddrv6']) {
- $dhcpdv6conf .= " fixed-address6 {$sm['ipaddrv6']};\n";
+ $ipaddrv6 = $sm['ipaddrv6'];
+ if ($ifcfgv6['ipaddrv6'] == 'track6') {
+ $ipaddrv6 = merge_ipv6_delegated_prefix($ifcfgipv6, $ipaddrv6);
+ }
+ $dhcpdv6conf .= " fixed-address6 {$ipaddrv6};\n";
}
if ($sm['hostname']) {
diff --git a/src/etc/inc/system.inc b/src/etc/inc/system.inc
index 631ab68..2204416 100644
--- a/src/etc/inc/system.inc
+++ b/src/etc/inc/system.inc
@@ -420,13 +420,24 @@ function system_hosts_generate() {
if (isset($dnsmasqcfg['regdhcpstatic']) && is_array($config['dhcpdv6'])) {
foreach ($config['dhcpdv6'] as $dhcpif => $dhcpifconf) {
if (is_array($dhcpifconf['staticmap']) && isset($dhcpifconf['enable'])) {
+ $isdelegated = $config['interfaces'][$dhcpif]['ipaddrv6'] == 'track6';
+ if ($isdelegated) {
+ $prefix = array_slice(explode(':', Net_IPv6::uncompress(get_interface_ipv6($dhcpif))), 0, 4);
+ }
foreach ($dhcpifconf['staticmap'] as $host) {
- if ($host['ipaddrv6'] && $host['hostname'] && $host['domain']) {
- $dhosts .= "{$host['ipaddrv6']} {$host['hostname']}.{$host['domain']} {$host['hostname']}\n";
- } else if ($host['ipaddrv6'] && $host['hostname'] && $dhcpifconf['domain']) {
- $dhosts .= "{$host['ipaddrv6']} {$host['hostname']}.{$dhcpifconf['domain']} {$host['hostname']}\n";
- } else if ($host['ipaddrv6'] && $host['hostname']) {
- $dhosts .= "{$host['ipaddrv6']} {$host['hostname']}.{$syscfg['domain']} {$host['hostname']}\n";
+ $ipaddrv6 = $host['ipaddrv6'];
+ if ($ipaddrv6 && $host['hostname']) {
+ if ($isdelegated) {
+ $suffix = array_slice(explode(':', Net_IPv6::uncompress($ipaddrv6)), 4);
+ $ipaddrv6 = Net_IPv6::compress(implode(':', array_merge($prefix, $suffix)));
+ }
+ if ($host['domain']) {
+ $dhosts .= "{$ipaddrv6} {$host['hostname']}.{$host['domain']} {$host['hostname']}\n";
+ } else if ($dhcpifconf['domain']) {
+ $dhosts .= "{$ipaddrv6} {$host['hostname']}.{$dhcpifconf['domain']} {$host['hostname']}\n";
+ } else {
+ $dhosts .= "{$ipaddrv6} {$host['hostname']}.{$syscfg['domain']} {$host['hostname']}\n";
+ }
}
}
}
diff --git a/src/usr/local/www/services_dhcpv6.php b/src/usr/local/www/services_dhcpv6.php
index 5513b3d..ea80ac4 100644
--- a/src/usr/local/www/services_dhcpv6.php
+++ b/src/usr/local/www/services_dhcpv6.php
@@ -99,8 +99,9 @@ $iflist = array_merge($iflist, get_configured_pppoe_server_interfaces());
if (!$if || !isset($iflist[$if])) {
foreach ($iflist as $ifent => $ifname) {
$oc = $config['interfaces'][$ifent];
- $valid_if_ipaddrv6 = (bool) (is_ipaddrv6($oc['ipaddrv6']) &&
- !is_linklocal($oc['ipaddrv6']));
+ $valid_if_ipaddrv6 = (bool) ($oc['ipaddrv6'] == 'track6' ||
+ (is_ipaddrv6($oc['ipaddrv6']) &&
+ !is_linklocal($oc['ipaddrv6'])));
if ((!is_array($config['dhcpdv6'][$ifent]) ||
!isset($config['dhcpdv6'][$ifent]['enable'])) &&
@@ -151,8 +152,13 @@ if (is_array($config['dhcpdv6'][$if])) {
$a_maps = &$config['dhcpdv6'][$if]['staticmap'];
}
-$ifcfgip = get_interface_ipv6($if);
-$ifcfgsn = get_interface_subnetv6($if);
+if ($config['interfaces'][$if]['ipaddrv6'] == 'track6') {
+ $ifcfgip = '::';
+ $ifcfgsn = 64;
+} else {
+ $ifcfgip = get_interface_ipv6($if);
+ $ifcfgsn = get_interface_subnetv6($if);
+}
/* set the enabled flag which will tell us if DHCP relay is enabled
* on any interface. We will use this to disable DHCP server since
@@ -234,11 +240,21 @@ if ($_POST) {
}
}
- if (($_POST['range_from'] && !is_ipaddrv6($_POST['range_from']))) {
- $input_errors[] = gettext("A valid range must be specified.");
+ if ($_POST['range_from']) {
+ if (!is_ipaddrv6($_POST['range_from'])) {
+ $input_errors[] = gettext("A valid range must be specified.");
+ } elseif ($config['interfaces'][$if]['ipaddrv6'] == 'track6' &&
+ !Net_IPv6::isInNetmask($_POST['range_from'], '::', 64)) {
+ $input_errors[] = gettext("The prefix (upper 64 bits) must be zero. Use the form ::x:x:x:x");
+ }
}
- if (($_POST['range_to'] && !is_ipaddrv6($_POST['range_to']))) {
- $input_errors[] = gettext("A valid range must be specified.");
+ if ($_POST['range_to']) {
+ if (!is_ipaddrv6($_POST['range_to'])) {
+ $input_errors[] = gettext("A valid range must be specified.");
+ } elseif ($config['interfaces'][$if]['ipaddrv6'] == 'track6' &&
+ !Net_IPv6::isInNetmask($_POST['range_to'], '::', 64)) {
+ $input_errors[] = gettext("The prefix (upper 64 bits) must be zero. Use the form ::x:x:x:x");
+ }
}
if (($_POST['gateway'] && !is_ipaddrv6($_POST['gateway']))) {
$input_errors[] = gettext("A valid IPv6 address must be specified for the gateway.");
@@ -507,8 +523,9 @@ $i = 0;
foreach ($iflist as $ifent => $ifname) {
$oc = $config['interfaces'][$ifent];
- $valid_if_ipaddrv6 = (bool) (is_ipaddrv6($oc['ipaddrv6']) &&
- !is_linklocal($oc['ipaddrv6']));
+ $valid_if_ipaddrv6 = (bool) ($oc['ipaddrv6'] == 'track6' ||
+ (is_ipaddrv6($oc['ipaddrv6']) &&
+ !is_linklocal($oc['ipaddrv6'])));
if ((!is_array($config['dhcpdv6'][$ifent]) ||
!isset($config['dhcpdv6'][$ifent]['enable'])) &&
diff --git a/src/usr/local/www/services_dhcpv6_edit.php b/src/usr/local/www/services_dhcpv6_edit.php
index f8c26da..b26ba9d 100644
--- a/src/usr/local/www/services_dhcpv6_edit.php
+++ b/src/usr/local/www/services_dhcpv6_edit.php
@@ -155,8 +155,13 @@ if ($_POST) {
}
}
}
- if (($_POST['ipaddrv6'] && !is_ipaddrv6($_POST['ipaddrv6']))) {
- $input_errors[] = gettext("A valid IPv6 address must be specified.");
+ if ($_POST['ipaddrv6']) {
+ if (!is_ipaddrv6($_POST['ipaddrv6'])) {
+ $input_errors[] = gettext("A valid IPv6 address must be specified.");
+ } elseif ($config['interfaces'][$if]['ipaddrv6'] == 'track6' &&
+ !Net_IPv6::isInNetmask($_POST['ipaddrv6'], '::', 64)) {
+ $input_errors[] = gettext("The prefix (upper 64 bits) must be zero. Use the form ::x:x:x:x");
+ }
}
if (empty($_POST['duid'])) {
diff --git a/src/usr/local/www/services_router_advertisements.php b/src/usr/local/www/services_router_advertisements.php
index 3a4746d..9ef58e1 100644
--- a/src/usr/local/www/services_router_advertisements.php
+++ b/src/usr/local/www/services_router_advertisements.php
@@ -102,8 +102,9 @@ $iflist = get_configured_interface_with_descr();
if (!$if || !isset($iflist[$if])) {
foreach ($iflist as $ifent => $ifname) {
$oc = $config['interfaces'][$ifent];
- $valid_if_ipaddrv6 = (bool) (is_ipaddrv6($oc['ipaddrv6']) &&
- !is_linklocal($oc['ipaddrv6']));
+ $valid_if_ipaddrv6 = (bool) ($oc['ipaddrv6'] == 'track6' ||
+ (is_ipaddrv6($oc['ipaddrv6']) &&
+ !is_linklocal($oc['ipaddrv6'])));
if ((!is_array($config['dhcpdv6'][$ifent]) ||
!isset($config['dhcpdv6'][$ifent]['enable'])) &&
OpenPOWER on IntegriCloud