xref: /freebsd-12.1/libexec/rc/rc.d/netwait (revision 0696600c)
1*0696600cSBjoern A. Zeeb#!/bin/sh
2*0696600cSBjoern A. Zeeb
3*0696600cSBjoern A. Zeeb# $FreeBSD$
4*0696600cSBjoern A. Zeeb#
5*0696600cSBjoern A. Zeeb# PROVIDE: netwait
6*0696600cSBjoern A. Zeeb# REQUIRE: devd ipfilter ipfw pf routing
7*0696600cSBjoern A. Zeeb# KEYWORD: nojail
8*0696600cSBjoern A. Zeeb#
9*0696600cSBjoern A. Zeeb# The netwait script helps handle two situations:
10*0696600cSBjoern A. Zeeb#  - Systems with USB or other late-attaching network hardware which
11*0696600cSBjoern A. Zeeb#    is initialized by devd events.  The script waits for all the
12*0696600cSBjoern A. Zeeb#    interfaces named in the netwait_if list to appear.
13*0696600cSBjoern A. Zeeb#  - Systems with statically-configured IP addresses in rc.conf(5).
14*0696600cSBjoern A. Zeeb#    The IP addresses in the netwait_ip list are pinged.  The script
15*0696600cSBjoern A. Zeeb#    waits for any single IP in the list to respond to the ping.  If your
16*0696600cSBjoern A. Zeeb#    system uses DHCP, you should probably use synchronous_dhclient="YES"
17*0696600cSBjoern A. Zeeb#    in your /etc/rc.conf instead of netwait_ip.
18*0696600cSBjoern A. Zeeb# Either or both of the wait lists can be used (at least one must be
19*0696600cSBjoern A. Zeeb# non-empty if netwait is enabled).
20*0696600cSBjoern A. Zeeb
21*0696600cSBjoern A. Zeeb. /etc/rc.subr
22*0696600cSBjoern A. Zeeb
23*0696600cSBjoern A. Zeebname="netwait"
24*0696600cSBjoern A. Zeebdesc="Wait for network devices or the network being up"
25*0696600cSBjoern A. Zeebrcvar="netwait_enable"
26*0696600cSBjoern A. Zeeb
27*0696600cSBjoern A. Zeebstart_cmd="${name}_start"
28*0696600cSBjoern A. Zeebstop_cmd=":"
29*0696600cSBjoern A. Zeeb
30*0696600cSBjoern A. Zeebnetwait_start()
31*0696600cSBjoern A. Zeeb{
32*0696600cSBjoern A. Zeeb	local ip rc count output link wait_if got_if any_error
33*0696600cSBjoern A. Zeeb
34*0696600cSBjoern A. Zeeb	if [ -z "${netwait_if}" ] && [ -z "${netwait_ip}" ]; then
35*0696600cSBjoern A. Zeeb		err 1 "No interface or IP addresses listed, nothing to wait for"
36*0696600cSBjoern A. Zeeb	fi
37*0696600cSBjoern A. Zeeb
38*0696600cSBjoern A. Zeeb	if [ ${netwait_timeout} -lt 1 ]; then
39*0696600cSBjoern A. Zeeb		err 1 "netwait_timeout must be >= 1"
40*0696600cSBjoern A. Zeeb	fi
41*0696600cSBjoern A. Zeeb
42*0696600cSBjoern A. Zeeb	if [ -n "${netwait_if}" ]; then
43*0696600cSBjoern A. Zeeb		any_error=0
44*0696600cSBjoern A. Zeeb		for wait_if in ${netwait_if}; do
45*0696600cSBjoern A. Zeeb			echo -n "Waiting for ${wait_if}"
46*0696600cSBjoern A. Zeeb			link=""
47*0696600cSBjoern A. Zeeb			got_if=0
48*0696600cSBjoern A. Zeeb			count=1
49*0696600cSBjoern A. Zeeb			# Handle SIGINT (Ctrl-C); force abort of while() loop
50*0696600cSBjoern A. Zeeb			trap break SIGINT
51*0696600cSBjoern A. Zeeb			while [ ${count} -le ${netwait_if_timeout} ]; do
52*0696600cSBjoern A. Zeeb				if output=`/sbin/ifconfig ${wait_if} 2>/dev/null`; then
53*0696600cSBjoern A. Zeeb					if [ ${got_if} -eq 0 ]; then
54*0696600cSBjoern A. Zeeb						echo -n ", interface present"
55*0696600cSBjoern A. Zeeb						got_if=1
56*0696600cSBjoern A. Zeeb					fi
57*0696600cSBjoern A. Zeeb					link=`expr "${output}" : '.*[[:blank:]]status: \(no carrier\)'`
58*0696600cSBjoern A. Zeeb					if [ -z "${link}" ]; then
59*0696600cSBjoern A. Zeeb						echo ', got link.'
60*0696600cSBjoern A. Zeeb						break
61*0696600cSBjoern A. Zeeb					fi
62*0696600cSBjoern A. Zeeb				fi
63*0696600cSBjoern A. Zeeb				sleep 1
64*0696600cSBjoern A. Zeeb				count=$((count+1))
65*0696600cSBjoern A. Zeeb			done
66*0696600cSBjoern A. Zeeb			# Restore default SIGINT handler
67*0696600cSBjoern A. Zeeb			trap - SIGINT
68*0696600cSBjoern A. Zeeb			if [ ${got_if} -eq 0 ]; then
69*0696600cSBjoern A. Zeeb				echo ", wait failed: interface never appeared."
70*0696600cSBjoern A. Zeeb				any_error=1
71*0696600cSBjoern A. Zeeb			elif [ -n "${link}" ]; then
72*0696600cSBjoern A. Zeeb				echo ", wait failed: interface still has no link."
73*0696600cSBjoern A. Zeeb				any_error=1
74*0696600cSBjoern A. Zeeb			fi
75*0696600cSBjoern A. Zeeb		done
76*0696600cSBjoern A. Zeeb		if [ ${any_error} -eq 1 ]; then
77*0696600cSBjoern A. Zeeb		    warn "Continuing with startup, but be aware you may not have "
78*0696600cSBjoern A. Zeeb		    warn "a fully functional networking layer at this point."
79*0696600cSBjoern A. Zeeb		fi
80*0696600cSBjoern A. Zeeb	fi
81*0696600cSBjoern A. Zeeb
82*0696600cSBjoern A. Zeeb	if [ -n "${netwait_ip}" ]; then
83*0696600cSBjoern A. Zeeb		# Handle SIGINT (Ctrl-C); force abort of for() loop
84*0696600cSBjoern A. Zeeb		trap break SIGINT
85*0696600cSBjoern A. Zeeb
86*0696600cSBjoern A. Zeeb		for ip in ${netwait_ip}; do
87*0696600cSBjoern A. Zeeb			echo -n "Waiting for ${ip} to respond to ICMP ping"
88*0696600cSBjoern A. Zeeb
89*0696600cSBjoern A. Zeeb			count=1
90*0696600cSBjoern A. Zeeb			while [ ${count} -le ${netwait_timeout} ]; do
91*0696600cSBjoern A. Zeeb				/sbin/ping -t 1 -c 1 -o ${ip} >/dev/null 2>&1
92*0696600cSBjoern A. Zeeb				rc=$?
93*0696600cSBjoern A. Zeeb
94*0696600cSBjoern A. Zeeb				if [ $rc -eq 0 ]; then
95*0696600cSBjoern A. Zeeb					# Restore default SIGINT handler
96*0696600cSBjoern A. Zeeb					trap - SIGINT
97*0696600cSBjoern A. Zeeb
98*0696600cSBjoern A. Zeeb					echo ', got response.'
99*0696600cSBjoern A. Zeeb					return
100*0696600cSBjoern A. Zeeb				fi
101*0696600cSBjoern A. Zeeb				count=$((count+1))
102*0696600cSBjoern A. Zeeb			done
103*0696600cSBjoern A. Zeeb			echo ', failed: No response from host.'
104*0696600cSBjoern A. Zeeb		done
105*0696600cSBjoern A. Zeeb
106*0696600cSBjoern A. Zeeb		# Restore default SIGINT handler
107*0696600cSBjoern A. Zeeb		trap - SIGINT
108*0696600cSBjoern A. Zeeb
109*0696600cSBjoern A. Zeeb		warn "Exhausted IP list.  Continuing with startup, but be aware you may"
110*0696600cSBjoern A. Zeeb		warn "not have a fully functional networking layer at this point."
111*0696600cSBjoern A. Zeeb	fi
112*0696600cSBjoern A. Zeeb
113*0696600cSBjoern A. Zeeb}
114*0696600cSBjoern A. Zeeb
115*0696600cSBjoern A. Zeebload_rc_config $name
116*0696600cSBjoern A. Zeebrun_rc_command "$1"
117