10696600cSBjoern A. Zeeb#!/bin/sh 20696600cSBjoern A. Zeeb# 30696600cSBjoern A. Zeeb# PROVIDE: netwait 451da4b19SCy Schubert# REQUIRE: devd ipfw pf routing 50696600cSBjoern A. Zeeb# 65ead817cSDag-Erling Smørgrav# The netwait script helps handle three situations: 70696600cSBjoern A. Zeeb# - Systems with USB or other late-attaching network hardware which 80696600cSBjoern A. Zeeb# is initialized by devd events. The script waits for all the 90696600cSBjoern A. Zeeb# interfaces named in the netwait_if list to appear. 105ead817cSDag-Erling Smørgrav# - Systems with IPv6 addresses, especially jails, where we need to 115ead817cSDag-Erling Smørgrav# wait for DAD to complete before starting daemons, as they will 125ead817cSDag-Erling Smørgrav# otherwise fail to bind to IN6ADDR_ANY. 130696600cSBjoern A. Zeeb# - Systems with statically-configured IP addresses in rc.conf(5). 140696600cSBjoern A. Zeeb# The IP addresses in the netwait_ip list are pinged. The script 150696600cSBjoern A. Zeeb# waits for any single IP in the list to respond to the ping. If your 160696600cSBjoern A. Zeeb# system uses DHCP, you should probably use synchronous_dhclient="YES" 170696600cSBjoern A. Zeeb# in your /etc/rc.conf instead of netwait_ip. 180696600cSBjoern A. Zeeb# Either or both of the wait lists can be used (at least one must be 190696600cSBjoern A. Zeeb# non-empty if netwait is enabled). 200696600cSBjoern A. Zeeb 210696600cSBjoern A. Zeeb. /etc/rc.subr 220696600cSBjoern A. Zeeb 230696600cSBjoern A. Zeebname="netwait" 240696600cSBjoern A. Zeebdesc="Wait for network devices or the network being up" 250696600cSBjoern A. Zeebrcvar="netwait_enable" 260696600cSBjoern A. Zeeb 270696600cSBjoern A. Zeebstart_cmd="${name}_start" 280696600cSBjoern A. Zeebstop_cmd=":" 290696600cSBjoern A. Zeeb 300696600cSBjoern A. Zeebnetwait_start() 310696600cSBjoern A. Zeeb{ 320696600cSBjoern A. Zeeb local ip rc count output link wait_if got_if any_error 330696600cSBjoern A. Zeeb 345ead817cSDag-Erling Smørgrav if [ -z "${netwait_if}" ] && [ -z "${netwait_ip}" ] && 355ead817cSDag-Erling Smørgrav ! checkyesno netwait_dad ; then 365ead817cSDag-Erling Smørgrav err 1 "Nothing to wait for" 370696600cSBjoern A. Zeeb fi 380696600cSBjoern A. Zeeb 39*ec6ad605SDag-Erling Smørgrav if ! [ "${netwait_if_timeout:=0}" -ge 1 ]; then 405ead817cSDag-Erling Smørgrav err 1 "netwait_if_timeout must be >= 1" 415ead817cSDag-Erling Smørgrav fi 42*ec6ad605SDag-Erling Smørgrav if ! check_kern_features inet6; then 43*ec6ad605SDag-Erling Smørgrav netwait_dad="NO" 44*ec6ad605SDag-Erling Smørgrav elif ! [ "${netwait_dad_timeout:=0}" -ge 1 ]; then 45*ec6ad605SDag-Erling Smørgrav netwait_dad_timeout=$(($(sysctl -n net.inet6.ip6.dad_count)+1)) 465ead817cSDag-Erling Smørgrav fi 47*ec6ad605SDag-Erling Smørgrav if ! [ "${netwait_timeout:=0}" -ge 1 ]; then 480696600cSBjoern A. Zeeb err 1 "netwait_timeout must be >= 1" 490696600cSBjoern A. Zeeb fi 500696600cSBjoern A. Zeeb 515ead817cSDag-Erling Smørgrav any_error=false 525ead817cSDag-Erling Smørgrav 530696600cSBjoern A. Zeeb if [ -n "${netwait_if}" ]; then 540696600cSBjoern A. Zeeb for wait_if in ${netwait_if}; do 550696600cSBjoern A. Zeeb echo -n "Waiting for ${wait_if}" 560696600cSBjoern A. Zeeb link="" 575ead817cSDag-Erling Smørgrav got_if=false 580696600cSBjoern A. Zeeb count=1 595ead817cSDag-Erling Smørgrav # Handle SIGINT (Ctrl-C); force abort of while loop 600696600cSBjoern A. Zeeb trap break SIGINT 610696600cSBjoern A. Zeeb while [ ${count} -le ${netwait_if_timeout} ]; do 620696600cSBjoern A. Zeeb if output=`/sbin/ifconfig ${wait_if} 2>/dev/null`; then 635ead817cSDag-Erling Smørgrav if ! ${got_if}; then 640696600cSBjoern A. Zeeb echo -n ", interface present" 655ead817cSDag-Erling Smørgrav got_if=true 660696600cSBjoern A. Zeeb fi 670696600cSBjoern A. Zeeb link=`expr "${output}" : '.*[[:blank:]]status: \(no carrier\)'` 680696600cSBjoern A. Zeeb if [ -z "${link}" ]; then 690696600cSBjoern A. Zeeb echo ', got link.' 700696600cSBjoern A. Zeeb break 710696600cSBjoern A. Zeeb fi 720696600cSBjoern A. Zeeb fi 730696600cSBjoern A. Zeeb sleep 1 740696600cSBjoern A. Zeeb count=$((count+1)) 750696600cSBjoern A. Zeeb done 760696600cSBjoern A. Zeeb # Restore default SIGINT handler 770696600cSBjoern A. Zeeb trap - SIGINT 785ead817cSDag-Erling Smørgrav if ! ${got_if}; then 790696600cSBjoern A. Zeeb echo ", wait failed: interface never appeared." 805ead817cSDag-Erling Smørgrav any_error=true 810696600cSBjoern A. Zeeb elif [ -n "${link}" ]; then 820696600cSBjoern A. Zeeb echo ", wait failed: interface still has no link." 835ead817cSDag-Erling Smørgrav any_error=true 840696600cSBjoern A. Zeeb fi 850696600cSBjoern A. Zeeb done 865ead817cSDag-Erling Smørgrav fi 875ead817cSDag-Erling Smørgrav 885ead817cSDag-Erling Smørgrav if checkyesno netwait_dad; then 895ead817cSDag-Erling Smørgrav got_dad=false 905ead817cSDag-Erling Smørgrav # Handle SIGINT (Ctrl-C); force abort of while loop 915ead817cSDag-Erling Smørgrav trap break SIGINT 925ead817cSDag-Erling Smørgrav 935ead817cSDag-Erling Smørgrav echo -n "Waiting for DAD to complete" 945ead817cSDag-Erling Smørgrav count=1 955ead817cSDag-Erling Smørgrav while [ ${count} -le ${netwait_dad_timeout} ]; do 965ead817cSDag-Erling Smørgrav if ! ifconfig | grep -q 'inet6.*tentative'; then 975ead817cSDag-Erling Smørgrav echo ', done.' 985ead817cSDag-Erling Smørgrav got_dad=true 995ead817cSDag-Erling Smørgrav break 1005ead817cSDag-Erling Smørgrav fi 1015ead817cSDag-Erling Smørgrav sleep 1 1025ead817cSDag-Erling Smørgrav count=$((count+1)) 1035ead817cSDag-Erling Smørgrav done 1045ead817cSDag-Erling Smørgrav 1055ead817cSDag-Erling Smørgrav # Restore default SIGINT handler 1065ead817cSDag-Erling Smørgrav trap - SIGINT 1075ead817cSDag-Erling Smørgrav 1085ead817cSDag-Erling Smørgrav if ! ${got_dad}; then 1095ead817cSDag-Erling Smørgrav echo ', timed out.' 1105ead817cSDag-Erling Smørgrav any_error=true 1110696600cSBjoern A. Zeeb fi 1120696600cSBjoern A. Zeeb fi 1130696600cSBjoern A. Zeeb 1140696600cSBjoern A. Zeeb if [ -n "${netwait_ip}" ]; then 1155ead817cSDag-Erling Smørgrav got_ip=false 1165ead817cSDag-Erling Smørgrav # Handle SIGINT (Ctrl-C); force abort of for loop 1170696600cSBjoern A. Zeeb trap break SIGINT 1180696600cSBjoern A. Zeeb 1190696600cSBjoern A. Zeeb for ip in ${netwait_ip}; do 1200696600cSBjoern A. Zeeb echo -n "Waiting for ${ip} to respond to ICMP ping" 1210696600cSBjoern A. Zeeb 1220696600cSBjoern A. Zeeb count=1 1230696600cSBjoern A. Zeeb while [ ${count} -le ${netwait_timeout} ]; do 1240696600cSBjoern A. Zeeb /sbin/ping -t 1 -c 1 -o ${ip} >/dev/null 2>&1 1250696600cSBjoern A. Zeeb rc=$? 1260696600cSBjoern A. Zeeb 1270696600cSBjoern A. Zeeb if [ $rc -eq 0 ]; then 1280696600cSBjoern A. Zeeb echo ', got response.' 1295ead817cSDag-Erling Smørgrav got_ip=false 1305ead817cSDag-Erling Smørgrav break 2 1310696600cSBjoern A. Zeeb fi 1320696600cSBjoern A. Zeeb count=$((count+1)) 1330696600cSBjoern A. Zeeb done 1340696600cSBjoern A. Zeeb echo ', failed: No response from host.' 1350696600cSBjoern A. Zeeb done 1360696600cSBjoern A. Zeeb 1370696600cSBjoern A. Zeeb # Restore default SIGINT handler 1380696600cSBjoern A. Zeeb trap - SIGINT 1390696600cSBjoern A. Zeeb 1405ead817cSDag-Erling Smørgrav if ! ${got_ip}; then 1415ead817cSDag-Erling Smørgrav any_error=true 1425ead817cSDag-Erling Smørgrav fi 1430696600cSBjoern A. Zeeb fi 1440696600cSBjoern A. Zeeb 1455ead817cSDag-Erling Smørgrav if ${any_error}; then 1465ead817cSDag-Erling Smørgrav warn "Continuing with startup, but be aware you may not have " 1475ead817cSDag-Erling Smørgrav warn "a fully functional networking layer at this point." 1485ead817cSDag-Erling Smørgrav fi 1490696600cSBjoern A. Zeeb} 1500696600cSBjoern A. Zeeb 1510696600cSBjoern A. Zeebload_rc_config $name 152f99f0ee1SAlexander Leidinger 153f99f0ee1SAlexander Leidinger# doesn't make sense to run in a svcj: config setting 154f99f0ee1SAlexander Leidingernetwait_svcj="NO" 155f99f0ee1SAlexander Leidinger 1560696600cSBjoern A. Zeebrun_rc_command "$1" 157