diff options
-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> |