summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSeth Mos <seth.mos@dds.nl>2011-05-06 12:09:57 +0000
committerSeth Mos <seth.mos@dds.nl>2011-05-06 12:09:57 +0000
commited3956405edee6a8cde1dca85b92d7b5154573ff (patch)
treef5f5b439d9115b4095729647a24f812b2658cce5
parent93a138ab04c551d5bcad07392fe4378a6924a23c (diff)
downloadpfsense-ed3956405edee6a8cde1dca85b92d7b5154573ff.zip
pfsense-ed3956405edee6a8cde1dca85b92d7b5154573ff.tar.gz
Add DHCP-PD support if the WAN interface is set to DHCP.
Select a DHCP-PD prefix length in correspondence with your ISP. If set to "none" it will not be requested and normal DHCPv6 is performed. You can set a link local IPv6 address on the LAN interface and select a DHCP-PD Prefix number from the drop down. When the dhcp-pd request is succesful, a global IPv6 address from the prefix pool with the corresponding prefix number will be configured on that interface. We then start a rtadvd daemon for this interface.
-rw-r--r--etc/inc/interfaces.inc128
-rw-r--r--etc/inc/services.inc34
-rwxr-xr-xusr/local/www/interfaces.php91
3 files changed, 154 insertions, 99 deletions
diff --git a/etc/inc/interfaces.inc b/etc/inc/interfaces.inc
index 822ff2e..f961d23 100644
--- a/etc/inc/interfaces.inc
+++ b/etc/inc/interfaces.inc
@@ -2544,7 +2544,7 @@ function find_dhclient_process($interface) {
function find_dhcp6c_process($interface) {
if ($interface)
- $pid = `/bin/pgrep -axf "[d]hcp6c"|grep -e "{$interface}"`;
+ $pid = `/bin/pgrep -axf "dhcp6c" |grep "{$interface}"`;
else
$pid = 0;
@@ -2801,6 +2801,85 @@ function interface_dhcp_configure($interface = "wan") {
global $config, $g;
$wancfg = $config['interfaces'][$interface];
+ $wanif = $wancfg['if'];
+ if (empty($wancfg))
+ $wancfg = array();
+
+ $wanif = get_real_interface($interface);
+ /* bring wan interface up before starting dhclient */
+ if($wanif)
+ interfaces_bring_up($wanif);
+ else
+ log_error("Could not bring up {$wanif} interface in interface_dhcp_configure()");
+
+ /* launch v6 before v4, dhclient can hold up the execution if no dhcp4 is available */
+ interface_dhcpv6_configure($interface);
+ interface_dhcpv4_configure($interface);
+
+ return 0;
+
+}
+
+function interface_dhcpv6_configure($interface = "wan") {
+ global $config, $g;
+ $iflist = get_configured_interface_with_descr(false, true);
+
+ $wancfg = $config['interfaces'][$interface];
+ $wanif = $wancfg['if'];
+ if (empty($wancfg))
+ $wancfg = array();
+
+ $wanif = get_real_interface($interface);
+
+ /* Add IPv6 dhclient here, only wide-dhcp6c works for now. */
+ $fd = fopen("{$g['varetc_path']}/dhcp6c_{$interface}.conf", "w");
+ if (!$fd) {
+ printf("Error: cannot open dhcp6c_{$interface}.conf in interfaces_wan_dhcp_configure() for writing.\n");
+ return 1;
+ }
+
+ $dhcp6cconf = "";
+ $dhcp6cconf .= "interface {$wanif} {\n";
+ $dhcp6cconf .= " send ia-na 0; # request stateful address\n";
+ if(is_numeric($wancfg['dhcp6-ia-pd-len'])) {
+ $dhcp6cconf .= " send ia-pd 0; # request prefix delegation\n";
+ }
+ $dhcp6cconf .= "request domain-name-servers;\n";
+ $dhcp6cconf .= "request domain-name;\n";
+ $dhcp6cconf .= "script \"/etc/rc.newwanipv6\"; # we'd like some nameservers please\n";
+
+ $dhcp6cconf .= "};\n";
+ $dhcp6cconf .= "id-assoc na 0 { };\n";
+ if(is_numeric($wancfg['dhcp6-ia-pd-len'])) {
+ /* Setup the prefix delegation */
+ $dhcp6cconf .= " id-assoc pd 0 {\n";
+ foreach($iflist as $friendly => $pdinterface) {
+ // log_error("setting up $friendly - $pdinterface - {$pdinterface['dhcp6-pd-sla-id']}");
+ if(is_numeric($config['interfaces'][$friendly]['dhcp6-pd-sla-id'])) {
+ $realif = get_real_interface($friendly);
+ $dhcp6cconf .= " prefix-interface {$realif} {\n";
+ $dhcp6cconf .= " sla-id {$config['interfaces'][$friendly]['dhcp6-pd-sla-id']};\n";
+ $dhcp6cconf .= " sla-len {$wancfg['dhcp6-ia-pd-len']};\n";
+ $dhcp6cconf .= " };\n";
+ }
+ }
+ $dhcp6cconf .= "};\n";
+ }
+
+ fwrite($fd, $dhcp6cconf);
+ fclose($fd);
+
+ /* fire up dhcp6c for IPv6 first, this backgrounds immediately */
+ mwexec("/usr/local/sbin/dhcp6c -c {$g['varetc_path']}/dhcp6c_{$interface}.conf {$wanif}");
+
+ return 0;
+}
+
+function interface_dhcpv4_configure($interface = "wan") {
+ global $config, $g;
+
+ $wancfg = $config['interfaces'][$interface];
+ $wanif = $wancfg['if'];
if (empty($wancfg))
$wancfg = array();
@@ -2851,53 +2930,6 @@ EOD;
fwrite($fd, $dhclientconf);
fclose($fd);
- /* Add IPv6 dhclient here, only wide-dhcp6c works for now. */
- $fd = fopen("{$g['varetc_path']}/dhcp6c_{$interface}.conf", "w");
- if (!$fd) {
- printf("Error: cannot open dhcp6c_{$interface}.conf in interfaces_wan_dhcp_configure() for writing.\n");
- return 1;
- }
-
- $dhcp6cconf = "";
-
- $dhcp6cconf .= <<<EOD
-interface {$wanif} {
- send ia-na 0; # request stateful address
- send ia-pd 0; # request prefix delegation
- request domain-name-servers;
- request domain-name;
- script "/etc/rc.newwanipv6"; # we'd like some nameservers please
-
-};
-id-assoc na 0 { };
-id-assoc pd 0 {
-
-EOD;
-
- /* Setup the prefix delegation */
- foreach($IfList as $pdinterface => $friendly) {
- if(is_numeric($interface['ia-pd'])) {
- $realif = get_real_interface($friendly);
- $dhcp6cconf .= " prefix-interface {$realif} {\n";
- $dhcp6cconf .= " sla-id {$interface['ia-pd']};\n";
- $dhcp6cconf .= " sla-len {$config['interface'][$interface]['dhcp-ia-pd-len']};\n";
- $dhcp6cconf .= " };\n";
- }
- }
-
- $dhcp6cconf .= "};\n";
-
- fwrite($fd, $dhcp6cconf);
- fclose($fd);
-
- /* bring wan interface up before starting dhclient */
- if($wanif)
- interfaces_bring_up($wanif);
- else
- log_error("Could not bring up {$wanif} interface in interface_dhcp_configure()");
-
- /* fire up dhcp6c for IPv6 first, this backgrounds immediately */
- mwexec("/usr/local/sbin/dhcp6c -c {$g['varetc_path']}/dhcp6c_{$interface}.conf {$wanif}");
/* fire up dhclient */
mwexec("/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$interface}.conf {$wanif} > {$g['tmp_path']}/{$wanif}_output > {$g['tmp_path']}/{$wanif}_error_output");
diff --git a/etc/inc/services.inc b/etc/inc/services.inc
index e95630d..20b2c75 100644
--- a/etc/inc/services.inc
+++ b/etc/inc/services.inc
@@ -82,22 +82,13 @@ ether:\
EOD;
/* Process all links which need the router advertise daemon */
- /* Currently for DHCP interfaces only, openvpn? */
$rtadvdnum = 0;
foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
if($dhcpv6ifconf['mode'] == "disabled")
continue;
$rtadvdnum++;
-
- /* It appears we can not advertise the gateway IP (carp)
- * rtadvd[44205]: <sock_open> IPV6_JOIN_GROUP(link) on vip1: Can't assign requested address
- if($dhcpv6ifconf['gateway'] <> "") {
- $dhcpv6if = find_carp_interface($dhcpv6ifconf['gateway']);
- }
- */
$realif = get_real_interface($dhcpv6if);
-
$rtadvdifs[] = $realif;
$ifcfgipv6 = get_interface_ipv6($dhcpv6if);
@@ -122,6 +113,27 @@ EOD;
}
$rtadvdconf .= "\t:tc=ether:\n";
$rtadvdconf .= "\n\n";
+ }
+
+ foreach ($Iflist as $if => $ifdescr) {
+ if(!is_numeric($config['interfaces'][$if]['dhcp6-pd-sla-id']))
+ continue;
+
+ $rtadvdnum++;
+ $realif = get_real_interface($if);
+ $rtadvdifs[] = $realif;
+
+ $ifcfgipv6 = get_interface_ipv6($if);
+ $ifcfgsnv6 = get_interface_subnetv6($if);
+ $subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
+ $subnetmaskv6 = gen_subnet_mask($ifcfgsnv6);
+
+ $rtadvdconf .= "{$realif}:\\\n";
+ $rtadvdconf .= "\t:addr=\"{$subnetv6}\":\\\n";
+ $rtadvdconf .= "\t:prefixlen#{$ifcfgsnv6}:\\\n";
+ $rtadvdconf .= "\t:raflags=\"mo\":\\\n";
+ $rtadvdconf .= "\t:tc=ether:\n";
+ $rtadvdconf .= "\n\n";
}
@@ -177,7 +189,7 @@ function services_dhcpdv4_configure() {
/* kill any running dhcpd */
if(is_process_running("dhcpd")) {
- killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpd.pid/dhcpd.pid");
+ killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpd.pid");
}
/* DHCP enabled on any interfaces? */
@@ -516,7 +528,7 @@ function services_dhcpdv6_configure() {
/* kill any running dhcpd */
if(is_process_running("dhcpd")) {
- killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpdv6.pid");
+ killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/'dhcpdv6.pid");
}
/* DHCP enabled on any interfaces? */
diff --git a/usr/local/www/interfaces.php b/usr/local/www/interfaces.php
index 1fa390f..6d689d1 100755
--- a/usr/local/www/interfaces.php
+++ b/usr/local/www/interfaces.php
@@ -190,9 +190,17 @@ if (is_array($config['aliases']['alias'])) {
switch($wancfg['ipaddr']) {
case "dhcp":
+ $pconfig['dhcp6-duid'] = $wancfg['dhcp6-duid'];
+ if($wancfg['dhcp6-ia-pd-len'] == "")
+ $wancfg['dhcp6-ia-pd-len'] = "none";
+ $pconfig['dhcp6-ia-pd-len'] = $wancfg['dhcp6-ia-pd-len'];
$pconfig['type'] = "dhcp";
break;
case "carpdev-dhcp":
+ $pconfig['dhcp6-duid'] = $wancfg['dhcp6-duid'];
+ if($wancfg['dhcp6-ia-pd-len'] == "")
+ $wancfg['dhcp6-ia-pd-len'] = "none";
+ $pconfig['dhcp6-ia-pd-len'] = $wancfg['dhcp6-ia-pd-len'];
$pconfig['type'] = "carpdev-dhcp";
$pconfig['ipaddr'] = "";
break;
@@ -224,6 +232,7 @@ switch($wancfg['ipaddrv6']) {
$pconfig['ipaddrv6'] = $wancfg['ipaddrv6'];
$pconfig['subnetv6'] = $wancfg['subnetv6'];
$pconfig['gatewayv6'] = $wancfg['gatewayv6'];
+ $pconfig['dhcp6-pd-sla-id'] = $wancfg['dhcp6-pd-sla-id'];
if((is_ipaddrv6($wancfg['ipaddrv6'])) && (is_ipaddr($wancfg['ipaddr']))) {
$pconfig['type'] = "staticv4v6";
}
@@ -417,7 +426,7 @@ if ($_POST['apply']) {
do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
break;
case "staticv6":
- $reqdfields = explode(" ", "ipaddrv6 subnetv6 gatewayv6");
+ $reqdfields = explode(" ", "ipaddrv6 subnetv6 gatewayv6 dhcp6-pd-sla-id");
$reqdfieldsn = array(gettext("IPv6 address"),gettext("Subnet bit count"),gettext("Gateway"));
do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
break;
@@ -429,7 +438,7 @@ if ($_POST['apply']) {
$_POST['ipaddrv6'] = trim($output[0]);
$_POST['subnetv6'] = "64";
}
- $reqdfields = explode(" ", "ipaddr subnet gateway ipaddrv6 subnetv6 gatewayv6");
+ $reqdfields = explode(" ", "ipaddr subnet gateway ipaddrv6 subnetv6 gatewayv6 dhcp6-pd-sla-id");
$reqdfieldsn = array(gettext("IPv4 address"),gettext("Subnet bit count"),gettext("Gateway"),gettext("IPv6 address"),gettext("Subnet bit count"),gettext("Gateway"));
do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
break;
@@ -609,6 +618,9 @@ if ($_POST['apply']) {
unset($wancfg['subnetv6']);
unset($wancfg['gatewayv6']);
unset($wancfg['dhcphostname']);
+ unset($wancfg['dhcp6-pd-sla-id']);
+ unset($wancfg['dhcp6-duid']);
+ unset($wancfg['dhcp6-ia-pd-len']);
unset($wancfg['pppoe_username']);
unset($wancfg['pppoe_password']);
unset($wancfg['pptp_username']);
@@ -664,6 +676,7 @@ if ($_POST['apply']) {
case "staticv6":
$wancfg['ipaddrv6'] = $_POST['ipaddrv6'];
$wancfg['subnetv6'] = $_POST['subnetv6'];
+ $wancfg['dhcp6-pd-sla-id'] = $_POST['dhcp6-pd-sla-id'];
if ($_POST['gatewayv6'] != "none") {
$wancfg['gatewayv6'] = $_POST['gatewayv6'];
}
@@ -676,6 +689,7 @@ if ($_POST['apply']) {
}
$wancfg['ipaddrv6'] = $_POST['ipaddrv6'];
$wancfg['subnetv6'] = $_POST['subnetv6'];
+ $wancfg['dhcp6-pd-sla-id'] = $_POST['dhcp6-pd-sla-id'];
if ($_POST['gatewayv6'] != "none") {
$wancfg['gatewayv6'] = $_POST['gatewayv6'];
}
@@ -685,9 +699,8 @@ if ($_POST['apply']) {
$wancfg['dhcphostname'] = $_POST['dhcphostname'];
$wancfg['alias-address'] = $_POST['alias-address'];
$wancfg['alias-subnet'] = $_POST['alias-subnet'];
- $wancfg['duid'] = $_POST['duid'];
- $wancfg['dhcp-ia-pd-len'] = $_POST['dhcp-ia-pd-len'];
- unset($wancfg['pd-sla-id']);
+ $wancfg['dhcp6-duid'] = $_POST['dhcp6-duid'];
+ $wancfg['dhcp6-ia-pd-len'] = $_POST['dhcp6-ia-pd-len'];
$wancfg['dhcp_plus'] = $_POST['dhcp_plus'] == "yes" ? true : false;
if($gateway_item) {
$a_gateways[] = $gateway_item;
@@ -698,9 +711,8 @@ if ($_POST['apply']) {
$wancfg['dhcphostname'] = $_POST['dhcphostname'];
$wancfg['alias-address'] = $_POST['alias-address'];
$wancfg['alias-subnet'] = $_POST['alias-subnet'];
- $wancfg['duid'] = $_POST['duid'];
- $wancfg['dhcp-ia-pd-len'] = $_POST['dhcp-ia-pd-len'];
- unset($wancfg['pd-sla-id']);
+ $wancfg['dhcp6-duid'] = $_POST['dhcp6-duid'];
+ $wancfg['dhcp6-ia-pd-len'] = $_POST['dhcp6-ia-pd-len'];
if($gateway_item) {
$a_gateways[] = $gateway_item;
}
@@ -716,7 +728,6 @@ if ($_POST['apply']) {
$a_ppps[$pppid]['apn'] = $_POST['apn'];
$wancfg['if'] = $_POST['type'] . $_POST['ptpid'];
$wancfg['ipaddr'] = $_POST['type'];
- unset($wancfg['pd-sla-id']);
unset($a_ppps[$pppid]['ondemand']);
unset($a_ppps[$pppid]['idletimeout']);
break;
@@ -747,7 +758,6 @@ if ($_POST['apply']) {
unset($a_ppps[$pppid]['pppoe-reset-type']);
$wancfg['if'] = $_POST['type'].$_POST['ptpid'];
$wancfg['ipaddr'] = $_POST['type'];
- unset($wancfg['pd-sla-id']);
if($gateway_item) {
$a_gateways[] = $gateway_item;
}
@@ -774,7 +784,6 @@ if ($_POST['apply']) {
unset($a_ppps[$pppid]['idletimeout']);
$wancfg['if'] = $_POST['type'].$_POST['ptpid'];
$wancfg['ipaddr'] = $_POST['type'];
- unset($wancfg['pd-sla-id']);
if($gateway_item) {
$a_gateways[] = $gateway_item;
}
@@ -1399,9 +1408,9 @@ $types = array("none" => gettext("None"), "staticv4" => gettext("Static IPv4"),
</td>
</tr>
<tr>
- <td width="22%" valign="top" class="vncell"><?=gettext("Gateway IPv6"); ?></td>
+ <td width="22%" valign="top" class="vncell"><?=gettext("DHCPv6 Prefix Delegation ID"); ?></td>
<td width="78%" class="vtable">
- <select name="pd-sla-id" class="formselect" id="pd-sla-id">
+ <select name="dhcp6-pd-sla-id" class="formselect" id="dhcp6-pd-sla-id">
<option value="none" selected><?=gettext("None"); ?></option>
<?php
// FIXME: Needs to calculate from prefix length from dhcp-pd
@@ -1409,11 +1418,13 @@ $types = array("none" => gettext("None"), "staticv4" => gettext("Static IPv4"),
for ($i = 16; $i > 0; $i--) {
if($i <> 15) {
echo "<option value=\"{$i}\" ";
- if ($i == $pconfig['pd-sla-id']) echo "selected";
+ if ($i == $pconfig['dhcp6-pd-sla-id']) echo "selected";
echo ">" . $i . "</option>";
}
}
- ?>
+ ?>
+ </select>
+ <?=gettext("This ID sets the delegated DHCP-PD prefix number which will be used to setup the interface.");?>
</td>
</tr>
@@ -1524,14 +1535,33 @@ $types = array("none" => gettext("None"), "staticv4" => gettext("Static IPv4"),
</td>
</tr>
<tr>
+ <td width="22%" valign="top" class="vncell"><?=gettext("Alias IPv4 address"); ?></td>
+ <td width="78%" class="vtable">
+ <input name="alias-address" type="text" class="formfld unknown" id="alias-address" size="20" value="<?=htmlspecialchars($pconfig['alias-address']);?>">
+ <select name="alias-subnet" class="formselect" id="alias-subnet">
+ <?php
+ for ($i = 32; $i > 0; $i--) {
+ if($i <> 31) {
+ echo "<option value=\"{$i}\" ";
+ if ($i == $pconfig['alias-subnet']) echo "selected";
+ echo ">" . $i . "</option>";
+ }
+ }
+ ?>
+ </select>
+ <?=gettext("The value in this field is used as a fixed alias IPv4 address by the " .
+ "DHCP client."); ?>
+ </td>
+ </tr>
+ <tr>
<td width="22%" valign="top" class="vncell"><?=gettext("DHCPv6 Unique Identifier (DUID)"); ?></td>
<td width="78%" class="vtable">
- <input name="duid" type="text" class="formfld unknown" id="duid" size="40" value="<?=htmlspecialchars($pconfig['duid']);?>">
+ <input name="dhcp6-duid" type="text" class="formfld unknown" id="dhcp6-duid" size="40" value="<?=htmlspecialchars($pconfig['dhcp6-duid']);?>">
<br>
<?=gettext("The value in this field is sent as the DHCPv6 client identifier " .
"when requesting a DHCPv6 lease."); ?><br />
<?php if(is_readable("/var/db/dhcp6c_duid")) {
- $current_duid = file_get_contents("/var/db/dhcp6c_duid");
+ // $current_duid = file_get_contents("/var/db/dhcp6c_duid");
}
echo gettext("The current DUID is: '") . $current_duid ."'";
?>
@@ -1541,37 +1571,18 @@ $types = array("none" => gettext("None"), "staticv4" => gettext("Static IPv4"),
<tr>
<td width="22%" valign="top" class="vncell"><?=gettext("DHCPv6 Prefix Delegation size"); ?></td>
<td width="78%" class="vtable">
- <select name="dhcp-ia-pd-len" class="formselect" id="dhcp-ia-pd-len">
+ <select name="dhcp6-ia-pd-len" class="formselect" id="dhcp6-ia-pd-len">
<?php
- $sizes = array(16 => "48", 12 => "52", 8 => "56", 4 => "60", 2 => "62", 1 => "63", 0 => "64");
+ $sizes = array("none" => "None", 16 => "48", 12 => "52", 8 => "56", 4 => "60", 2 => "62", 1 => "63", 0 => "64");
foreach($sizes as $bits => $length) {
echo "<option value=\"{$bits}\" ";
- if ($bits == $pconfig['dhcp-ia-pd-len']) echo "selected";
+ if (is_numeric($pconfig['dhcp6-ia-pd-len']) && ($bits == $pconfig['dhcp6-ia-pd-len'])) echo "selected";
echo ">" . $length . "</option>";
}
?>
</select>
<br>
- <?=gettext("The value in this field is the delegated prefix length provided by DHCPv6. Normally specified by the ISP."); ?>
- </td>
- </tr>
- <tr>
- <td width="22%" valign="top" class="vncell"><?=gettext("Alias IP address"); ?></td>
- <td width="78%" class="vtable">
- <input name="alias-address" type="text" class="formfld unknown" id="alias-address" size="20" value="<?=htmlspecialchars($pconfig['alias-address']);?>">
- <select name="alias-subnet" class="formselect" id="alias-subnet">
- <?php
- for ($i = 32; $i > 0; $i--) {
- if($i <> 31) {
- echo "<option value=\"{$i}\" ";
- if ($i == $pconfig['alias-subnet']) echo "selected";
- echo ">" . $i . "</option>";
- }
- }
- ?>
- </select>
- <?=gettext("The value in this field is used as a fixed alias IP address by the " .
- "DHCP client."); ?>
+ <?=gettext("The value in this field is the delegated prefix length provided by the DHCPv6 server. Normally specified by the ISP."); ?>
</td>
</tr>
OpenPOWER on IntegriCloud