xref: /freebsd/libexec/rc/rc.d/netwait (revision f99f0ee14e3af81c23150a6a340259ca8a33d01a)
10696600cSBjoern A. Zeeb#!/bin/sh
20696600cSBjoern A. Zeeb#
30696600cSBjoern A. Zeeb# PROVIDE: netwait
451da4b19SCy Schubert# REQUIRE: devd ipfw pf routing
50696600cSBjoern A. Zeeb# KEYWORD: nojail
60696600cSBjoern A. Zeeb#
70696600cSBjoern A. Zeeb# The netwait script helps handle two situations:
80696600cSBjoern A. Zeeb#  - Systems with USB or other late-attaching network hardware which
90696600cSBjoern A. Zeeb#    is initialized by devd events.  The script waits for all the
100696600cSBjoern A. Zeeb#    interfaces named in the netwait_if list to appear.
110696600cSBjoern A. Zeeb#  - Systems with statically-configured IP addresses in rc.conf(5).
120696600cSBjoern A. Zeeb#    The IP addresses in the netwait_ip list are pinged.  The script
130696600cSBjoern A. Zeeb#    waits for any single IP in the list to respond to the ping.  If your
140696600cSBjoern A. Zeeb#    system uses DHCP, you should probably use synchronous_dhclient="YES"
150696600cSBjoern A. Zeeb#    in your /etc/rc.conf instead of netwait_ip.
160696600cSBjoern A. Zeeb# Either or both of the wait lists can be used (at least one must be
170696600cSBjoern A. Zeeb# non-empty if netwait is enabled).
180696600cSBjoern A. Zeeb
190696600cSBjoern A. Zeeb. /etc/rc.subr
200696600cSBjoern A. Zeeb
210696600cSBjoern A. Zeebname="netwait"
220696600cSBjoern A. Zeebdesc="Wait for network devices or the network being up"
230696600cSBjoern A. Zeebrcvar="netwait_enable"
240696600cSBjoern A. Zeeb
250696600cSBjoern A. Zeebstart_cmd="${name}_start"
260696600cSBjoern A. Zeebstop_cmd=":"
270696600cSBjoern A. Zeeb
280696600cSBjoern A. Zeebnetwait_start()
290696600cSBjoern A. Zeeb{
300696600cSBjoern A. Zeeb	local ip rc count output link wait_if got_if any_error
310696600cSBjoern A. Zeeb
320696600cSBjoern A. Zeeb	if [ -z "${netwait_if}" ] && [ -z "${netwait_ip}" ]; then
330696600cSBjoern A. Zeeb		err 1 "No interface or IP addresses listed, nothing to wait for"
340696600cSBjoern A. Zeeb	fi
350696600cSBjoern A. Zeeb
360696600cSBjoern A. Zeeb	if [ ${netwait_timeout} -lt 1 ]; then
370696600cSBjoern A. Zeeb		err 1 "netwait_timeout must be >= 1"
380696600cSBjoern A. Zeeb	fi
390696600cSBjoern A. Zeeb
400696600cSBjoern A. Zeeb	if [ -n "${netwait_if}" ]; then
410696600cSBjoern A. Zeeb		any_error=0
420696600cSBjoern A. Zeeb		for wait_if in ${netwait_if}; do
430696600cSBjoern A. Zeeb			echo -n "Waiting for ${wait_if}"
440696600cSBjoern A. Zeeb			link=""
450696600cSBjoern A. Zeeb			got_if=0
460696600cSBjoern A. Zeeb			count=1
470696600cSBjoern A. Zeeb			# Handle SIGINT (Ctrl-C); force abort of while() loop
480696600cSBjoern A. Zeeb			trap break SIGINT
490696600cSBjoern A. Zeeb			while [ ${count} -le ${netwait_if_timeout} ]; do
500696600cSBjoern A. Zeeb				if output=`/sbin/ifconfig ${wait_if} 2>/dev/null`; then
510696600cSBjoern A. Zeeb					if [ ${got_if} -eq 0 ]; then
520696600cSBjoern A. Zeeb						echo -n ", interface present"
530696600cSBjoern A. Zeeb						got_if=1
540696600cSBjoern A. Zeeb					fi
550696600cSBjoern A. Zeeb					link=`expr "${output}" : '.*[[:blank:]]status: \(no carrier\)'`
560696600cSBjoern A. Zeeb					if [ -z "${link}" ]; then
570696600cSBjoern A. Zeeb						echo ', got link.'
580696600cSBjoern A. Zeeb						break
590696600cSBjoern A. Zeeb					fi
600696600cSBjoern A. Zeeb				fi
610696600cSBjoern A. Zeeb				sleep 1
620696600cSBjoern A. Zeeb				count=$((count+1))
630696600cSBjoern A. Zeeb			done
640696600cSBjoern A. Zeeb			# Restore default SIGINT handler
650696600cSBjoern A. Zeeb			trap - SIGINT
660696600cSBjoern A. Zeeb			if [ ${got_if} -eq 0 ]; then
670696600cSBjoern A. Zeeb				echo ", wait failed: interface never appeared."
680696600cSBjoern A. Zeeb				any_error=1
690696600cSBjoern A. Zeeb			elif [ -n "${link}" ]; then
700696600cSBjoern A. Zeeb				echo ", wait failed: interface still has no link."
710696600cSBjoern A. Zeeb				any_error=1
720696600cSBjoern A. Zeeb			fi
730696600cSBjoern A. Zeeb		done
740696600cSBjoern A. Zeeb		if [ ${any_error} -eq 1 ]; then
750696600cSBjoern A. Zeeb		    warn "Continuing with startup, but be aware you may not have "
760696600cSBjoern A. Zeeb		    warn "a fully functional networking layer at this point."
770696600cSBjoern A. Zeeb		fi
780696600cSBjoern A. Zeeb	fi
790696600cSBjoern A. Zeeb
800696600cSBjoern A. Zeeb	if [ -n "${netwait_ip}" ]; then
810696600cSBjoern A. Zeeb		# Handle SIGINT (Ctrl-C); force abort of for() loop
820696600cSBjoern A. Zeeb		trap break SIGINT
830696600cSBjoern A. Zeeb
840696600cSBjoern A. Zeeb		for ip in ${netwait_ip}; do
850696600cSBjoern A. Zeeb			echo -n "Waiting for ${ip} to respond to ICMP ping"
860696600cSBjoern A. Zeeb
870696600cSBjoern A. Zeeb			count=1
880696600cSBjoern A. Zeeb			while [ ${count} -le ${netwait_timeout} ]; do
890696600cSBjoern A. Zeeb				/sbin/ping -t 1 -c 1 -o ${ip} >/dev/null 2>&1
900696600cSBjoern A. Zeeb				rc=$?
910696600cSBjoern A. Zeeb
920696600cSBjoern A. Zeeb				if [ $rc -eq 0 ]; then
930696600cSBjoern A. Zeeb					# Restore default SIGINT handler
940696600cSBjoern A. Zeeb					trap - SIGINT
950696600cSBjoern A. Zeeb
960696600cSBjoern A. Zeeb					echo ', got response.'
970696600cSBjoern A. Zeeb					return
980696600cSBjoern A. Zeeb				fi
990696600cSBjoern A. Zeeb				count=$((count+1))
1000696600cSBjoern A. Zeeb			done
1010696600cSBjoern A. Zeeb			echo ', failed: No response from host.'
1020696600cSBjoern A. Zeeb		done
1030696600cSBjoern A. Zeeb
1040696600cSBjoern A. Zeeb		# Restore default SIGINT handler
1050696600cSBjoern A. Zeeb		trap - SIGINT
1060696600cSBjoern A. Zeeb
1070696600cSBjoern A. Zeeb		warn "Exhausted IP list.  Continuing with startup, but be aware you may"
1080696600cSBjoern A. Zeeb		warn "not have a fully functional networking layer at this point."
1090696600cSBjoern A. Zeeb	fi
1100696600cSBjoern A. Zeeb
1110696600cSBjoern A. Zeeb}
1120696600cSBjoern A. Zeeb
1130696600cSBjoern A. Zeebload_rc_config $name
114*f99f0ee1SAlexander Leidinger
115*f99f0ee1SAlexander Leidinger# doesn't make sense to run in a svcj: config setting
116*f99f0ee1SAlexander Leidingernetwait_svcj="NO"
117*f99f0ee1SAlexander Leidinger
1180696600cSBjoern A. Zeebrun_rc_command "$1"
119