diff options
author | Seth Mos <seth.mos@dds.nl> | 2011-05-06 12:09:57 +0000 |
---|---|---|
committer | Seth Mos <seth.mos@dds.nl> | 2011-05-06 12:09:57 +0000 |
commit | ed3956405edee6a8cde1dca85b92d7b5154573ff (patch) | |
tree | f5f5b439d9115b4095729647a24f812b2658cce5 | |
parent | 93a138ab04c551d5bcad07392fe4378a6924a23c (diff) | |
download | pfsense-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.inc | 128 | ||||
-rw-r--r-- | etc/inc/services.inc | 34 | ||||
-rwxr-xr-x | usr/local/www/interfaces.php | 91 |
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> |