diff --git a/src/etc/inc/interfaces.inc b/src/etc/inc/interfaces.inc index b3fc36987..91c3271ea 100644 --- a/src/etc/inc/interfaces.inc +++ b/src/etc/inc/interfaces.inc @@ -2937,8 +2937,8 @@ function interface_dhcpv6_prepare($interface = 'wan', $wancfg) if (is_numeric($wancfg['dhcp6-ia-pd-len'])) { /* Setup the prefix delegation */ $dhcp6cconf .= "id-assoc pd 0 {\n"; - $preflen = 64 - $wancfg['dhcp6-ia-pd-len']; if (isset($wancfg['dhcp6-ia-pd-send-hint'])) { + $preflen = 64 - $wancfg['dhcp6-ia-pd-len']; $dhcp6cconf .= " prefix ::/{$preflen} infinity;\n"; } $iflist = link_interface_to_track6($interface); diff --git a/src/etc/inc/services.inc b/src/etc/inc/services.inc index 8e2d9f6d1..c312cf758 100644 --- a/src/etc/inc/services.inc +++ b/src/etc/inc/services.inc @@ -323,6 +323,7 @@ function services_radvd_configure($blacklist = array()) $ifcfgipv6 = get_interface_ipv6($if); if ($autotype == 'slaac') { + /* XXX this may be incorrect and needs an override or revisit */ $subnetv6 = '2000::'; } elseif (is_ipaddrv6($ifcfgipv6)) { $ifcfgsnv6 = get_interface_subnetv6($if); @@ -347,7 +348,8 @@ function services_radvd_configure($blacklist = array()) $radvdconf .= sprintf("\tAdvLinkMTU %s;\n", !empty($mtu) ? $mtu : 1280); $radvdconf .= "\tAdvOtherConfigFlag on;\n"; $radvdconf .= "\tprefix {$subnetv6}/{$ifcfgsnv6} {\n"; - if ($autotype == 'slaac') { + /* if delegation is off or unavailable use the tracked interface prefix */ + if (calculate_ipv6_delegation_length($trackif) < 0) { $radvdconf .= "\t\tBase6Interface $realtrackif;\n"; $radvdconf .= "\t\tDeprecatePrefix on;\n"; } @@ -1112,16 +1114,16 @@ function services_dhcpdv6_configure($blacklist = array(), $verbose = false) continue; } if (!empty($config['interfaces'][$ifname]['track6-interface'])) { - $realif = get_real_interface($ifname, "inet6"); + $realif = get_real_interface($ifname, 'inet6'); $ifcfgipv6 = get_interface_ipv6($ifname); if (!is_ipaddrv6($ifcfgipv6)) { continue; } + $ifcfgipv6 = Net_IPv6::getNetmask($ifcfgipv6, 64); - $trackifname = $config['interfaces'][$ifname]['track6-interface']; - $trackcfg = $config['interfaces'][$trackifname]; - $pdlen = calculate_ipv6_delegation_length($trackifname); + if (!isset($config['interfaces'][$ifname]['dhcpd6track6allowoverride'])) { + /* mock a real server */ $dhcpdv6cfg[$ifname] = array(); $dhcpdv6cfg[$ifname]['enable'] = true; @@ -1133,7 +1135,8 @@ function services_dhcpdv6_configure($blacklist = array(), $verbose = false) $ifcfgipv6arr[7] = '2000'; $dhcpdv6cfg[$ifname]['range']['to'] = Net_IPv6::compress(implode(':', $ifcfgipv6arr)); - /* prefix length > 0? We can add dhcp6 prefix delegation server */ + /* with enough room we can add dhcp6 prefix delegation */ + $pdlen = calculate_ipv6_delegation_length($config['interfaces'][$ifname]['track6-interface']); if ($pdlen > 2) { $pdlenmax = $pdlen; $pdlenhalf = $pdlenmax - 1; diff --git a/src/etc/inc/util.inc b/src/etc/inc/util.inc index 7c1d66b52..d48d4fc87 100644 --- a/src/etc/inc/util.inc +++ b/src/etc/inc/util.inc @@ -231,36 +231,40 @@ function gen_subnetv6_max($ipaddr, $bits) return $result; } -/* Returns the calculated bit length of the prefix delegation from the WAN interface */ -/* DHCP-PD is variable, calculate from the prefix-len on the WAN interface */ -/* 6rd is variable, calculate from 64 - (v6 prefixlen - (32 - v4 prefixlen)) */ -/* 6to4 is 16 bits, e.g. 65535 */ -function calculate_ipv6_delegation_length($if) { +/* returns the calculated bit length of the prefix delegation from a WAN interface */ +function calculate_ipv6_delegation_length($if) +{ global $config; - if(!isset($config['interfaces'][$if]) || !is_array($config['interfaces'][$if])) { - return false; - } elseif (!isset($config['interfaces'][$if]['ipaddrv6'])) { - return 0; + $pdlen = -1; + + if (!isset($config['interfaces'][$if]['ipaddrv6'])) { + return $pdlen; } - switch($config['interfaces'][$if]['ipaddrv6']) { - case "6to4": + switch ($config['interfaces'][$if]['ipaddrv6']) { + case '6to4': $pdlen = 16; break; - case "6rd": + case '6rd': $rd6cfg = $config['interfaces'][$if]; - $rd6plen = explode("/", $rd6cfg['prefix-6rd']); - $pdlen = (64 - ($rd6plen[1] + (32 - $rd6cfg['prefix-6rd-v4plen']))); + $rd6plen = explode('/', $rd6cfg['prefix-6rd']); + $pdlen = 64 - ($rd6plen[1] + (32 - $rd6cfg['prefix-6rd-v4plen'])); + if ($pdlen == 0) { + /* XXX bug reports this is not working, needs investigation */ + $pdlen = -1; + } break; - case "dhcp6": + case 'dhcp6': $dhcp6cfg = $config['interfaces'][$if]; - $pdlen = $dhcp6cfg['dhcp6-ia-pd-len']; + if (is_numeric($dhcp6cfg['dhcp6-ia-pd-len'])) { + $pdlen = $dhcp6cfg['dhcp6-ia-pd-len']; + } break; default: - $pdlen = 0; break; } + return $pdlen; }