From 668e8961ffac78f7a605b3ab87064d98ad7700e9 Mon Sep 17 00:00:00 2001 From: smos Date: Wed, 25 Jan 2012 17:57:22 +0100 Subject: 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 --- etc/inc/interfaces.inc | 37 ++++++++++++++++++++++ etc/inc/services.inc | 74 ++++++++++++++++++++++++++++++++++++++++++++ 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"), + $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 "\n"; + $numbers = pow(2, $rdlen); + for($i = 0;$i < $numbers; $i++) { + echo ""; + } + ?> + + + + -- cgit v1.1