diff --git a/src/etc/inc/interfaces.inc b/src/etc/inc/interfaces.inc index e81e487599..b6caf60bec 100644 --- a/src/etc/inc/interfaces.inc +++ b/src/etc/inc/interfaces.inc @@ -1398,18 +1398,22 @@ function interfaces_vips_configure($interface, $family = null) $proxyarp = false; $pfsync = false; + $dad = false; foreach ($config['virtualip']['vip'] as $vip) { if ($vip['interface'] != $interface) { continue; } - if ($family === 4 && strpos($vip['subnet'], ':') !== false) { - continue; - } elseif ($family === 6 && strpos($vip['subnet'], ':') === false) { + $inet6 = strpos($vip['subnet'], ':') !== false; + + if (($family === 4 && $inet6) || ($family === 6 && !$inet6)) { continue; } + /* XXX trigger DAD only through rc.newwanipv6 explicit call for now */ + $dad = $dad || ($inet6 && $family === 6); + switch ($vip['mode']) { case 'proxyarp': $proxyarp = true; @@ -1431,6 +1435,10 @@ function interfaces_vips_configure($interface, $family = null) if ($proxyarp) { interface_proxyarp_configure(); } + + if ($dad) { + waitfordad(); + } } function interface_ipalias_configure($vip) diff --git a/src/etc/inc/util.inc b/src/etc/inc/util.inc index 765259282b..c13f06f3e2 100644 --- a/src/etc/inc/util.inc +++ b/src/etc/inc/util.inc @@ -93,6 +93,14 @@ function waitforpid($pidfile, $timeout = -1) return trim(file_get_contents($pidfile)); } +function waitfordad($grace_period = 1) +{ + $dad_delay = (int)get_single_sysctl('net.inet6.ip6.dad_count'); + if ($dad_delay) { + sleep($dad_delay + $grace_period); + } +} + function is_process_running($process) { exec('/bin/pgrep -anx ' . escapeshellarg($process), $output, $retval); diff --git a/src/etc/rc.newwanipv6 b/src/etc/rc.newwanipv6 index fb062a025b..a2f7c195ed 100755 --- a/src/etc/rc.newwanipv6 +++ b/src/etc/rc.newwanipv6 @@ -68,11 +68,7 @@ if (!$fp || !flock($fp, LOCK_EX | LOCK_NB)) { } /* wait for DAD to complete to avoid discarding tentative address */ -$dad_delay = (int)get_single_sysctl('net.inet6.ip6.dad_count'); -if ($dad_delay) { - /* XXX this is also required but missed for IPv6 VIPs created later in the script */ - sleep($dad_delay + 2); -} +waitfordad(2); /* this may be required to cleanse the DNS information no longer available */ system_resolver_configure();