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