]>
Commit | Line | Data |
---|---|---|
4977febf | 1 | #!/bin/sh |
9d169a07 | 2 | |
01b23b69 HH |
3 | is_ip() { |
4 | echo "$1" | { | |
5 | IFS=. read a b c d | |
6 | test "$a" -ge 0 -a "$a" -le 255 \ | |
7 | -a "$b" -ge 0 -a "$b" -le 255 \ | |
8 | -a "$c" -ge 0 -a "$c" -le 255 \ | |
9 | -a "$d" -ge 0 -a "$d" -le 255 \ | |
10 | 2> /dev/null | |
11 | } && return 0 | |
12 | return 1 | |
13 | } | |
14 | ||
9d169a07 WW |
15 | get_ip() { |
16 | local iface="$1" ip="" | |
17 | ip=$(ip -o -f inet addr show $iface) | |
18 | ip=${ip%%/*} | |
19 | ip=${ip##* } | |
c1c96f2c | 20 | echo $ip |
9d169a07 WW |
21 | } |
22 | ||
23 | iface_for_remote_addr() { | |
24 | set -- $(ip -o route get to $1) | |
25 | echo $5 | |
26 | } | |
27 | ||
4ef0e2d9 WW |
28 | iface_for_ip() { |
29 | set -- $(ip -o addr show to $1) | |
30 | echo $2 | |
31 | } | |
32 | ||
9d169a07 | 33 | iface_for_mac() { |
99c7b70d | 34 | local interface="" mac="$(echo $1 | sed 'y/ABCDEF/abcdef/')" |
9d169a07 WW |
35 | for interface in /sys/class/net/*; do |
36 | if [ $(cat $interface/address) = "$mac" ]; then | |
37 | echo ${interface##*/} | |
38 | fi | |
39 | done | |
40 | } | |
41 | ||
4ef0e2d9 WW |
42 | # get the iface name for the given identifier - either a MAC, IP, or iface name |
43 | iface_name() { | |
44 | case $1 in | |
45 | ??:??:??:??:??:??|??-??-??-??-??-??) iface_for_mac $1 ;; | |
46 | *:*:*|*.*.*.*) iface_for_ip $1 ;; | |
47 | *) echo $1 ;; | |
48 | esac | |
49 | } | |
50 | ||
51 | # list the configured interfaces | |
52 | configured_ifaces() { | |
53 | local IFACES="" iface_id="" rv=1 | |
54 | [ -e "/tmp/net.ifaces" ] && read IFACES < /tmp/net.ifaces | |
55 | if { pidof udevd || pidof systemd-udevd; } > /dev/null; then | |
56 | for iface_id in $IFACES; do | |
57 | echo $(iface_name $iface_id) | |
58 | rv=0 | |
59 | done | |
60 | else | |
61 | warn "configured_ifaces called before udev is running" | |
62 | echo $IFACES | |
63 | [ -n "$IFACES" ] && rv=0 | |
64 | fi | |
65 | return $rv | |
66 | } | |
67 | ||
25aa3c5a WW |
68 | all_ifaces_up() { |
69 | local iface="" IFACES="" | |
70 | [ -e "/tmp/net.ifaces" ] && read IFACES < /tmp/net.ifaces | |
71 | for iface in $IFACES; do | |
72 | [ -e /tmp/net.$iface.up ] || return 1 | |
73 | done | |
74 | } | |
75 | ||
5d90ba4f HH |
76 | all_ifaces_setup() { |
77 | local iface="" IFACES="" | |
78 | [ -e "/tmp/net.ifaces" ] && read IFACES < /tmp/net.ifaces | |
79 | for iface in $IFACES; do | |
80 | [ -e /tmp/net.$iface.did-setup ] || return 1 | |
81 | done | |
82 | } | |
83 | ||
25aa3c5a WW |
84 | get_netroot_ip() { |
85 | local prefix="" server="" rest="" | |
86 | splitsep "$1" ":" prefix server rest | |
87 | case $server in | |
88 | [0-9]*\.[0-9]*\.[0-9]*\.[0-9]*) echo "$server"; return 0 ;; | |
89 | esac | |
90 | return 1 | |
91 | } | |
92 | ||
93 | ip_is_local() { | |
94 | strstr "$(ip route get $1 2>/dev/null)" " via " | |
95 | } | |
96 | ||
97 | ifdown() { | |
98 | local netif="$1" | |
99 | # ip down/flush ensures that routing info goes away as well | |
100 | ip link set $netif down | |
101 | ip addr flush dev $netif | |
102 | echo "#empty" > /etc/resolv.conf | |
32bd2fbb | 103 | rm -f -- /tmp/net.$netif.did-setup |
e7838a83 HH |
104 | [ -z "$DO_VLAN" ] && \ |
105 | [ -e /sys/class/net/$netif/address ] && \ | |
43a85a73 | 106 | rm -f -- /tmp/net.$(cat /sys/class/net/$netif/address).did-setup |
25aa3c5a WW |
107 | # TODO: send "offline" uevent? |
108 | } | |
109 | ||
110 | setup_net() { | |
111 | local netif="$1" f="" gw_ip="" netroot_ip="" iface="" IFACES="" | |
7b46244b | 112 | local _p |
1e4a8801 | 113 | [ -e /tmp/net.$netif.did-setup ] && return |
e7838a83 HH |
114 | [ -z "$DO_VLAN" ] && \ |
115 | [ -e /sys/class/net/$netif/address ] && \ | |
43a85a73 | 116 | [ -e /tmp/net.$(cat /sys/class/net/$netif/address).did-setup ] && return |
25aa3c5a WW |
117 | [ -e "/tmp/net.ifaces" ] && read IFACES < /tmp/net.ifaces |
118 | [ -z "$IFACES" ] && IFACES="$netif" | |
25aa3c5a | 119 | # run the scripts written by ifup |
25aa3c5a WW |
120 | [ -e /tmp/net.$netif.hostname ] && . /tmp/net.$netif.hostname |
121 | [ -e /tmp/net.$netif.override ] && . /tmp/net.$netif.override | |
122 | [ -e /tmp/dhclient.$netif.dhcpopts ] && . /tmp/dhclient.$netif.dhcpopts | |
123 | # set up resolv.conf | |
124 | [ -e /tmp/net.$netif.resolv.conf ] && \ | |
9e19c051 | 125 | awk '!array[$0]++' /tmp/net.$netif.resolv.conf > /etc/resolv.conf |
0b7bfacf | 126 | [ -e /tmp/net.$netif.gw ] && . /tmp/net.$netif.gw |
25aa3c5a | 127 | |
7b46244b HH |
128 | # add static route |
129 | for _p in $(getargs rd.route); do | |
130 | route_to_var "$_p" || continue | |
c440d302 | 131 | [ -n "$route_dev" ] && [ "$route_dev" != "$netif" ] && continue |
7b46244b | 132 | ip route add "$route_mask" ${route_gw:+via "$route_gw"} ${route_dev:+dev "$route_dev"} |
29b885b4 | 133 | if strstr "$route_mask" ":"; then |
7b46244b HH |
134 | printf -- "%s\n" "$route_mask ${route_gw:+via $route_gw} ${route_dev:+dev $route_dev}" \ |
135 | > /tmp/net.route6."$netif" | |
136 | else | |
137 | printf -- "%s\n" "$route_mask ${route_gw:+via $route_gw} ${route_dev:+dev $route_dev}" \ | |
138 | > /tmp/net.route."$netif" | |
139 | fi | |
140 | done | |
141 | ||
11085802 SH |
142 | # If a static route was necessary to reach the gateway, the |
143 | # first gateway setup call will have failed with | |
144 | # RTNETLINK answers: Network is unreachable | |
145 | # Replace the default route again after static routes to cover | |
146 | # this scenario. | |
147 | [ -e /tmp/net.$netif.gw ] && . /tmp/net.$netif.gw | |
148 | ||
25aa3c5a WW |
149 | # Handle STP Timeout: arping the default gateway. |
150 | # (or the root server, if a) it's local or b) there's no gateway.) | |
151 | # Note: This assumes that if no router is present the | |
152 | # root server is on the same subnet. | |
153 | ||
154 | # Get DHCP-provided router IP, or the cmdline-provided "gw=" argument | |
155 | [ -n "$new_routers" ] && gw_ip=${new_routers%%,*} | |
156 | [ -n "$gw" ] && gw_ip=$gw | |
157 | ||
158 | # Get the "netroot" IP (if there's an IP address in there) | |
159 | netroot_ip=$(get_netroot_ip $netroot) | |
160 | ||
161 | # try netroot if it's local (or there's no gateway) | |
162 | if ip_is_local $netroot_ip || [ -z "$gw_ip" ]; then | |
163 | dest="$netroot_ip" | |
164 | else | |
165 | dest="$gw_ip" | |
166 | fi | |
8b88dc7f HH |
167 | |
168 | unset layer2 | |
169 | if [ -f /sys/class/net/$netif/device/layer2 ]; then | |
170 | read layer2 < /sys/class/net/$netif/device/layer2 | |
171 | fi | |
172 | ||
61b4afb4 | 173 | if [ "$layer2" != "0" ] && [ -n "$dest" ] && ! strstr "$dest" ":"; then |
9853791d HH |
174 | if command -v arping2 >/dev/null; then |
175 | arping2 -q -C 1 -c 60 -I $netif $dest || info "Resolving $dest via ARP on $netif failed" | |
176 | else | |
177 | arping -q -f -w 60 -I $netif $dest || info "Resolving $dest via ARP on $netif failed" | |
178 | fi | |
25aa3c5a | 179 | fi |
8b88dc7f HH |
180 | unset layer2 |
181 | ||
1e4a8801 | 182 | > /tmp/net.$netif.did-setup |
e7838a83 HH |
183 | [ -z "$DO_VLAN" ] && \ |
184 | [ -e /sys/class/net/$netif/address ] && \ | |
43a85a73 | 185 | > /tmp/net.$(cat /sys/class/net/$netif/address).did-setup |
25aa3c5a WW |
186 | } |
187 | ||
e173f0b3 WW |
188 | save_netinfo() { |
189 | local netif="$1" IFACES="" f="" i="" | |
190 | [ -e /tmp/net.ifaces ] && read IFACES < /tmp/net.ifaces | |
191 | # Add $netif to the front of IFACES (if it's not there already). | |
192 | set -- "$netif" | |
193 | for i in $IFACES; do [ "$i" != "$netif" ] && set -- "$@" "$i"; done | |
194 | IFACES="$*" | |
195 | for i in $IFACES; do | |
196 | for f in /tmp/dhclient.$i.*; do | |
197 | [ -f $f ] && cp -f $f /tmp/net.${f#/tmp/dhclient.} | |
198 | done | |
199 | done | |
200 | echo $IFACES > /tmp/.net.ifaces.new | |
201 | mv /tmp/.net.ifaces.new /tmp/net.ifaces | |
202 | } | |
203 | ||
25aa3c5a | 204 | set_ifname() { |
0b11ea71 | 205 | local name="$1" mac="$2" num=-1 n="" |
25aa3c5a WW |
206 | # if it's already set, return the existing name |
207 | for n in $(getargs ifname=); do | |
208 | strstr "$n" "$mac" && echo ${n%%:*} && return | |
209 | done | |
210 | # otherwise, pick a new name and use that | |
0b11ea71 HH |
211 | while :; do |
212 | num=$(($num+1)); | |
213 | [ -e /sys/class/net/$name$num ] && continue | |
214 | for n in $(getargs ifname=); do | |
215 | [ "$name$num" = "${n%%:*}" ] && continue 2 | |
216 | done | |
217 | break | |
218 | done | |
25aa3c5a WW |
219 | echo "ifname=$name$num:$mac" >> /etc/cmdline.d/45-ifname.conf |
220 | echo "$name$num" | |
221 | } | |
222 | ||
215ff169 WW |
223 | # pxelinux provides macaddr '-' separated, but we need ':' |
224 | fix_bootif() { | |
225 | local macaddr=${1} | |
226 | local IFS='-' | |
5899f2f5 | 227 | macaddr=$(printf '%s:' ${macaddr}) |
215ff169 WW |
228 | macaddr=${macaddr%:} |
229 | # strip hardware type field from pxelinux | |
230 | [ -n "${macaddr%??:??:??:??:??:??}" ] && macaddr=${macaddr#??:} | |
231 | # return macaddr with lowercase alpha characters expected by udev | |
232 | echo $macaddr | sed 'y/ABCDEF/abcdef/' | |
233 | } | |
234 | ||
25aa3c5a | 235 | ibft_to_cmdline() { |
f2cbd4cb | 236 | local iface="" |
25aa3c5a WW |
237 | modprobe -q iscsi_ibft |
238 | ( | |
239 | for iface in /sys/firmware/ibft/ethernet*; do | |
f2cbd4cb WC |
240 | local mac="" dev="" |
241 | local dhcp="" ip="" gw="" mask="" hostname="" | |
e95e48c6 | 242 | local dns1 dns2 |
f2cbd4cb | 243 | |
25aa3c5a WW |
244 | [ -e ${iface}/mac ] || continue |
245 | mac=$(read a < ${iface}/mac; echo $a) | |
d672bf16 CL |
246 | [ -z "$mac" ] && continue |
247 | dev=$(set_ifname ibft $mac) | |
0b11ea71 HH |
248 | |
249 | [ -e /tmp/net.${dev}.has_ibft_config ] && continue | |
250 | ||
c98d1756 HR |
251 | [ -e ${iface}/flags ] && flags=$(read a < ${iface}/flags; echo $a) |
252 | # Skip invalid interfaces | |
253 | (( $flags & 1 )) || continue | |
254 | # Skip interfaces not used for booting | |
255 | (( $flags & 2 )) || continue | |
9444bf61 | 256 | [ -e ${iface}/dhcp ] && dhcp=$(read a < ${iface}/dhcp; echo $a) |
c98d1756 HR |
257 | [ -e ${iface}/origin ] && origin=$(read a < ${iface}/origin; echo $a) |
258 | [ -e ${iface}/ip-addr ] && ip=$(read a < ${iface}/ip-addr; echo $a) | |
259 | ||
260 | if [ -n "$ip" ] ; then | |
261 | case "$ip" in | |
262 | *.*.*.*) | |
263 | family=ipv4 | |
264 | ;; | |
265 | *:*) | |
266 | family=ipv6 | |
267 | ;; | |
268 | esac | |
269 | fi | |
270 | if [ -n "$dhcp" ] || [ "$origin" -eq 3 ]; then | |
271 | if [ "$family" = "ipv6" ] ; then | |
272 | echo "ip=$dev:dhcp6" | |
273 | else | |
274 | echo "ip=$dev:dhcp" | |
275 | fi | |
9444bf61 | 276 | elif [ -e ${iface}/ip-addr ]; then |
0b11ea71 HH |
277 | # skip not assigned ip adresses |
278 | [ "$ip" = "0.0.0.0" ] && continue | |
9444bf61 | 279 | [ -e ${iface}/gateway ] && gw=$(read a < ${iface}/gateway; echo $a) |
c04a321b | 280 | [ "$gateway" = "0.0.0.0" ] && unset $gateway |
9444bf61 | 281 | [ -e ${iface}/subnet-mask ] && mask=$(read a < ${iface}/subnet-mask; echo $a) |
c98d1756 | 282 | [ -e ${iface}/prefix-len ] && prefix=$(read a < ${iface}/prefix-len; echo $a) |
e95e48c6 | 283 | [ -e ${iface}/primary-dns ] && dns1=$(read a < ${iface}/primary-dns; echo $a) |
c04a321b | 284 | [ "$dns1" = "0.0.0.0" ] && unset $dns1 |
e95e48c6 | 285 | [ -e ${iface}/secondary-dns ] && dns2=$(read a < ${iface}/secondary-dns; echo $a) |
c04a321b | 286 | [ "$dns2" = "0.0.0.0" ] && unset $dns2 |
9444bf61 | 287 | [ -e ${iface}/hostname ] && hostname=$(read a < ${iface}/hostname; echo $a) |
c98d1756 HR |
288 | if [ "$family" = "ipv6" ] ; then |
289 | if [ -n "$ip" ] ; then | |
1a7b71bb | 290 | ip="[$ip]" |
c98d1756 HR |
291 | [ -n "$prefix" ] || prefix=64 |
292 | ip="[${ip}/${prefix}]" | |
293 | mask= | |
294 | fi | |
295 | if [ -n "$gw" ] ; then | |
296 | gw="[${gw}]" | |
297 | fi | |
298 | fi | |
299 | if [ -n "$ip" ] && [ -n "$mask" -o -n "$prefix" ]; then | |
e95e48c6 | 300 | echo "ip=$ip::$gw:$mask:$hostname:$dev:none${dns1:+:$dns1}${dns2:+:$dns2}" |
dd82da4e HH |
301 | else |
302 | warn "${iface} does not contain a valid iBFT configuration" | |
303 | warn "ip-addr=$ip" | |
304 | warn "gateway=$gw" | |
305 | warn "subnet-mask=$mask" | |
306 | warn "hostname=$hostname" | |
307 | fi | |
25aa3c5a | 308 | else |
dd82da4e HH |
309 | info "${iface} does not contain a valid iBFT configuration" |
310 | ls -l ${iface} | vinfo | |
25aa3c5a | 311 | fi |
9444bf61 | 312 | |
f2cbd4cb | 313 | if [ -e ${iface}/vlan ]; then |
29763cb7 HH |
314 | vlan=$(read a < ${iface}/vlan; echo $a) |
315 | if [ "$vlan" -ne "0" ]; then | |
316 | case "$vlan" in | |
317 | [0-9]*) | |
318 | echo "vlan=$dev.$vlan:$dev" | |
319 | echo $mac > /tmp/net.${dev}.${vlan}.has_ibft_config | |
320 | ;; | |
321 | *) | |
322 | echo "vlan=$vlan:$dev" | |
323 | echo $mac > /tmp/net.${vlan}.has_ibft_config | |
324 | ;; | |
325 | esac | |
326 | else | |
327 | echo $mac > /tmp/net.${dev}.has_ibft_config | |
328 | fi | |
f4eb0d98 PD |
329 | else |
330 | echo $mac > /tmp/net.${dev}.has_ibft_config | |
f2cbd4cb WC |
331 | fi |
332 | ||
25aa3c5a WW |
333 | done |
334 | ) >> /etc/cmdline.d/40-ibft.conf | |
25aa3c5a | 335 | } |
ac3f1c6e HH |
336 | |
337 | parse_iscsi_root() | |
338 | { | |
339 | local v | |
340 | v=${1#iscsi:} | |
341 | ||
29763cb7 | 342 | # extract authentication info |
ac3f1c6e | 343 | case "$v" in |
29763cb7 HH |
344 | *@*:*:*:*:*) |
345 | authinfo=${v%%@*} | |
346 | v=${v#*@} | |
347 | # allow empty authinfo to allow having an @ in iscsi_target_name like this: | |
348 | # netroot=iscsi:@192.168.1.100::3260::iqn.2009-01.com.example:testdi@sk | |
349 | if [ -n "$authinfo" ]; then | |
350 | OLDIFS="$IFS" | |
351 | IFS=: | |
352 | set $authinfo | |
353 | IFS="$OLDIFS" | |
354 | if [ $# -gt 4 ]; then | |
355 | warn "Wrong authentication info in iscsi: parameter!" | |
356 | return 1 | |
357 | fi | |
358 | iscsi_username=$1 | |
359 | iscsi_password=$2 | |
360 | if [ $# -gt 2 ]; then | |
361 | iscsi_in_username=$3 | |
362 | iscsi_in_password=$4 | |
363 | fi | |
364 | fi | |
365 | ;; | |
ac3f1c6e HH |
366 | esac |
367 | ||
29763cb7 | 368 | # extract target ip |
ac3f1c6e | 369 | case "$v" in |
29763cb7 HH |
370 | [[]*[]]:*) |
371 | iscsi_target_ip=${v#[[]} | |
372 | iscsi_target_ip=${iscsi_target_ip%%[]]*} | |
373 | v=${v#[[]$iscsi_target_ip[]]:} | |
374 | ;; | |
375 | *) | |
376 | iscsi_target_ip=${v%%[:]*} | |
377 | v=${v#$iscsi_target_ip:} | |
378 | ;; | |
ac3f1c6e HH |
379 | esac |
380 | ||
36e8ce4f HH |
381 | unset iscsi_target_name |
382 | # extract target name | |
383 | case "$v" in | |
384 | *:iqn.*) | |
385 | iscsi_target_name=iqn.${v##*:iqn.} | |
386 | v=${v%:iqn.*}: | |
387 | ;; | |
388 | *:eui.*) | |
7cddd7b8 HH |
389 | iscsi_target_name=eui.${v##*:eui.} |
390 | v=${v%:eui.*}: | |
36e8ce4f HH |
391 | ;; |
392 | *:naa.*) | |
7cddd7b8 HH |
393 | iscsi_target_name=naa.${v##*:naa.} |
394 | v=${v%:naa.*}: | |
36e8ce4f HH |
395 | ;; |
396 | esac | |
397 | ||
29763cb7 | 398 | # parse the rest |
ac3f1c6e HH |
399 | OLDIFS="$IFS" |
400 | IFS=: | |
401 | set $v | |
402 | IFS="$OLDIFS" | |
403 | ||
404 | iscsi_protocol=$1; shift # ignored | |
405 | iscsi_target_port=$1; shift | |
29763cb7 | 406 | |
36e8ce4f HH |
407 | if [ -n "$iscsi_target_name" ]; then |
408 | if [ $# -eq 3 ]; then | |
409 | iscsi_iface_name=$1; shift | |
410 | fi | |
411 | if [ $# -eq 2 ]; then | |
412 | iscsi_netdev_name=$1; shift | |
413 | fi | |
414 | iscsi_lun=$1; shift | |
415 | if [ $# -ne 0 ]; then | |
416 | warn "Invalid parameter in iscsi: parameter!" | |
417 | return 1 | |
418 | fi | |
419 | return 0 | |
ac3f1c6e | 420 | fi |
29763cb7 | 421 | |
29763cb7 | 422 | |
36e8ce4f HH |
423 | if [ $# -gt 3 ] && [ -n "$1$2" ]; then |
424 | if [ -z "$3" ] || [ "$3" -ge 0 ] 2>/dev/null ; then | |
425 | iscsi_iface_name=$1; shift | |
426 | iscsi_netdev_name=$1; shift | |
427 | fi | |
ac3f1c6e | 428 | fi |
29763cb7 | 429 | |
36e8ce4f | 430 | iscsi_lun=$1; shift |
29763cb7 | 431 | |
36e8ce4f HH |
432 | iscsi_target_name=$(printf "%s:" "$@") |
433 | iscsi_target_name=${iscsi_target_name%:} | |
ac3f1c6e HH |
434 | } |
435 | ||
990e945f HH |
436 | ip_to_var() { |
437 | local v=${1}: | |
438 | local i | |
439 | set -- | |
440 | while [ -n "$v" ]; do | |
441 | if [ "${v#\[*:*:*\]:}" != "$v" ]; then | |
442 | # handle IPv6 address | |
443 | i="${v%%\]:*}" | |
444 | i="${i##\[}" | |
445 | set -- "$@" "$i" | |
446 | v=${v#\[$i\]:} | |
447 | else | |
448 | set -- "$@" "${v%%:*}" | |
449 | v=${v#*:} | |
450 | fi | |
451 | done | |
452 | ||
66bfe863 | 453 | unset ip srv gw mask hostname dev autoconf macaddr mtu dns1 dns2 |
740c46c0 HH |
454 | |
455 | if [ $# -eq 0 ]; then | |
456 | autoconf="error" | |
457 | return 0 | |
458 | fi | |
459 | ||
460 | if [ $# -eq 1 ]; then | |
461 | # format: ip={dhcp|on|any|dhcp6|auto6} | |
462 | # or | |
463 | # ip=<ipv4-address> means anaconda-style static config argument cluster | |
464 | autoconf="$1" | |
465 | ||
466 | if strstr "$autoconf" "*.*.*.*"; then | |
467 | # ip=<ipv4-address> means anaconda-style static config argument cluster: | |
468 | # ip=<ip> gateway=<gw> netmask=<nm> hostname=<host> mtu=<mtu> | |
469 | # ksdevice={link|bootif|ibft|<MAC>|<ifname>} | |
470 | ip="$autoconf" | |
471 | gw=$(getarg gateway=) | |
472 | mask=$(getarg netmask=) | |
473 | hostname=$(getarg hostname=) | |
474 | dev=$(getarg ksdevice=) | |
475 | autoconf="none" | |
476 | mtu=$(getarg mtu=) | |
477 | ||
478 | # handle special values for ksdevice | |
479 | case "$dev" in | |
480 | bootif|BOOTIF) dev=$(fix_bootif $(getarg BOOTIF=)) ;; | |
481 | link) dev="" ;; # FIXME: do something useful with this | |
482 | ibft) dev="" ;; # ignore - ibft is handled elsewhere | |
66bfe863 | 483 | esac |
740c46c0 HH |
484 | fi |
485 | return 0 | |
486 | fi | |
487 | ||
488 | if [ "$2" = "dhcp" -o "$2" = "on" -o "$2" = "any" -o "$2" = "dhcp6" -o "$2" = "auto6" ]; then | |
489 | # format: ip=<interface>:{dhcp|on|any|dhcp6|auto6}[:[<mtu>][:<macaddr>]] | |
490 | [ -n "$1" ] && dev="$1" | |
491 | [ -n "$2" ] && autoconf="$2" | |
492 | [ -n "$3" ] && mtu=$3 | |
493 | if [ -z "$5" ]; then | |
494 | macaddr="$4" | |
495 | else | |
496 | macaddr="${4}:${5}:${6}:${7}:${8}:${9}" | |
497 | fi | |
498 | return 0 | |
499 | fi | |
500 | ||
501 | # format: ip=<client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>:<interface>:{none|off|dhcp|on|any|dhcp6|auto6|ibft}:[:[<mtu>][:<macaddr>]] | |
502 | ||
503 | [ -n "$1" ] && ip=$1 | |
504 | [ -n "$2" ] && srv=$2 | |
505 | [ -n "$3" ] && gw=$3 | |
506 | [ -n "$4" ] && mask=$4 | |
507 | [ -n "$5" ] && hostname=$5 | |
508 | [ -n "$6" ] && dev=$6 | |
509 | [ -n "$7" ] && autoconf=$7 | |
510 | case "$8" in | |
511 | [0-9]*:*|[0-9]*.[0-9]*.[0-9]*.[0-9]*) | |
512 | dns1="$8" | |
513 | [ -n "$9" ] && dns2="$9" | |
66bfe863 | 514 | ;; |
740c46c0 HH |
515 | [0-9]*) |
516 | mtu="$8" | |
517 | if [ -n "${9}" -a -z "${10}" ]; then | |
518 | macaddr="${9}" | |
519 | elif [ -n "${9}" -a -n "${10}" -a -n "${11}" -a -n "${12}" -a -n "${13}" -a -n "${14}" ]; then | |
520 | macaddr="${9}:${10}:${11}:${12}:${13}:${14}" | |
521 | fi | |
c98d1756 | 522 | ;; |
740c46c0 HH |
523 | *) |
524 | if [ -n "${9}" -a -z "${10}" ]; then | |
525 | macaddr="${9}" | |
526 | elif [ -n "${9}" -a -n "${10}" -a -n "${11}" -a -n "${12}" -a -n "${13}" -a -n "${14}" ]; then | |
527 | macaddr="${9}:${10}:${11}:${12}:${13}:${14}" | |
528 | fi | |
529 | ;; | |
c98d1756 | 530 | esac |
740c46c0 | 531 | return 0 |
990e945f | 532 | } |
e7dc1e42 | 533 | |
7b46244b HH |
534 | route_to_var() { |
535 | local v=${1}: | |
536 | local i | |
537 | set -- | |
538 | while [ -n "$v" ]; do | |
539 | if [ "${v#\[*:*:*\]:}" != "$v" ]; then | |
540 | # handle IPv6 address | |
541 | i="${v%%\]:*}" | |
542 | i="${i##\[}" | |
543 | set -- "$@" "$i" | |
544 | v=${v#\[$i\]:} | |
545 | else | |
546 | set -- "$@" "${v%%:*}" | |
547 | v=${v#*:} | |
548 | fi | |
549 | done | |
550 | ||
551 | unset route_mask route_gw route_dev | |
552 | case $# in | |
553 | 2) [ -n "$1" ] && route_mask="$1"; [ -n "$2" ] && route_gw="$2" | |
554 | return 0;; | |
555 | 3) [ -n "$1" ] && route_mask="$1"; [ -n "$2" ] && route_gw="$2"; [ -n "$3" ] && route_dev="$3" | |
556 | return 0;; | |
557 | *) return 1;; | |
558 | esac | |
559 | } | |
560 | ||
e7dc1e42 HH |
561 | parse_ifname_opts() { |
562 | local IFS=: | |
563 | set $1 | |
564 | ||
565 | case $# in | |
566 | 7) | |
567 | ifname_if=$1 | |
568 | # udev requires MAC addresses to be lower case | |
569 | ifname_mac=$(echo $2:$3:$4:$5:$6:$7 | sed 'y/ABCDEF/abcdef/') | |
570 | ;; | |
571 | *) | |
572 | die "Invalid arguments for ifname=" | |
573 | ;; | |
574 | esac | |
1760dfc0 HH |
575 | |
576 | case $ifname_if in | |
577 | eth[0-9]|eth[0-9][0-9]|eth[0-9][0-9][0-9]|eth[0-9][0-9][0-9][0-9]) | |
578 | warn "ifname=$ifname_if uses the kernel name space for interfaces" | |
579 | warn "This can fail for multiple network interfaces and is discouraged!" | |
580 | warn "Please use a custom name like \"netboot\" or \"bluesocket\"" | |
581 | warn "or use biosdevname and no ifname= at all." | |
582 | ;; | |
583 | esac | |
584 | ||
e7dc1e42 | 585 | } |
efa5eb42 | 586 | |
90781679 DY |
587 | # some network driver need long time to initialize, wait before it's ready. |
588 | wait_for_if_link() { | |
589 | local cnt=0 | |
590 | local li | |
2448fbf1 HH |
591 | local timeout="$(getargs rd.net.timeout.iflink=)" |
592 | timeout=${timeout:-60} | |
593 | timeout=$(($timeout*10)) | |
594 | ||
595 | while [ $cnt -lt $timeout ]; do | |
90781679 DY |
596 | li=$(ip -o link show dev $1 2>/dev/null) |
597 | [ -n "$li" ] && return 0 | |
598 | sleep 0.1 | |
599 | cnt=$(($cnt+1)) | |
600 | done | |
601 | return 1 | |
602 | } | |
603 | ||
efa5eb42 DY |
604 | wait_for_if_up() { |
605 | local cnt=0 | |
606 | local li | |
2448fbf1 HH |
607 | local timeout="$(getargs rd.net.timeout.ifup=)" |
608 | timeout=${timeout:-20} | |
609 | timeout=$(($timeout*10)) | |
610 | ||
611 | while [ $cnt -lt $timeout ]; do | |
efa5eb42 | 612 | li=$(ip -o link show up dev $1) |
df95b100 HH |
613 | if [ -n "$li" ]; then |
614 | case "$li" in | |
615 | *\<UP*) | |
616 | return 0;; | |
617 | *\<*,UP\>*) | |
618 | return 0;; | |
619 | *\<*,UP,*\>*) | |
620 | return 0;; | |
621 | esac | |
622 | fi | |
623 | if strstr "$li" "LOWER_UP" \ | |
624 | && strstr "$li" "state UNKNOWN" \ | |
625 | && ! strstr "$li" "DORMANT"; then | |
626 | return 0 | |
42b4fc90 | 627 | fi |
efa5eb42 DY |
628 | sleep 0.1 |
629 | cnt=$(($cnt+1)) | |
630 | done | |
631 | return 1 | |
632 | } | |
633 | ||
634 | wait_for_route_ok() { | |
635 | local cnt=0 | |
2448fbf1 HH |
636 | local timeout="$(getargs rd.net.timeout.route=)" |
637 | timeout=${timeout:-20} | |
638 | timeout=$(($timeout*10)) | |
639 | ||
640 | while [ $cnt -lt $timeout ]; do | |
efa5eb42 DY |
641 | li=$(ip route show) |
642 | [ -n "$li" ] && [ -z "${li##*$1*}" ] && return 0 | |
643 | sleep 0.1 | |
644 | cnt=$(($cnt+1)) | |
645 | done | |
646 | return 1 | |
647 | } | |
b455451f | 648 | |
61b4afb4 HH |
649 | wait_for_ipv6_dad() { |
650 | local cnt=0 | |
651 | local li | |
2448fbf1 HH |
652 | local timeout="$(getargs rd.net.timeout.ipv6dad=)" |
653 | timeout=${timeout:-50} | |
654 | timeout=$(($timeout*10)) | |
655 | ||
656 | while [ $cnt -lt $timeout ]; do | |
7c5ec0f5 | 657 | li=$(ip -6 addr show dev $1 scope link) |
61b4afb4 HH |
658 | strstr "$li" "tentative" || return 0 |
659 | sleep 0.1 | |
660 | cnt=$(($cnt+1)) | |
661 | done | |
662 | return 1 | |
663 | } | |
664 | ||
f8b958dc HH |
665 | wait_for_ipv6_auto() { |
666 | local cnt=0 | |
667 | local li | |
2448fbf1 HH |
668 | local timeout="$(getargs rd.net.timeout.ipv6auto=)" |
669 | timeout=${timeout:-40} | |
670 | timeout=$(($timeout*10)) | |
671 | ||
672 | while [ $cnt -lt $timeout ]; do | |
f8b958dc | 673 | li=$(ip -6 addr show dev $1) |
7f70f811 HH |
674 | if ! strstr "$li" "tentative"; then |
675 | strstr "$li" "dynamic" && return 0 | |
676 | fi | |
f8b958dc HH |
677 | sleep 0.1 |
678 | cnt=$(($cnt+1)) | |
679 | done | |
680 | return 1 | |
681 | } | |
682 | ||
b455451f | 683 | linkup() { |
90781679 DY |
684 | wait_for_if_link $1 2>/dev/null\ |
685 | && ip link set $1 up 2>/dev/null\ | |
686 | && wait_for_if_up $1 2>/dev/null | |
b455451f DY |
687 | } |
688 | ||
cbfe65c2 | 689 | type hostname >/dev/null 2>&1 || \ |
29763cb7 HH |
690 | hostname() { |
691 | cat /proc/sys/kernel/hostname | |
cbfe65c2 | 692 | } |
7c8da72c | 693 | |
df95b100 | 694 | iface_has_carrier() { |
07d9319d | 695 | local cnt=0 |
7c8da72c HH |
696 | local interface="$1" flags="" |
697 | [ -n "$interface" ] || return 2 | |
698 | interface="/sys/class/net/$interface" | |
699 | [ -d "$interface" ] || return 2 | |
2448fbf1 HH |
700 | local timeout="$(getargs rd.net.timeout.carrier=)" |
701 | timeout=${timeout:-5} | |
702 | timeout=$(($timeout*10)) | |
703 | ||
7c8da72c | 704 | linkup "$1" |
df95b100 HH |
705 | |
706 | li=$(ip -o link show up dev $1) | |
707 | strstr "$li" "NO-CARRIER" && _no_carrier_flag=1 | |
708 | ||
2448fbf1 | 709 | while [ $cnt -lt $timeout ]; do |
df95b100 HH |
710 | if [ -n "$_no_carrier_flag" ]; then |
711 | # NO-CARRIER flag was cleared | |
712 | strstr "$li" "NO-CARRIER" || return 0 | |
713 | fi | |
714 | # double check the syscfs carrier flag | |
715 | [ -e "$interface/carrier" ] && [ "$(cat $interface/carrier)" = 1 ] && return 0 | |
07d9319d HH |
716 | sleep 0.1 |
717 | cnt=$(($cnt+1)) | |
718 | done | |
719 | return 1 | |
7c8da72c HH |
720 | } |
721 | ||
df95b100 HH |
722 | iface_has_link() { |
723 | iface_has_carrier "$@" | |
724 | } | |
725 | ||
7c8da72c HH |
726 | find_iface_with_link() { |
727 | local iface_path="" iface="" | |
728 | for iface_path in /sys/class/net/*; do | |
729 | iface=${iface_path##*/} | |
730 | str_starts "$iface" "lo" && continue | |
731 | if iface_has_link $iface; then | |
732 | echo "$iface" | |
733 | return 0 | |
734 | fi | |
735 | done | |
736 | return 1 | |
737 | } | |
fb0e5184 HH |
738 | |
739 | is_persistent_ethernet_name() { | |
3947f07d HH |
740 | local _netif="$1" |
741 | local _name_assign_type="0" | |
742 | ||
743 | [ -f "/sys/class/net/$_netif/name_assign_type" ] \ | |
744 | && _name_assign_type=$(cat "/sys/class/net/$_netif/name_assign_type") | |
745 | ||
746 | # NET_NAME_ENUM 1 | |
747 | [ "$_name_assign_type" = "1" ] && return 1 | |
748 | ||
749 | # NET_NAME_PREDICTABLE 2 | |
750 | [ "$_name_assign_type" = "2" ] && return 0 | |
751 | ||
752 | case "$_netif" in | |
fb0e5184 | 753 | # udev persistent interface names |
fb0e5184 HH |
754 | eno[0-9]|eno[0-9][0-9]|eno[0-9][0-9][0-9]*) |
755 | ;; | |
756 | ens[0-9]|ens[0-9][0-9]|ens[0-9][0-9][0-9]*) | |
757 | ;; | |
758 | enp[0-9]s[0-9]*|enp[0-9][0-9]s[0-9]*|enp[0-9][0-9][0-9]*s[0-9]*) | |
759 | ;; | |
760 | enP*p[0-9]s[0-9]*|enP*p[0-9][0-9]s[0-9]*|enP*p[0-9][0-9][0-9]*s[0-9]*) | |
761 | ;; | |
762 | # biosdevname | |
763 | em[0-9]|em[0-9][0-9]|em[0-9][0-9][0-9]*) | |
764 | ;; | |
765 | p[0-9]p[0-9]*|p[0-9][0-9]p[0-9]*|p[0-9][0-9][0-9]*p[0-9]*) | |
766 | ;; | |
767 | *) | |
768 | return 1 | |
769 | esac | |
770 | return 0 | |
771 | } | |
3947f07d HH |
772 | |
773 | is_kernel_ethernet_name() { | |
774 | local _netif="$1" | |
775 | local _name_assign_type="1" | |
776 | ||
777 | if [ -e "/sys/class/net/$_netif/name_assign_type" ]; then | |
778 | _name_assign_type=$(cat "/sys/class/net/$_netif/name_assign_type") | |
779 | ||
780 | case "$_name_assign_type" in | |
781 | 2|3|4) | |
782 | # NET_NAME_PREDICTABLE 2 | |
783 | # NET_NAME_USER 3 | |
784 | # NET_NAME_RENAMED 4 | |
785 | return 1 | |
786 | ;; | |
787 | 1|*) | |
788 | # NET_NAME_ENUM 1 | |
789 | return 0 | |
790 | ;; | |
791 | esac | |
792 | fi | |
793 | ||
794 | # fallback to error prone manual name check | |
795 | case "$_netif" in | |
796 | eth[0-9]|eth[0-9][0-9]|eth[0-9][0-9][0-9]*) | |
797 | return 0 | |
798 | ;; | |
799 | *) | |
800 | return 1 | |
801 | esac | |
802 | ||
803 | } |