interfaces: snoop prefix from wan for 6rd /64, slaac and dhcpv6 pd len "none"

PR: https://github.com/opnsense/core/issues/2663
This commit is contained in:
Franco Fichtner 2018-09-08 16:13:30 +02:00
parent 45a6e35c3d
commit 2cb88d030e
3 changed files with 31 additions and 24 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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;
}