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 \
16 local iface
="$1" ip
=""
17 ip
=$
(ip
-f inet addr show
$iface)
23 iface_for_remote_addr
() {
24 set -- $
(ip route get to
$1 |
sed 's/.*\bdev\b//p;q')
29 set -- $
(ip addr show to
$1)
34 local interface
="" mac
="$(echo $1 | sed 'y/ABCDEF/abcdef/')"
35 for interface
in /sys
/class
/net
/*; do
36 if [ $
(cat $interface/address
) = "$mac" ]; then
42 # get the iface name for the given identifier - either a MAC, IP, or iface name
45 ??
:??
:??
:??
:??
:??|??
-??
-??
-??
-??
-??
) iface_for_mac
$1 ;;
46 *:*:*|
*.
*.
*.
*) iface_for_ip
$1 ;;
51 # list the configured interfaces
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)
61 warn
"configured_ifaces called before udev is running"
63 [ -n "$IFACES" ] && rv
=0
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
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
85 local prefix
="" server
="" rest
=""
86 splitsep
"$1" ":" prefix server rest
88 [0-9]*\.
[0-9]*\.
[0-9]*\.
[0-9]*) echo "$server"; return 0 ;;
94 strstr
"$(ip route get $1 2>/dev/null)" " via "
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
103 rm -f -- /tmp
/net.
$netif.did-setup
104 [ -z "$DO_VLAN" ] && \
105 [ -e /sys
/class
/net
/$netif/address
] && \
106 rm -f -- /tmp
/net.$
(cat /sys
/class
/net
/$netif/address
).did-setup
107 # TODO: send "offline" uevent?
111 local netif
="$1" f
="" gw_ip
="" netroot_ip
="" iface
="" IFACES
=""
113 [ -e /tmp
/net.
$netif.did-setup
] && return
114 [ -z "$DO_VLAN" ] && \
115 [ -e /sys
/class
/net
/$netif/address
] && \
116 [ -e /tmp
/net.$
(cat /sys
/class
/net
/$netif/address
).did-setup
] && return
117 [ -e "/tmp/net.ifaces" ] && read IFACES
< /tmp
/net.ifaces
118 [ -z "$IFACES" ] && IFACES
="$netif"
119 # run the scripts written by ifup
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
124 [ -e /tmp
/net.
$netif.resolv.conf
] && \
125 awk '!array[$0]++' /tmp
/net.
$netif.resolv.conf
> /etc
/resolv.conf
126 [ -e /tmp
/net.
$netif.gw
] && .
/tmp
/net.
$netif.gw
129 for _p
in $
(getargs rd.route
); do
130 route_to_var
"$_p" ||
continue
131 [ -n "$route_dev" ] && [ "$route_dev" != "$netif" ] && continue
132 ip route add
"$route_mask" ${route_gw:+via $route_gw} ${route_dev:+dev $route_dev}
133 if strstr
"$route_mask" ":"; then
134 printf -- "%s\n" "$route_mask ${route_gw:+via $route_gw} ${route_dev:+dev $route_dev}" \
135 > /tmp
/net.route6.
"$netif"
137 printf -- "%s\n" "$route_mask ${route_gw:+via $route_gw} ${route_dev:+dev $route_dev}" \
138 > /tmp
/net.route.
"$netif"
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
147 [ -e /tmp
/net.
$netif.gw
] && .
/tmp
/net.
$netif.gw
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.
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
158 # Get the "netroot" IP (if there's an IP address in there)
159 netroot_ip
=$
(get_netroot_ip
$netroot)
161 # try netroot if it's local (or there's no gateway)
162 if ip_is_local
$netroot_ip ||
[ -z "$gw_ip" ]; then
169 if [ -f /sys
/class
/net
/$netif/device
/layer2
]; then
170 read layer2
< /sys
/class
/net
/$netif/device
/layer2
173 if [ "$layer2" != "0" ] && [ -n "$dest" ] && ! strstr
"$dest" ":"; then
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"
177 arping
-q -f -w 60 -I $netif $dest || info
"Resolving $dest via ARP on $netif failed"
182 > /tmp
/net.
$netif.did-setup
183 [ -z "$DO_VLAN" ] && \
184 [ -e /sys
/class
/net
/$netif/address
] && \
185 > /tmp
/net.$
(cat /sys
/class
/net
/$netif/address
).did-setup
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).
193 for i
in $IFACES; do [ "$i" != "$netif" ] && set -- "$@" "$i"; done
196 for f
in /tmp
/dhclient.
$i.
*; do
197 [ -f $f ] && cp -f $f /tmp
/net.
${f#/tmp/dhclient.}
200 echo $IFACES > /tmp
/.net.ifaces.new
201 mv /tmp
/.net.ifaces.new
/tmp
/net.ifaces
205 local name
="$1" mac
="$2" num
=-1 n
=""
206 # if it's already set, return the existing name
207 for n
in $
(getargs ifname
=); do
208 strstr
"$n" "$mac" && echo ${n%%:*} && return
210 # otherwise, pick a new name and use that
213 [ -e /sys
/class
/net
/$name$num ] && continue
214 for n
in $
(getargs ifname
=); do
215 [ "$name$num" = "${n%%:*}" ] && continue 2
219 echo "ifname=$name$num:$mac" >> /etc
/cmdline.d
/45-ifname.conf
223 # pxelinux provides macaddr '-' separated, but we need ':'
227 macaddr
=$
(printf '%s:' ${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/'
237 modprobe
-q iscsi_ibft
239 for iface
in /sys
/firmware
/ibft
/ethernet
*; do
241 local dhcp
="" ip
="" gw
="" mask
="" hostname
=""
244 [ -e ${iface}/mac
] ||
continue
245 mac
=$
(read a
< ${iface}/mac
; echo $a)
246 [ -z "$mac" ] && continue
247 dev
=$
(set_ifname ibft
$mac)
249 [ -e /tmp
/net.
${dev}.has_ibft_config
] && continue
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
256 [ -e ${iface}/dhcp
] && dhcp
=$
(read a
< ${iface}/dhcp
; echo $a)
257 [ -e ${iface}/origin
] && origin
=$
(read a
< ${iface}/origin
; echo $a)
258 [ -e ${iface}/ip-addr
] && ip
=$
(read a
< ${iface}/ip-addr
; echo $a)
260 if [ -n "$ip" ] ; then
270 if [ -n "$dhcp" ] ||
[ "$origin" -eq 3 ]; then
271 if [ "$family" = "ipv6" ] ; then
276 elif [ -e ${iface}/ip-addr
]; then
277 # skip not assigned ip adresses
278 [ "$ip" = "0.0.0.0" ] && continue
279 [ -e ${iface}/gateway
] && gw
=$
(read a
< ${iface}/gateway
; echo $a)
280 [ "$gateway" = "0.0.0.0" ] && unset $gateway
281 [ -e ${iface}/subnet-mask
] && mask
=$
(read a
< ${iface}/subnet-mask
; echo $a)
282 [ -e ${iface}/prefix-len
] && prefix
=$
(read a
< ${iface}/prefix-len
; echo $a)
283 [ -e ${iface}/primary-dns
] && dns1
=$
(read a
< ${iface}/primary-dns
; echo $a)
284 [ "$dns1" = "0.0.0.0" ] && unset $dns1
285 [ -e ${iface}/secondary-dns
] && dns2
=$
(read a
< ${iface}/secondary-dns
; echo $a)
286 [ "$dns2" = "0.0.0.0" ] && unset $dns2
287 [ -e ${iface}/hostname
] && hostname
=$
(read a
< ${iface}/hostname
; echo $a)
288 if [ "$family" = "ipv6" ] ; then
289 if [ -n "$ip" ] ; then
291 [ -n "$prefix" ] || prefix
=64
292 ip
="[${ip}/${prefix}]"
295 if [ -n "$gw" ] ; then
299 if [ -n "$ip" ] && [ -n "$mask" -o -n "$prefix" ]; then
300 echo "ip=$ip::$gw:$mask:$hostname:$dev:none${dns1:+:$dns1}${dns2:+:$dns2}"
302 warn
"${iface} does not contain a valid iBFT configuration"
305 warn
"subnet-mask=$mask"
306 warn
"hostname=$hostname"
309 info
"${iface} does not contain a valid iBFT configuration"
310 ls -l ${iface} | vinfo
313 if [ -e ${iface}/vlan
]; then
314 vlan
=$
(read a
< ${iface}/vlan
; echo $a)
315 if [ "$vlan" -ne "0" ]; then
318 echo "vlan=$dev.$vlan:$dev"
319 echo $mac > /tmp
/net.
${dev}.
${vlan}.has_ibft_config
322 echo "vlan=$vlan:$dev"
323 echo $mac > /tmp
/net.
${vlan}.has_ibft_config
327 echo $mac > /tmp
/net.
${dev}.has_ibft_config
330 echo $mac > /tmp
/net.
${dev}.has_ibft_config
334 ) >> /etc
/cmdline.d
/40-ibft.conf
342 # extract authentication info
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
354 if [ $# -gt 4 ]; then
355 warn
"Wrong authentication info in iscsi: parameter!"
360 if [ $# -gt 2 ]; then
371 iscsi_target_ip
=${v#[[]}
372 iscsi_target_ip
=${iscsi_target_ip%%[]]*}
373 v
=${v#[[]$iscsi_target_ip[]]:}
376 iscsi_target_ip
=${v%%[:]*}
377 v
=${v#$iscsi_target_ip:}
381 unset iscsi_target_name
382 # extract target name
385 iscsi_target_name
=iqn.
${v##*:iqn.}
389 iscsi_target_name
=eui.
${v##*:eui.}
393 iscsi_target_name
=naa.
${v##*:naa.}
404 iscsi_protocol
=$1; shift # ignored
405 iscsi_target_port
=$1; shift
407 if [ -n "$iscsi_target_name" ]; then
408 if [ $# -eq 3 ]; then
409 iscsi_iface_name
=$1; shift
411 if [ $# -eq 2 ]; then
412 iscsi_netdev_name
=$1; shift
415 if [ $# -ne 0 ]; then
416 warn
"Invalid parameter in iscsi: parameter!"
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
432 iscsi_target_name
=$
(printf "%s:" "$@")
433 iscsi_target_name
=${iscsi_target_name%:}
440 while [ -n "$v" ]; do
441 if [ "${v#\[*:*:*\]:}" != "$v" ]; then
442 # handle IPv6 address
448 set -- "$@" "${v%%:*}"
453 unset ip srv gw mask hostname dev autoconf macaddr mtu dns1 dns2
455 if [ $# -eq 0 ]; then
460 if [ $# -eq 1 ]; then
461 # format: ip={dhcp|on|any|dhcp6|auto6|either6}
463 # ip=<ipv4-address> means anaconda-style static config argument cluster
466 if strglob
"$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>}
471 gw
=$
(getarg gateway
=)
472 mask
=$
(getarg netmask
=)
473 hostname
=$
(getarg hostname
=)
474 dev
=$
(getarg ksdevice
=)
478 # handle special values for ksdevice
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
488 if [ "$2" = "dhcp" -o "$2" = "on" -o "$2" = "any" -o "$2" = "dhcp6" -o "$2" = "auto6" -o "$2" = "either6" ]; 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
496 macaddr
="${4}:${5}:${6}:${7}:${8}:${9}"
501 # format: ip=<client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>:<interface>:{none|off|dhcp|on|any|dhcp6|auto6|ibft}:[:[<mtu>][:<macaddr>]]
504 [ -n "$2" ] && srv
=$2
506 [ -n "$4" ] && mask
=$4
507 [ -n "$5" ] && hostname
=$5
508 [ -n "$6" ] && dev
=$6
509 [ -n "$7" ] && autoconf
=$7
511 [0-9]*:*|
[0-9]*.
[0-9]*.
[0-9]*.
[0-9]*)
513 [ -n "$9" ] && dns2
="$9"
517 if [ -n "${9}" -a -z "${10}" ]; then
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}"
524 if [ -n "${9}" -a -z "${10}" ]; then
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}"
538 while [ -n "$v" ]; do
539 if [ "${v#\[*:*:*\]:}" != "$v" ]; then
540 # handle IPv6 address
546 set -- "$@" "${v%%:*}"
551 unset route_mask route_gw route_dev
553 2) [ -n "$1" ] && route_mask
="$1"; [ -n "$2" ] && route_gw
="$2"
555 3) [ -n "$1" ] && route_mask
="$1"; [ -n "$2" ] && route_gw
="$2"; [ -n "$3" ] && route_dev
="$3"
561 parse_ifname_opts
() {
568 # udev requires MAC addresses to be lower case
569 ifname_mac
=$
(echo $2:$3:$4:$5:$6:$7 |
sed 'y/ABCDEF/abcdef/')
572 die
"Invalid arguments for ifname="
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."
587 # some network driver need long time to initialize, wait before it's ready.
591 local timeout
="$(getargs rd.net.timeout.iflink=)"
592 timeout
=${timeout:-60}
593 timeout
=$
(($timeout*10))
595 while [ $cnt -lt $timeout ]; do
596 li
=$
(ip link show dev
$1 2>/dev
/null
)
597 [ -n "$li" ] && return 0
607 local timeout
="$(getargs rd.net.timeout.ifup=)"
608 timeout
=${timeout:-20}
609 timeout
=$
(($timeout*10))
611 while [ $cnt -lt $timeout ]; do
612 li
=$
(ip link show up dev
$1)
613 if [ -n "$li" ]; then
623 if strstr
"$li" "LOWER_UP" \
624 && strstr
"$li" "state UNKNOWN" \
625 && ! strstr
"$li" "DORMANT"; then
634 wait_for_route_ok
() {
636 local timeout
="$(getargs rd.net.timeout.route=)"
637 timeout
=${timeout:-20}
638 timeout
=$
(($timeout*10))
640 while [ $cnt -lt $timeout ]; do
642 [ -n "$li" ] && [ -z "${li##*$1*}" ] && return 0
649 wait_for_ipv6_dad_link
() {
651 local timeout
="$(getargs rd.net.timeout.ipv6dad=)"
652 timeout
=${timeout:-50}
653 timeout
=$
(($timeout*10))
655 while [ $cnt -lt $timeout ]; do
656 [ -z "$(ip -6 addr show dev "$1" scope link tentative)" ] \
657 && [ -n "$(ip -6 route list proto ra dev "$1" | grep ^default)" ] \
659 [ -n "$(ip -6 addr show dev "$1" scope link dadfailed)" ] \
667 wait_for_ipv6_dad
() {
669 local timeout
="$(getargs rd.net.timeout.ipv6dad=)"
670 timeout
=${timeout:-50}
671 timeout
=$
(($timeout*10))
673 while [ $cnt -lt $timeout ]; do
674 [ -z "$(ip -6 addr show dev "$1" tentative)" ] \
675 && [ -n "$(ip -6 route list proto ra dev "$1" | grep ^default)" ] \
677 [ -n "$(ip -6 addr show dev "$1" dadfailed)" ] \
685 wait_for_ipv6_auto
() {
687 local timeout
="$(getargs rd.net.timeout.ipv6auto=)"
688 timeout
=${timeout:-40}
689 timeout
=$
(($timeout*10))
691 while [ $cnt -lt $timeout ]; do
692 [ -z "$(ip -6 addr show dev "$1" tentative)" ] \
693 && [ -n "$(ip -6 route list proto ra dev "$1" | grep ^default)" ] \
702 wait_for_if_link
$1 2>/dev
/null\
703 && ip link
set $1 up
2>/dev
/null\
704 && wait_for_if_up
$1 2>/dev
/null
707 type hostname
>/dev
/null
2>&1 || \
709 cat /proc
/sys
/kernel
/hostname
712 iface_has_carrier
() {
714 local interface
="$1" flags
=""
715 [ -n "$interface" ] ||
return 2
716 interface
="/sys/class/net/$interface"
717 [ -d "$interface" ] ||
return 2
718 local timeout
="$(getargs rd.net.timeout.carrier=)"
719 timeout
=${timeout:-5}
720 timeout
=$
(($timeout*10))
724 li
=$
(ip link show up dev
$1)
725 strstr
"$li" "NO-CARRIER" && _no_carrier_flag
=1
727 while [ $cnt -lt $timeout ]; do
728 if [ -n "$_no_carrier_flag" ]; then
729 li
=$
(ip link show up dev
$1)
730 # NO-CARRIER flag was cleared
731 strstr
"$li" "NO-CARRIER" ||
return 0
732 elif ! [ -e "$interface/carrier" ]; then
733 # sysfs not available and "NO-CARRIER" not displayed
736 # double check the syscfs carrier flag
737 [ -e "$interface/carrier" ] && [ "$(cat $interface/carrier)" = 1 ] && return 0
745 iface_has_carrier
"$@"
748 iface_is_enslaved
() {
750 _li
=$
(ip link show dev
$1)
751 strstr
"$_li" " master " ||
return 1
755 find_iface_with_link
() {
756 local iface_path
="" iface
=""
757 for iface_path
in /sys
/class
/net
/*; do
758 iface
=${iface_path##*/}
759 str_starts
"$iface" "lo" && continue
760 if iface_has_link
$iface; then
768 is_persistent_ethernet_name
() {
770 local _name_assign_type
="0"
772 [ -f "/sys/class/net/$_netif/name_assign_type" ] \
773 && _name_assign_type
=$
(cat "/sys/class/net/$_netif/name_assign_type")
776 [ "$_name_assign_type" = "1" ] && return 1
778 # NET_NAME_PREDICTABLE 2
779 [ "$_name_assign_type" = "2" ] && return 0
782 # udev persistent interface names
783 eno
[0-9]|eno
[0-9][0-9]|eno
[0-9][0-9][0-9]*)
785 ens
[0-9]|ens
[0-9][0-9]|ens
[0-9][0-9][0-9]*)
787 enp
[0-9]s
[0-9]*|enp
[0-9][0-9]s
[0-9]*|enp
[0-9][0-9][0-9]*s
[0-9]*)
789 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]*)
792 em
[0-9]|em
[0-9][0-9]|em
[0-9][0-9][0-9]*)
794 p
[0-9]p
[0-9]*|p
[0-9][0-9]p
[0-9]*|p
[0-9][0-9][0-9]*p
[0-9]*)
802 is_kernel_ethernet_name
() {
804 local _name_assign_type
="1"
806 if [ -e "/sys/class/net/$_netif/name_assign_type" ]; then
807 _name_assign_type
=$
(cat "/sys/class/net/$_netif/name_assign_type")
809 case "$_name_assign_type" in
811 # NET_NAME_PREDICTABLE 2
823 # fallback to error prone manual name check
825 eth
[0-9]|eth
[0-9][0-9]|eth
[0-9][0-9][0-9]*)
834 iface_get_subchannels
() {
841 for i
in /sys
/class
/net
/$_netif/device
/cdev
[0-9]*; do
842 [ -e $i ] ||
continue
843 channel
=$
(readlink
-f $i)
844 printf -- "%s" "${channel##*/},"
847 [ -n "$_subchannels" ] ||
return 1
849 printf -- "%s" ${_subchannels%,}