diff options
author | smos <seth.mos@dds.nl> | 2012-01-25 17:57:22 +0100 |
---|---|---|
committer | smos <seth.mos@dds.nl> | 2012-01-25 18:17:14 +0100 |
commit | 668e8961ffac78f7a605b3ab87064d98ad7700e9 (patch) | |
tree | f5b21d16ddccfbf4f7521401a93aea12a2c4e064 | |
parent | a843870de25d5f938cf91fdea1ff823e5ccc5bec (diff) | |
download | pfsense-668e8961ffac78f7a605b3ab87064d98ad7700e9.zip pfsense-668e8961ffac78f7a605b3ab87064d98ad7700e9.tar.gz |
Add backend 6RD support. We don't have the required patch yet for our stf driver.
Needs hooks into our gateway code to handle the default gateway since the stf interface does use router solicitations
Adds to ticket #2117
-rw-r--r-- | etc/inc/interfaces.inc | 37 | ||||
-rw-r--r-- | etc/inc/services.inc | 74 | ||||
-rwxr-xr-x | usr/local/www/interfaces.php | 39 |
3 files changed, 148 insertions, 2 deletions
diff --git a/etc/inc/interfaces.inc b/etc/inc/interfaces.inc index b8cd1af..aff0ad6 100644 --- a/etc/inc/interfaces.inc +++ b/etc/inc/interfaces.inc @@ -2936,6 +2936,43 @@ function interface_carpdev_dhcp_configure($interface = "wan") { return 0; } +function interface_6rd_configure($interface = "wan"){ + global $config, $g; + $iflist = get_configured_interface_with_descr(false, true); + + /* because this is a tunnel interface we can only function + * with a public IPv4 address on the interface */ + + $wancfg = $config['interfaces'][$interface]; + $wanif = $wancfg['if']; + if (empty($wancfg)) + $wancfg = array(); + + $wanif = get_real_interface($interface); + + $ip4address = find_interface_ip($wanif); + if((!is_ipaddrv4($ip4address)) || (is_private_ip($ip4address))) { + log_error("The interface IPv4 '{$ip4address}' address on interface '{$wanif}' is not public, not configuring 6RD tunnel"); + // return false; + } + + /* setup the stf interface */ + mwexec("/sbin/ifconfig stf0 destroy"); + mwexec("/sbin/ifconfig stf0 create"); + mwexec("/sbin/ifconfig stf0 inet6 {$wancfg['prefix-6rd']}"); + + /* Example 6RD setup steps + # ifconfig fxp0 inet6 2001:db8:c000:0202::1/64 + # ifconfig fxp1 inet 192.0.2.2/24 + # ifconfig stf0 create + # ifconfig stf0 inet6 2001:db8:c000:0202::/32 + # route add -inet6 default 2001:db8:c000:0201::1 + */ + + return 0; + +} + function interface_dhcpv6_configure($interface = "wan") { global $config, $g; $iflist = get_configured_interface_with_descr(false, true); diff --git a/etc/inc/services.inc b/etc/inc/services.inc index d1e8d86..3f88455 100644 --- a/etc/inc/services.inc +++ b/etc/inc/services.inc @@ -91,6 +91,8 @@ EOD; /* Process all links which need the router advertise daemon */ $rtadvdnum = 0; $rtadvdifs=array(); + + /* handle manually configured DHCP6 settings first */ foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) { if($dhcpv6ifconf['mode'] == "disabled") continue; @@ -155,6 +157,7 @@ EOD; $rtadvdnum++; } + /* handle DHCP-PD prefixes */ foreach ($Iflist as $if => $ifdescr) { if(!is_numeric($config['interfaces'][$if]['dhcp6-pd-sla-id'])) continue; @@ -201,6 +204,77 @@ EOD; } } + /* Handle 6RD prefix assignment */ + foreach ($Iflist as $if => $ifdescr) { + if(!is_numeric($config['interfaces'][$if]['prefix-6rd-id'])) + continue; + + echo "rtadvd config for {$if}\n"; + + $realif = get_real_interface($if); + /* prevent duplicate entries */ + if(in_array($realif, $rtadvdifs)) + continue; + + $rtadvdifs[] = $realif; + + /* find the interface which has the 6RD prefix defined and it's IPv4 address */ + foreach($Iflist as $rdif => $rdifdescr) { + if($config['interfaces'][$rdif]['ipaddrv6'] == "6rd") { + $realrdif = get_real_interface("$rdif"); + $ip4address = find_interface_ip($realrdif); + echo "rtadvd config found 6RD if {$rdif} address {$ip4address}\n"; + if((!is_ipaddrv4($ip4address)) || (is_private_ip($ip4address))) { + log_error("The interface IPv4 '{$ip4address}' address on interface '{$rdif}' is not public, not configuring 6RD prefix on {$if}"); + // continue; + } + /* calculate the IPv6 prefix from the public IPv4 address */ + $ip4arr = explode(".", $ip4address); + $rd6prefix = explode("/", $config['interfaces'][$rdif]['prefix-6rd']); + $rd6prefix = explode(":", $rd6prefix[0]); + if($config['interfaces'][$rdif]['prefix-6rd-len'] == 0) { + $rd6lanprefixlen = 64; + } else { + log_error("We only support a 64 bit subnet currently"); + continue; + } + $rd6lanprefix = sprintf("{$rd6prefix[0]}:{$rd6prefix[1]}:%02x%02x:%02x%02x::", $ip4arr[0], $ip4arr[1], $ip4arr[2], $ip4arr[3]); + $subnetv6 = "{$rd6lanprefix}/{$rd6lanprefixlen}"; + // mwexec("/sbin/ifconfig {$realif} inet6 {$rd6lanprefix}1 prefixlen {$rd6lanprefixlen}"); + } + } + + + $dnslist = array(); + if(is_ipaddrv6($subnetv6)) { + $rtadvdconf .= "# Generated for 6RD on $if\n"; + $rtadvdconf .= "{$realif}:\\\n"; + /* use lower timers for 6RD prefixes */ + $rtadvdconf .= "\t:pltime=60:\\\n"; + $rtadvdconf .= "\t:pltime=120:\\\n"; + $rtadvdconf .= "\t:vltime=180:\\\n"; + $rtadvdconf .= "\t:rtltime=60:\\\n"; + $rtadvdconf .= "\t:addr=\"{$subnetv6}\":\\\n"; + $rtadvdconf .= "\t:prefixlen#{$rd6lanprefixlen}:\\\n"; + $rtadvdconf .= "\t:raflags=\"mo\":\\\n"; + if (isset($config['dnsmasq']['enable'])) { + $dnslist[] = get_interface_ipv6($dhcpv6if); + } elseif (!empty($config['system']['dnsserver'][0])) { + foreach($config['system']['dnsserver'] as $server) { + if(is_ipaddrv6($server)) + $dnslist[] = $server; + } + } + if(!empty($dnslist)) { + $dnsstring = implode(",", $dnslist); + $rtadvdconf .= "\t:rdnss=\"{$dnsstring}\":\\\n"; + } + $rtadvdconf .= "\t:tc=ether:\\\n"; + $rtadvdconf .= "\n\n"; + $rtadvdnum++; + } + } + fwrite($fd, $rtadvdconf); fclose($fd); diff --git a/usr/local/www/interfaces.php b/usr/local/www/interfaces.php index 10b2ce5..208925b 100755 --- a/usr/local/www/interfaces.php +++ b/usr/local/www/interfaces.php @@ -235,6 +235,7 @@ switch($wancfg['ipaddrv6']) { $pconfig['subnetv6'] = $wancfg['subnetv6']; $pconfig['gatewayv6'] = $wancfg['gatewayv6']; $pconfig['dhcp6-pd-sla-id'] = $wancfg['dhcp6-pd-sla-id']; + $pconfig['prefix-6rd-id'] = $wancfg['prefix-6rd-id']; } else $pconfig['type6'] = "none"; break; @@ -638,6 +639,7 @@ if ($_POST['apply']) { unset($wancfg['prefix-6rd']); unset($wancfg['prefix-6rd-len']); unset($wancfg['gateway-6rd']); + unset($wancfg['prefix-6rd-id']); unset($wancfg['pppoe_password']); unset($wancfg['pptp_username']); unset($wancfg['pptp_password']); @@ -788,6 +790,7 @@ if ($_POST['apply']) { $wancfg['ipaddrv6'] = $_POST['ipaddrv6']; $wancfg['subnetv6'] = $_POST['subnetv6']; $wancfg['dhcp6-pd-sla-id'] = $_POST['dhcp6-pd-sla-id']; + $wancfg['prefix-6rd-id'] = $_POST['prefix-6rd-id']; if ($_POST['gatewayv6'] != "none") { $wancfg['gatewayv6'] = $_POST['gatewayv6']; } @@ -1603,7 +1606,6 @@ $types6 = array("none" => gettext("None"), "staticv6" => gettext("Static IPv6"), <td width="22%" valign="top" class="vncell"><?=gettext("DHCPv6 Prefix Delegation ID"); ?></td> <td width="78%" class="vtable"> <select name="dhcp6-pd-sla-id" class="formselect" id="dhcp6-pd-sla-id"> - <option value="none" selected><?=gettext("None"); ?></option> <?php // Needs to check if the ID is not used on another interface foreach($ifdescrs as $pdif => $pddescr) { @@ -1612,11 +1614,16 @@ $types6 = array("none" => gettext("None"), "staticv6" => gettext("Static IPv6"), continue; } } + + if($pconfig['dhcp6-pd-sla-id'] == "none") + $selected = "selected"; + echo "<option value=\"none\" {$selected}>". gettext("None") ."</option>\n"; $numbers = pow(2, $pdlen); for($i = 0;$i < $numbers; $i++) { echo "<option value=\"{$i}\" "; - if ($i == $pconfig['dhcp6-pd-sla-id']) + if ("$i" == $pconfig['dhcp6-pd-sla-id']) { echo "selected"; + } echo ">" . dechex($i) . "</option>"; } ?> @@ -1624,6 +1631,34 @@ $types6 = array("none" => gettext("None"), "staticv6" => gettext("Static IPv6"), <?=gettext("This ID sets the delegated DHCP-PD prefix number which will be used to setup the interface.");?> </td> </tr> + <tr> + <td width="22%" valign="top" class="vncell"><?=gettext("6RD Rapid Deployment network ID"); ?></td> + <td width="78%" class="vtable"> + <select name="prefix-6rd-id" class="formselect" id="prefix-6rd-id"> + <?php + // Needs to check if the ID is not used on another interface + foreach($ifdescrs as $rdif => $rddescr) { + if(is_numeric($config['interfaces'][$rdif]['prefix-6rd-len'])) { + $rdlen = $config['interfaces'][$rdif]['prefix-6rd-len']; + continue; + } + } + if($pconfig['prefix-6rd-id'] == "none") + $selected = "selected"; + echo "<option value=\"none\" {$selected}>". gettext("None") ."</option>\n"; + $numbers = pow(2, $rdlen); + for($i = 0;$i < $numbers; $i++) { + echo "<option value=\"{$i}\" "; + if ("$i" == $pconfig['prefix-6rd-id']) { + echo "selected"; + } + echo ">" . dechex($i) . "</option>"; + } + ?> + </select> + <?=gettext("This ID sets the 6RD network prefix which will be used to setup the interface.");?> + </td> + </tr> </table> </td> </tr> |