]>
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 | 396 | iscsi_target_ip=${iscsi_target_ip%%[]]*} |
08b63a25 | 397 | v=${v#[[]"$iscsi_target_ip"[]]:} |
29763cb7 HH |
398 | ;; |
399 | *) | |
400 | iscsi_target_ip=${v%%[:]*} | |
08b63a25 | 401 | v=${v#"$iscsi_target_ip":} |
29763cb7 | 402 | ;; |
ac3f1c6e HH |
403 | esac |
404 | ||
36e8ce4f HH |
405 | unset iscsi_target_name |
406 | # extract target name | |
407 | case "$v" in | |
408 | *:iqn.*) | |
409 | iscsi_target_name=iqn.${v##*:iqn.} | |
410 | v=${v%:iqn.*}: | |
411 | ;; | |
412 | *:eui.*) | |
7cddd7b8 HH |
413 | iscsi_target_name=eui.${v##*:eui.} |
414 | v=${v%:eui.*}: | |
36e8ce4f HH |
415 | ;; |
416 | *:naa.*) | |
7cddd7b8 HH |
417 | iscsi_target_name=naa.${v##*:naa.} |
418 | v=${v%:naa.*}: | |
36e8ce4f HH |
419 | ;; |
420 | esac | |
421 | ||
29763cb7 | 422 | # parse the rest |
ac3f1c6e HH |
423 | OLDIFS="$IFS" |
424 | IFS=: | |
e25c536c | 425 | # shellcheck disable=SC2086 |
ac3f1c6e HH |
426 | set $v |
427 | IFS="$OLDIFS" | |
428 | ||
9a52c3fd HH |
429 | iscsi_protocol=$1 |
430 | shift # ignored | |
431 | iscsi_target_port=$1 | |
432 | shift | |
29763cb7 | 433 | |
36e8ce4f HH |
434 | if [ -n "$iscsi_target_name" ]; then |
435 | if [ $# -eq 3 ]; then | |
9a52c3fd HH |
436 | iscsi_iface_name=$1 |
437 | shift | |
36e8ce4f HH |
438 | fi |
439 | if [ $# -eq 2 ]; then | |
9a52c3fd HH |
440 | iscsi_netdev_name=$1 |
441 | shift | |
36e8ce4f | 442 | fi |
9a52c3fd HH |
443 | iscsi_lun=$1 |
444 | shift | |
36e8ce4f HH |
445 | if [ $# -ne 0 ]; then |
446 | warn "Invalid parameter in iscsi: parameter!" | |
447 | return 1 | |
448 | fi | |
449 | return 0 | |
ac3f1c6e | 450 | fi |
29763cb7 | 451 | |
36e8ce4f | 452 | if [ $# -gt 3 ] && [ -n "$1$2" ]; then |
9a52c3fd HH |
453 | if [ -z "$3" ] || [ "$3" -ge 0 ] 2> /dev/null; then |
454 | iscsi_iface_name=$1 | |
455 | shift | |
456 | iscsi_netdev_name=$1 | |
457 | shift | |
36e8ce4f | 458 | fi |
ac3f1c6e | 459 | fi |
29763cb7 | 460 | |
9a52c3fd HH |
461 | iscsi_lun=$1 |
462 | shift | |
29763cb7 | 463 | |
36e8ce4f HH |
464 | iscsi_target_name=$(printf "%s:" "$@") |
465 | iscsi_target_name=${iscsi_target_name%:} | |
ac3f1c6e HH |
466 | } |
467 | ||
990e945f | 468 | ip_to_var() { |
08b63a25 | 469 | local v="${1}": |
990e945f HH |
470 | local i |
471 | set -- | |
472 | while [ -n "$v" ]; do | |
473 | if [ "${v#\[*:*:*\]:}" != "$v" ]; then | |
474 | # handle IPv6 address | |
475 | i="${v%%\]:*}" | |
476 | i="${i##\[}" | |
477 | set -- "$@" "$i" | |
08b63a25 | 478 | v=${v#\["$i"\]:} |
990e945f HH |
479 | else |
480 | set -- "$@" "${v%%:*}" | |
481 | v=${v#*:} | |
482 | fi | |
483 | done | |
484 | ||
66bfe863 | 485 | unset ip srv gw mask hostname dev autoconf macaddr mtu dns1 dns2 |
740c46c0 HH |
486 | |
487 | if [ $# -eq 0 ]; then | |
488 | autoconf="error" | |
489 | return 0 | |
490 | fi | |
491 | ||
492 | if [ $# -eq 1 ]; then | |
4026cd3b | 493 | # format: ip={dhcp|on|any|dhcp6|auto6|either6|single-dhcp} |
740c46c0 HH |
494 | # or |
495 | # ip=<ipv4-address> means anaconda-style static config argument cluster | |
496 | autoconf="$1" | |
497 | ||
b2616b52 | 498 | if strglob "$autoconf" "*.*.*.*"; then |
740c46c0 HH |
499 | # ip=<ipv4-address> means anaconda-style static config argument cluster: |
500 | # ip=<ip> gateway=<gw> netmask=<nm> hostname=<host> mtu=<mtu> | |
501 | # ksdevice={link|bootif|ibft|<MAC>|<ifname>} | |
502 | ip="$autoconf" | |
503 | gw=$(getarg gateway=) | |
504 | mask=$(getarg netmask=) | |
505 | hostname=$(getarg hostname=) | |
506 | dev=$(getarg ksdevice=) | |
507 | autoconf="none" | |
508 | mtu=$(getarg mtu=) | |
509 | ||
510 | # handle special values for ksdevice | |
511 | case "$dev" in | |
e25c536c | 512 | bootif | BOOTIF) dev=$(fix_bootif "$(getarg BOOTIF=)") ;; |
740c46c0 HH |
513 | link) dev="" ;; # FIXME: do something useful with this |
514 | ibft) dev="" ;; # ignore - ibft is handled elsewhere | |
66bfe863 | 515 | esac |
740c46c0 HH |
516 | fi |
517 | return 0 | |
518 | fi | |
519 | ||
67354eeb | 520 | if [ "$2" = "dhcp" -o "$2" = "on" -o "$2" = "any" -o "$2" = "dhcp6" -o "$2" = "auto6" -o "$2" = "either6" ]; then |
740c46c0 HH |
521 | # format: ip=<interface>:{dhcp|on|any|dhcp6|auto6}[:[<mtu>][:<macaddr>]] |
522 | [ -n "$1" ] && dev="$1" | |
523 | [ -n "$2" ] && autoconf="$2" | |
524 | [ -n "$3" ] && mtu=$3 | |
525 | if [ -z "$5" ]; then | |
526 | macaddr="$4" | |
527 | else | |
528 | macaddr="${4}:${5}:${6}:${7}:${8}:${9}" | |
529 | fi | |
530 | return 0 | |
531 | fi | |
532 | ||
533 | # format: ip=<client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>:<interface>:{none|off|dhcp|on|any|dhcp6|auto6|ibft}:[:[<mtu>][:<macaddr>]] | |
534 | ||
535 | [ -n "$1" ] && ip=$1 | |
536 | [ -n "$2" ] && srv=$2 | |
537 | [ -n "$3" ] && gw=$3 | |
538 | [ -n "$4" ] && mask=$4 | |
539 | [ -n "$5" ] && hostname=$5 | |
540 | [ -n "$6" ] && dev=$6 | |
541 | [ -n "$7" ] && autoconf=$7 | |
542 | case "$8" in | |
9a52c3fd | 543 | [0-9a-fA-F]*:* | [0-9]*.[0-9]*.[0-9]*.[0-9]*) |
740c46c0 HH |
544 | dns1="$8" |
545 | [ -n "$9" ] && dns2="$9" | |
66bfe863 | 546 | ;; |
740c46c0 HH |
547 | [0-9]*) |
548 | mtu="$8" | |
549 | if [ -n "${9}" -a -z "${10}" ]; then | |
550 | macaddr="${9}" | |
551 | elif [ -n "${9}" -a -n "${10}" -a -n "${11}" -a -n "${12}" -a -n "${13}" -a -n "${14}" ]; then | |
552 | macaddr="${9}:${10}:${11}:${12}:${13}:${14}" | |
553 | fi | |
c98d1756 | 554 | ;; |
740c46c0 HH |
555 | *) |
556 | if [ -n "${9}" -a -z "${10}" ]; then | |
557 | macaddr="${9}" | |
558 | elif [ -n "${9}" -a -n "${10}" -a -n "${11}" -a -n "${12}" -a -n "${13}" -a -n "${14}" ]; then | |
559 | macaddr="${9}:${10}:${11}:${12}:${13}:${14}" | |
560 | fi | |
9a52c3fd | 561 | ;; |
c98d1756 | 562 | esac |
740c46c0 | 563 | return 0 |
990e945f | 564 | } |
e7dc1e42 | 565 | |
7b46244b | 566 | route_to_var() { |
08b63a25 | 567 | local v="${1}": |
7b46244b HH |
568 | local i |
569 | set -- | |
570 | while [ -n "$v" ]; do | |
571 | if [ "${v#\[*:*:*\]:}" != "$v" ]; then | |
572 | # handle IPv6 address | |
573 | i="${v%%\]:*}" | |
574 | i="${i##\[}" | |
575 | set -- "$@" "$i" | |
08b63a25 | 576 | v=${v#\["$i"\]:} |
7b46244b HH |
577 | else |
578 | set -- "$@" "${v%%:*}" | |
579 | v=${v#*:} | |
580 | fi | |
581 | done | |
582 | ||
583 | unset route_mask route_gw route_dev | |
584 | case $# in | |
9a52c3fd HH |
585 | 2) |
586 | [ -n "$1" ] && route_mask="$1" | |
587 | [ -n "$2" ] && route_gw="$2" | |
588 | return 0 | |
589 | ;; | |
590 | 3) | |
591 | [ -n "$1" ] && route_mask="$1" | |
592 | [ -n "$2" ] && route_gw="$2" | |
593 | [ -n "$3" ] && route_dev="$3" | |
594 | return 0 | |
595 | ;; | |
596 | *) return 1 ;; | |
7b46244b HH |
597 | esac |
598 | } | |
599 | ||
e7dc1e42 HH |
600 | parse_ifname_opts() { |
601 | local IFS=: | |
e25c536c HH |
602 | # shellcheck disable=SC2086 |
603 | set -- $1 | |
e7dc1e42 HH |
604 | |
605 | case $# in | |
606 | 7) | |
607 | ifname_if=$1 | |
608 | # udev requires MAC addresses to be lower case | |
e25c536c | 609 | ifname_mac=$(echo "$2:$3:$4:$5:$6:$7" | sed 'y/ABCDEF/abcdef/') |
e7dc1e42 | 610 | ;; |
376ce851 TB |
611 | 21) |
612 | ifname_if=$1 | |
613 | # udev requires MAC addresses to be lower case | |
e25c536c | 614 | 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 | 615 | ;; |
e7dc1e42 HH |
616 | *) |
617 | die "Invalid arguments for ifname=" | |
618 | ;; | |
619 | esac | |
1760dfc0 HH |
620 | |
621 | case $ifname_if in | |
9a52c3fd | 622 | 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 |
623 | warn "ifname=$ifname_if uses the kernel name space for interfaces" |
624 | warn "This can fail for multiple network interfaces and is discouraged!" | |
75d758e8 | 625 | warn 'Please use a custom name like "netboot" or "bluesocket"' |
1760dfc0 HH |
626 | warn "or use biosdevname and no ifname= at all." |
627 | ;; | |
628 | esac | |
629 | ||
e7dc1e42 | 630 | } |
efa5eb42 | 631 | |
90781679 DY |
632 | # some network driver need long time to initialize, wait before it's ready. |
633 | wait_for_if_link() { | |
634 | local cnt=0 | |
635 | local li | |
e25c536c HH |
636 | local timeout |
637 | timeout=$(getargs rd.net.timeout.iflink=) | |
2448fbf1 | 638 | timeout=${timeout:-60} |
75d758e8 | 639 | timeout=$((timeout * 10)) |
2448fbf1 HH |
640 | |
641 | while [ $cnt -lt $timeout ]; do | |
e25c536c | 642 | li=$(ip link show dev "$@" 2> /dev/null) |
90781679 DY |
643 | [ -n "$li" ] && return 0 |
644 | sleep 0.1 | |
75d758e8 | 645 | cnt=$((cnt + 1)) |
90781679 DY |
646 | done |
647 | return 1 | |
648 | } | |
649 | ||
efa5eb42 DY |
650 | wait_for_if_up() { |
651 | local cnt=0 | |
652 | local li | |
e25c536c HH |
653 | local timeout |
654 | timeout=$(getargs rd.net.timeout.ifup=) | |
2448fbf1 | 655 | timeout=${timeout:-20} |
75d758e8 | 656 | timeout=$((timeout * 10)) |
2448fbf1 HH |
657 | |
658 | while [ $cnt -lt $timeout ]; do | |
e25c536c | 659 | li=$(ip link show up dev "$@") |
df95b100 HH |
660 | if [ -n "$li" ]; then |
661 | case "$li" in | |
662 | *\<UP*) | |
9a52c3fd HH |
663 | return 0 |
664 | ;; | |
df95b100 | 665 | *\<*,UP\>*) |
9a52c3fd HH |
666 | return 0 |
667 | ;; | |
df95b100 | 668 | *\<*,UP,*\>*) |
9a52c3fd HH |
669 | return 0 |
670 | ;; | |
df95b100 HH |
671 | esac |
672 | fi | |
673 | if strstr "$li" "LOWER_UP" \ | |
9a52c3fd HH |
674 | && strstr "$li" "state UNKNOWN" \ |
675 | && ! strstr "$li" "DORMANT"; then | |
df95b100 | 676 | return 0 |
42b4fc90 | 677 | fi |
efa5eb42 | 678 | sleep 0.1 |
75d758e8 | 679 | cnt=$((cnt + 1)) |
efa5eb42 DY |
680 | done |
681 | return 1 | |
682 | } | |
683 | ||
684 | wait_for_route_ok() { | |
685 | local cnt=0 | |
e25c536c HH |
686 | local timeout |
687 | timeout=$(getargs rd.net.timeout.route=) | |
2448fbf1 | 688 | timeout=${timeout:-20} |
75d758e8 | 689 | timeout=$((timeout * 10)) |
2448fbf1 HH |
690 | |
691 | while [ $cnt -lt $timeout ]; do | |
efa5eb42 | 692 | li=$(ip route show) |
08b63a25 | 693 | [ -n "$li" ] && [ -z "${li##*"$1"*}" ] && return 0 |
efa5eb42 | 694 | sleep 0.1 |
75d758e8 | 695 | cnt=$((cnt + 1)) |
efa5eb42 DY |
696 | done |
697 | return 1 | |
698 | } | |
b455451f | 699 | |
811a070d HH |
700 | wait_for_ipv6_dad_link() { |
701 | local cnt=0 | |
e25c536c HH |
702 | local timeout |
703 | timeout=$(getargs rd.net.timeout.ipv6dad=) | |
811a070d | 704 | timeout=${timeout:-50} |
75d758e8 | 705 | timeout=$((timeout * 10)) |
811a070d HH |
706 | |
707 | while [ $cnt -lt $timeout ]; do | |
e25c536c HH |
708 | [ -n "$(ip -6 addr show dev "$@" scope link)" ] \ |
709 | && [ -z "$(ip -6 addr show dev "$@" scope link tentative)" ] \ | |
811a070d | 710 | && return 0 |
e25c536c | 711 | [ -n "$(ip -6 addr show dev "$@" scope link dadfailed)" ] \ |
811a070d HH |
712 | && return 1 |
713 | sleep 0.1 | |
75d758e8 | 714 | cnt=$((cnt + 1)) |
811a070d HH |
715 | done |
716 | return 1 | |
717 | } | |
718 | ||
61b4afb4 HH |
719 | wait_for_ipv6_dad() { |
720 | local cnt=0 | |
e25c536c HH |
721 | local timeout |
722 | timeout=$(getargs rd.net.timeout.ipv6dad=) | |
2448fbf1 | 723 | timeout=${timeout:-50} |
75d758e8 | 724 | timeout=$((timeout * 10)) |
2448fbf1 HH |
725 | |
726 | while [ $cnt -lt $timeout ]; do | |
e25c536c HH |
727 | [ -n "$(ip -6 addr show dev "$@")" ] \ |
728 | && [ -z "$(ip -6 addr show dev "$@" tentative)" ] \ | |
811a070d | 729 | && return 0 |
e25c536c | 730 | [ -n "$(ip -6 addr show dev "$@" dadfailed)" ] \ |
811a070d | 731 | && return 1 |
61b4afb4 | 732 | sleep 0.1 |
75d758e8 | 733 | cnt=$((cnt + 1)) |
61b4afb4 HH |
734 | done |
735 | return 1 | |
736 | } | |
737 | ||
f8b958dc HH |
738 | wait_for_ipv6_auto() { |
739 | local cnt=0 | |
e25c536c HH |
740 | local timeout |
741 | timeout=$(getargs rd.net.timeout.ipv6auto=) | |
2448fbf1 | 742 | timeout=${timeout:-40} |
75d758e8 | 743 | timeout=$((timeout * 10)) |
2448fbf1 HH |
744 | |
745 | while [ $cnt -lt $timeout ]; do | |
e25c536c HH |
746 | [ -z "$(ip -6 addr show dev "$@" tentative)" ] \ |
747 | && { ip -6 route list proto ra dev "$@" | grep -q ^default; } \ | |
e8dc8c4d | 748 | && return 0 |
f8b958dc | 749 | sleep 0.1 |
75d758e8 | 750 | cnt=$((cnt + 1)) |
f8b958dc HH |
751 | done |
752 | return 1 | |
753 | } | |
754 | ||
b455451f | 755 | linkup() { |
e25c536c | 756 | wait_for_if_link "$@" 2> /dev/null && ip link set "$@" up 2> /dev/null && wait_for_if_up "$@" 2> /dev/null |
b455451f DY |
757 | } |
758 | ||
9a52c3fd HH |
759 | type hostname > /dev/null 2>&1 \ |
760 | || hostname() { | |
761 | cat /proc/sys/kernel/hostname | |
762 | } | |
7c8da72c | 763 | |
df95b100 | 764 | iface_has_carrier() { |
07d9319d | 765 | local cnt=0 |
36af0518 | 766 | local iface="$1" flags="" |
e25c536c | 767 | local timeout |
36af0518 HH |
768 | local iface_sys_path |
769 | [ -n "$iface" ] || return 2 | |
770 | iface_sys_path="/sys/class/net/$iface" | |
771 | [ -d "$iface_sys_path" ] || return 2 | |
e25c536c | 772 | timeout=$(getargs rd.net.timeout.carrier=) |
579fbb9f | 773 | timeout=${timeout:-10} |
75d758e8 | 774 | timeout=$((timeout * 10)) |
2448fbf1 | 775 | |
7c8da72c | 776 | linkup "$1" |
df95b100 | 777 | |
36af0518 | 778 | li=$(ip link show up dev "$iface") |
df95b100 HH |
779 | strstr "$li" "NO-CARRIER" && _no_carrier_flag=1 |
780 | ||
2448fbf1 | 781 | while [ $cnt -lt $timeout ]; do |
df95b100 | 782 | if [ -n "$_no_carrier_flag" ]; then |
36af0518 | 783 | li=$(ip link show up dev "$iface") |
df95b100 HH |
784 | # NO-CARRIER flag was cleared |
785 | strstr "$li" "NO-CARRIER" || return 0 | |
36af0518 | 786 | elif ! [ -e "$iface_sys_path/carrier" ]; then |
efecf0a9 HH |
787 | # sysfs not available and "NO-CARRIER" not displayed |
788 | return 0 | |
df95b100 HH |
789 | fi |
790 | # double check the syscfs carrier flag | |
36af0518 | 791 | [ -e "$iface_sys_path/carrier" ] && [ "$(cat "$iface_sys_path"/carrier)" = 1 ] && return 0 |
07d9319d | 792 | sleep 0.1 |
75d758e8 | 793 | cnt=$((cnt + 1)) |
07d9319d HH |
794 | done |
795 | return 1 | |
7c8da72c HH |
796 | } |
797 | ||
df95b100 HH |
798 | iface_has_link() { |
799 | iface_has_carrier "$@" | |
800 | } | |
801 | ||
f6e3b59e HH |
802 | iface_is_enslaved() { |
803 | local _li | |
e25c536c | 804 | _li=$(ip link show dev "$@") |
8084f3f6 | 805 | strstr "$_li" " master " || return 1 |
f6e3b59e HH |
806 | return 0 |
807 | } | |
808 | ||
7c8da72c HH |
809 | find_iface_with_link() { |
810 | local iface_path="" iface="" | |
811 | for iface_path in /sys/class/net/*; do | |
812 | iface=${iface_path##*/} | |
813 | str_starts "$iface" "lo" && continue | |
e25c536c | 814 | if iface_has_link "$iface"; then |
7c8da72c HH |
815 | echo "$iface" |
816 | return 0 | |
817 | fi | |
818 | done | |
819 | return 1 | |
820 | } | |
fb0e5184 HH |
821 | |
822 | is_persistent_ethernet_name() { | |
3947f07d HH |
823 | local _netif="$1" |
824 | local _name_assign_type="0" | |
825 | ||
826 | [ -f "/sys/class/net/$_netif/name_assign_type" ] \ | |
28f37724 | 827 | && read -r _name_assign_type < "/sys/class/net/$_netif/name_assign_type" 2> /dev/null |
3947f07d HH |
828 | |
829 | # NET_NAME_ENUM 1 | |
830 | [ "$_name_assign_type" = "1" ] && return 1 | |
831 | ||
832 | # NET_NAME_PREDICTABLE 2 | |
833 | [ "$_name_assign_type" = "2" ] && return 0 | |
834 | ||
835 | case "$_netif" in | |
fb0e5184 | 836 | # udev persistent interface names |
9a52c3fd HH |
837 | eno[0-9] | eno[0-9][0-9] | eno[0-9][0-9][0-9]*) ;; |
838 | ||
839 | ens[0-9] | ens[0-9][0-9] | ens[0-9][0-9][0-9]*) ;; | |
840 | ||
841 | enp[0-9]s[0-9]* | enp[0-9][0-9]s[0-9]* | enp[0-9][0-9][0-9]*s[0-9]*) ;; | |
842 | ||
843 | 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]*) ;; | |
844 | ||
845 | # biosdevname | |
846 | em[0-9] | em[0-9][0-9] | em[0-9][0-9][0-9]*) ;; | |
847 | ||
848 | p[0-9]p[0-9]* | p[0-9][0-9]p[0-9]* | p[0-9][0-9][0-9]*p[0-9]*) ;; | |
849 | ||
fb0e5184 HH |
850 | *) |
851 | return 1 | |
9a52c3fd | 852 | ;; |
fb0e5184 HH |
853 | esac |
854 | return 0 | |
855 | } | |
3947f07d HH |
856 | |
857 | is_kernel_ethernet_name() { | |
858 | local _netif="$1" | |
859 | local _name_assign_type="1" | |
860 | ||
861 | if [ -e "/sys/class/net/$_netif/name_assign_type" ]; then | |
28f37724 | 862 | read -r _name_assign_type < "/sys/class/net/$_netif/name_assign_type" |
3947f07d HH |
863 | |
864 | case "$_name_assign_type" in | |
9a52c3fd | 865 | 2 | 3 | 4) |
3947f07d HH |
866 | # NET_NAME_PREDICTABLE 2 |
867 | # NET_NAME_USER 3 | |
868 | # NET_NAME_RENAMED 4 | |
869 | return 1 | |
870 | ;; | |
9a52c3fd | 871 | 1 | *) |
3947f07d HH |
872 | # NET_NAME_ENUM 1 |
873 | return 0 | |
874 | ;; | |
875 | esac | |
876 | fi | |
877 | ||
878 | # fallback to error prone manual name check | |
879 | case "$_netif" in | |
9a52c3fd | 880 | eth[0-9] | eth[0-9][0-9] | eth[0-9][0-9][0-9]*) |
3947f07d HH |
881 | return 0 |
882 | ;; | |
883 | *) | |
884 | return 1 | |
9a52c3fd | 885 | ;; |
3947f07d HH |
886 | esac |
887 | ||
888 | } | |
041e49ee HH |
889 | |
890 | iface_get_subchannels() { | |
891 | local _netif | |
892 | local _subchannels | |
893 | ||
894 | _netif="$1" | |
895 | ||
896 | _subchannels=$({ | |
e25c536c HH |
897 | for i in /sys/class/net/"$_netif"/device/cdev[0-9]*; do |
898 | [ -e "$i" ] || continue | |
899 | channel=$(readlink -f "$i") | |
9a52c3fd HH |
900 | printf -- "%s" "${channel##*/}," |
901 | done | |
902 | }) | |
041e49ee HH |
903 | [ -n "$_subchannels" ] || return 1 |
904 | ||
e25c536c | 905 | printf -- "%s" "${_subchannels%,}" |
041e49ee | 906 | } |