1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
#!/bin/sh
#
# PROVIDE: netwait
# REQUIRE: devd ipfw pf routing
#
# The netwait script helps handle three situations:
# - Systems with USB or other late-attaching network hardware which
# is initialized by devd events. The script waits for all the
# interfaces named in the netwait_if list to appear.
# - Systems with IPv6 addresses, especially jails, where we need to
# wait for DAD to complete before starting daemons, as they will
# otherwise fail to bind to IN6ADDR_ANY.
# - Systems with statically-configured IP addresses in rc.conf(5).
# The IP addresses in the netwait_ip list are pinged. The script
# waits for any single IP in the list to respond to the ping. If your
# system uses DHCP, you should probably use synchronous_dhclient="YES"
# in your /etc/rc.conf instead of netwait_ip.
# Either or both of the wait lists can be used (at least one must be
# non-empty if netwait is enabled).
. /etc/rc.subr
name="netwait"
desc="Wait for network devices or the network being up"
rcvar="netwait_enable"
start_cmd="${name}_start"
stop_cmd=":"
netwait_start()
{
local ip rc count output link wait_if got_if any_error
if [ -z "${netwait_if}" ] && [ -z "${netwait_ip}" ] &&
! checkyesno netwait_dad ; then
err 1 "Nothing to wait for"
fi
if ! [ "${netwait_if_timeout:=0}" -ge 1 ]; then
err 1 "netwait_if_timeout must be >= 1"
fi
if ! check_kern_features inet6; then
netwait_dad="NO"
elif ! [ "${netwait_dad_timeout:=0}" -ge 1 ]; then
netwait_dad_timeout=$(($(sysctl -n net.inet6.ip6.dad_count)+1))
fi
if ! [ "${netwait_timeout:=0}" -ge 1 ]; then
err 1 "netwait_timeout must be >= 1"
fi
any_error=false
if [ -n "${netwait_if}" ]; then
for wait_if in ${netwait_if}; do
echo -n "Waiting for ${wait_if}"
link=""
got_if=false
count=1
# Handle SIGINT (Ctrl-C); force abort of while loop
trap break SIGINT
while [ ${count} -le ${netwait_if_timeout} ]; do
if output=`/sbin/ifconfig ${wait_if} 2>/dev/null`; then
if ! ${got_if}; then
echo -n ", interface present"
got_if=true
fi
link=`expr "${output}" : '.*[[:blank:]]status: \(no carrier\)'`
if [ -z "${link}" ]; then
echo ', got link.'
break
fi
fi
sleep 1
count=$((count+1))
done
# Restore default SIGINT handler
trap - SIGINT
if ! ${got_if}; then
echo ", wait failed: interface never appeared."
any_error=true
elif [ -n "${link}" ]; then
echo ", wait failed: interface still has no link."
any_error=true
fi
done
fi
if checkyesno netwait_dad; then
got_dad=false
# Handle SIGINT (Ctrl-C); force abort of while loop
trap break SIGINT
echo -n "Waiting for DAD to complete"
count=1
while [ ${count} -le ${netwait_dad_timeout} ]; do
if ! ifconfig | grep -q 'inet6.*tentative'; then
echo ', done.'
got_dad=true
break
fi
sleep 1
count=$((count+1))
done
# Restore default SIGINT handler
trap - SIGINT
if ! ${got_dad}; then
echo ', timed out.'
any_error=true
fi
fi
if [ -n "${netwait_ip}" ]; then
got_ip=false
# Handle SIGINT (Ctrl-C); force abort of for loop
trap break SIGINT
for ip in ${netwait_ip}; do
echo -n "Waiting for ${ip} to respond to ICMP ping"
count=1
while [ ${count} -le ${netwait_timeout} ]; do
/sbin/ping -t 1 -c 1 -o ${ip} >/dev/null 2>&1
rc=$?
if [ $rc -eq 0 ]; then
echo ', got response.'
got_ip=false
break 2
fi
count=$((count+1))
done
echo ', failed: No response from host.'
done
# Restore default SIGINT handler
trap - SIGINT
if ! ${got_ip}; then
any_error=true
fi
fi
if ${any_error}; then
warn "Continuing with startup, but be aware you may not have "
warn "a fully functional networking layer at this point."
fi
}
load_rc_config $name
# doesn't make sense to run in a svcj: config setting
netwait_svcj="NO"
run_rc_command "$1"
|