Index: libexec/rc/network.subr =================================================================== --- libexec/rc/network.subr +++ libexec/rc/network.subr @@ -47,8 +47,8 @@ ifscript_up ${ifn} && cfg=0 ifconfig_up ${ifn} && cfg=0 if ! noafif $ifn; then - afexists inet && ipv4_up ${ifn} && cfg=0 afexists inet6 && ipv6_up ${ifn} && cfg=0 + afexists inet && ipv4_up ${ifn} && cfg=0 fi childif_create ${ifn} && cfg=0 @@ -1746,7 +1746,7 @@ _if=$1 _flag=$2 - ${IFCONFIG_CMD} $_if 2>/dev/null | while read proto addr rest; do + ${IFCONFIG_CMD} $_if inet6 2>/dev/null | while read proto addr rest; do case "${proto}/${addr}/${_flag}/${rest}" in inet6/fe80::*//*) echo ${addr} @@ -1766,3 +1766,49 @@ return done } + +# network6_gettentative if +# Check if there are any tentative IPv6 addresses on $if. +# Returns the number of tentative addresses found. +network6_gettentative() +{ + local _if proto addr rest count + _if=$1 + + count=0 + while read proto addr rest; do + case "${proto}/${addr}/${rest}" in + inet6/*/*tentative*) + count=$((count + 1)) + ;; + esac + done </dev/null` +EOI + + return ${count} +} + +# network6_gettentative if +# Wait for "tentative" addresses to clear on $_ifnlist. +# Returns with timeout or when all tentative flags are gone. +network6_waitdad() +{ + local _ifnlist _if count iter + _ifnlist="$1" + + count=1 + iter=0 + # We should never need more than 2 iterations unless someone + # adds more addresses while we sleep. + while test ${count} -gt 0 -a ${iter} -lt 2; do + sleep `${SYSCTL_N} net.inet6.ip6.dad_count` + count=0 + for _if in ${_ifnlist}; do + if ! network6_gettentative ${_if} ; then + count=1 + fi + done + iter=$((iter + 1)) + done +} Index: libexec/rc/rc.d/netif =================================================================== --- libexec/rc/rc.d/netif +++ libexec/rc/rc.d/netif @@ -200,6 +200,7 @@ done _dadwait= + _dadifn= _fail= _ok= for ifn in ${_cooked_list# }; do @@ -215,8 +216,10 @@ esac if ${_func} ${ifn} $2; then _ok="${_ok} ${ifn}" - if ipv6if ${ifn}; then + if ipv6if ${ifn} && \ + ! network6_gettentative ${ifn} ; then _dadwait=1 + _dadifn="${_dadifn} ${ifn}" fi else _fail="${_fail} ${ifn}" @@ -225,9 +228,8 @@ # inet6 address configuration needs sleep for DAD. case ${_func}:${_dadwait} in - ifn_start:1|ifn_vnetup:1|ifn_vnetdown:1) - sleep `${SYSCTL_N} net.inet6.ip6.dad_count` - sleep 1 + ifn_start:1) + network6_waitdad "${_dadifn}" ;; esac Index: libexec/rc/rc.d/rtsold =================================================================== --- libexec/rc/rc.d/rtsold +++ libexec/rc/rc.d/rtsold @@ -15,13 +15,6 @@ rcvar="rtsold_enable" command="/usr/sbin/${name}" pidfile="/var/run/${name}.pid" -start_postcmd="rtsold_poststart" - -rtsold_poststart() -{ - # wait for DAD - sleep $(($(${SYSCTL_N} net.inet6.ip6.dad_count) + 1)) -} load_rc_config $name run_rc_command "$1"