]> git.ipfire.org Git - thirdparty/dracut.git/blobdiff - modules.d/40network/net-lib.sh
fix: codespell
[thirdparty/dracut.git] / modules.d / 40network / net-lib.sh
index e6a9f8e5a808c05753350ddb28786f3b5d3b395b..fa09c409083bb4ca6d619ae8e6276efc84755f35 100755 (executable)
@@ -1,65 +1,72 @@
 #!/bin/sh
 
+# shellcheck disable=SC2034
+IFNETFILE="/tmp/bootnetif"
+
 is_ip() {
     echo "$1" | {
-        IFS=. read a b c d
+        IFS=. read -r a b c d
         test "$a" -ge 0 -a "$a" -le 255 \
-             -a "$b" -ge 0 -a "$b" -le 255 \
-             -a "$c" -ge 0 -a "$c" -le 255 \
-             -a "$d" -ge 0 -a "$d" -le 255 \
-             2> /dev/null
+            -a "$b" -ge 0 -a "$b" -le 255 \
+            -a "$c" -ge 0 -a "$c" -le 255 \
+            -a "$d" -ge 0 -a "$d" -le 255 \
+            2> /dev/null
     } && return 0
     return 1
 }
 
 get_ip() {
     local iface="$1" ip=""
-    ip=$(ip -o -f inet addr show $iface)
+    ip=$(ip -f inet addr show "$iface")
     ip=${ip%%/*}
     ip=${ip##* }
-    echo $ip
+    echo "$ip"
 }
 
 iface_for_remote_addr() {
-    set -- $(ip -o route get to $1)
-    echo $5
+    # shellcheck disable=SC2046
+    set -- $(ip route get to "$@" | sed 's/.*\bdev\b//p;q')
+    echo "$1"
 }
 
 iface_for_ip() {
-    set -- $(ip -o addr show to $1)
-    echo $2
+    # shellcheck disable=SC2046
+    set -- $(ip addr show to "$@")
+    echo "${2%:}"
 }
 
 iface_for_mac() {
-    local interface="" mac="$(echo $1 | sed 'y/ABCDEF/abcdef/')"
+    local interface=""
+    local mac
+    mac="$(echo "$@" | sed 'y/ABCDEF/abcdef/')"
     for interface in /sys/class/net/*; do
-        if [ $(cat $interface/address) = "$mac" ]; then
-            echo ${interface##*/}
+        if [ "$(cat "$interface"/address)" = "$mac" ]; then
+            echo "${interface##*/}"
         fi
     done
 }
 
 # get the iface name for the given identifier - either a MAC, IP, or iface name
 iface_name() {
-    case $1 in
-        ??:??:??:??:??:??|??-??-??-??-??-??) iface_for_mac $1 ;;
-        *:*:*|*.*.*.*) iface_for_ip $1 ;;
-        *) echo $1 ;;
+    case "$1" in
+        ??:??:??:??:??:?? | ??-??-??-??-??-??) iface_for_mac "$1" ;;
+        *:*:* | *.*.*.*) iface_for_ip "$1" ;;
+        *) echo "$1" ;;
     esac
 }
 
 # list the configured interfaces
 configured_ifaces() {
     local IFACES="" iface_id="" rv=1
-    [ -e "/tmp/net.ifaces" ] && read IFACES < /tmp/net.ifaces
+    [ -e "/tmp/net.ifaces" ] && read -r IFACES < /tmp/net.ifaces
     if { pidof udevd || pidof systemd-udevd; } > /dev/null; then
         for iface_id in $IFACES; do
-            echo $(iface_name $iface_id)
+            printf "%s\n" "$(iface_name "$iface_id")"
             rv=0
         done
     else
         warn "configured_ifaces called before udev is running"
-        echo $IFACES
+        echo "$IFACES"
         [ -n "$IFACES" ] && rv=0
     fi
     return $rv
@@ -67,63 +74,74 @@ configured_ifaces() {
 
 all_ifaces_up() {
     local iface="" IFACES=""
-    [ -e "/tmp/net.ifaces" ] && read IFACES < /tmp/net.ifaces
+    [ -e "/tmp/net.ifaces" ] && read -r IFACES < /tmp/net.ifaces
     for iface in $IFACES; do
-        [ -e /tmp/net.$iface.up ] || return 1
+        [ -e /tmp/net."$iface".up ] || return 1
     done
 }
 
 all_ifaces_setup() {
     local iface="" IFACES=""
-    [ -e "/tmp/net.ifaces" ] && read IFACES < /tmp/net.ifaces
+    [ -e "/tmp/net.ifaces" ] && read -r IFACES < /tmp/net.ifaces
     for iface in $IFACES; do
-        [ -e /tmp/net.$iface.did-setup ] || return 1
+        [ -e /tmp/net."$iface".did-setup ] || return 1
     done
 }
 
 get_netroot_ip() {
     local prefix="" server="" rest=""
-    splitsep "$1" ":" prefix server rest
+    splitsep ":" "$1" prefix server rest
     case $server in
-        [0-9]*\.[0-9]*\.[0-9]*\.[0-9]*) echo "$server"; return 0 ;;
+        [0-9]*\.[0-9]*\.[0-9]*\.[0-9]*)
+            echo "$server"
+            return 0
+            ;;
     esac
     return 1
 }
 
 ip_is_local() {
-    strstr "$(ip route get $1 2>/dev/null)" " via "
+    li=$(ip route get "$@" 2> /dev/null)
+    if [ -n "$li" ]; then
+        strstr "$li" " via " || return 0
+    fi
+    return 1
 }
 
 ifdown() {
     local netif="$1"
     # ip down/flush ensures that routing info goes away as well
-    ip link set $netif down
-    ip addr flush dev $netif
+    ip link set "$netif" down
+    ip addr flush dev "$netif"
     echo "#empty" > /etc/resolv.conf
-    rm -f -- /tmp/net.$netif.did-setup
-    [ -z "$DO_VLAN" ] && \
-       [ -e /sys/class/net/$netif/address ] && \
-        rm -f -- /tmp/net.$(cat /sys/class/net/$netif/address).did-setup
+    rm -f -- /tmp/net."$netif".did-setup
+    [ -z "$DO_VLAN" ] \
+        && [ -e /sys/class/net/"$netif"/address ] \
+        && rm -f -- "/tmp/net.$(cat /sys/class/net/"$netif"/address).did-setup"
     # TODO: send "offline" uevent?
 }
 
 setup_net() {
     local netif="$1" f="" gw_ip="" netroot_ip="" iface="" IFACES=""
     local _p
-    [ -e /tmp/net.$netif.did-setup ] && return
-    [ -z "$DO_VLAN" ] && \
-       [ -e /sys/class/net/$netif/address ] && \
-        [ -e /tmp/net.$(cat /sys/class/net/$netif/address).did-setup ] && return
-    [ -e "/tmp/net.ifaces" ] && read IFACES < /tmp/net.ifaces
+    [ -e /tmp/net."$netif".did-setup ] && return
+    [ -z "$DO_VLAN" ] \
+        && [ -e /sys/class/net/"$netif"/address ] \
+        && [ -e "/tmp/net.$(cat /sys/class/net/"$netif"/address).did-setup" ] && return
+    [ -e "/tmp/net.ifaces" ] && read -r IFACES < /tmp/net.ifaces
     [ -z "$IFACES" ] && IFACES="$netif"
     # run the scripts written by ifup
-    [ -e /tmp/net.$netif.hostname ]      && . /tmp/net.$netif.hostname
-    [ -e /tmp/net.$netif.override ]      && . /tmp/net.$netif.override
-    [ -e /tmp/dhclient.$netif.dhcpopts ] && . /tmp/dhclient.$netif.dhcpopts
+    # shellcheck disable=SC1090
+    [ -e /tmp/net."$netif".hostname ] && . /tmp/net."$netif".hostname
+    # shellcheck disable=SC1090
+    [ -e /tmp/net."$netif".override ] && . /tmp/net."$netif".override
+    # shellcheck disable=SC1090
+    [ -e /tmp/dhclient."$netif".dhcpopts ] && . /tmp/dhclient."$netif".dhcpopts
     # set up resolv.conf
-    [ -e /tmp/net.$netif.resolv.conf ] && \
-        awk '!array[$0]++' /tmp/net.$netif.resolv.conf > /etc/resolv.conf
-    [ -e /tmp/net.$netif.gw ]            && . /tmp/net.$netif.gw
+    [ -e /tmp/net."$netif".resolv.conf ] \
+        && awk '!array[$0]++' /tmp/net."$netif".resolv.conf > /etc/resolv.conf
+    # shellcheck disable=SC1090
+    [ -e /tmp/net."$netif".gw ] && . /tmp/net."$netif".gw
 
     # add static route
     for _p in $(getargs rd.route); do
@@ -144,7 +162,8 @@ setup_net() {
     #     RTNETLINK answers: Network is unreachable
     # Replace the default route again after static routes to cover
     # this scenario.
-    [ -e /tmp/net.$netif.gw ]            && . /tmp/net.$netif.gw
+    # shellcheck disable=SC1090
+    [ -e /tmp/net."$netif".gw ] && . /tmp/net."$netif".gw
 
     # Handle STP Timeout: arping the default gateway.
     # (or the root server, if a) it's local or b) there's no gateway.)
@@ -156,48 +175,48 @@ setup_net() {
     [ -n "$gw" ] && gw_ip=$gw
 
     # Get the "netroot" IP (if there's an IP address in there)
-    netroot_ip=$(get_netroot_ip $netroot)
+    netroot_ip=$(get_netroot_ip "$netroot")
 
     # try netroot if it's local (or there's no gateway)
-    if ip_is_local $netroot_ip || [ -z "$gw_ip" ]; then
+    if ip_is_local "$netroot_ip" || [ -z "$gw_ip" ]; then
         dest="$netroot_ip"
     else
         dest="$gw_ip"
     fi
 
     unset layer2
-    if [ -f /sys/class/net/$netif/device/layer2 ]; then
-        read layer2 < /sys/class/net/$netif/device/layer2
+    if [ -f /sys/class/net/"$netif"/device/layer2 ]; then
+        read -r layer2 < /sys/class/net/"$netif"/device/layer2
     fi
 
     if [ "$layer2" != "0" ] && [ -n "$dest" ] && ! strstr "$dest" ":"; then
-        if command -v arping2 >/dev/null; then
-            arping2 -q -C 1 -c 60 -I $netif $dest || info "Resolving $dest via ARP on $netif failed"
+        if command -v arping2 > /dev/null; then
+            arping2 -q -C 1 -c 60 -I "$netif" "$dest" || info "Resolving $dest via ARP on $netif failed"
         else
-            arping -q -f -w 60 -I $netif $dest || info "Resolving $dest via ARP on $netif failed"
+            arping -q -f -w 60 -I "$netif" "$dest" || info "Resolving $dest via ARP on $netif failed"
         fi
     fi
     unset layer2
 
-    > /tmp/net.$netif.did-setup
-    [ -z "$DO_VLAN" ] && \
-       [ -e /sys/class/net/$netif/address ] && \
-        > /tmp/net.$(cat /sys/class/net/$netif/address).did-setup
+    : > /tmp/net."$netif".did-setup
+    [ -z "$DO_VLAN" ] \
+        && [ -e /sys/class/net/"$netif"/address ] \
+        && : > "/tmp/net.$(cat /sys/class/net/"$netif"/address).did-setup"
 }
 
 save_netinfo() {
     local netif="$1" IFACES="" f="" i=""
-    [ -e /tmp/net.ifaces ] && read IFACES < /tmp/net.ifaces
+    [ -e /tmp/net.ifaces ] && read -r IFACES < /tmp/net.ifaces
     # Add $netif to the front of IFACES (if it's not there already).
     set -- "$netif"
     for i in $IFACES; do [ "$i" != "$netif" ] && set -- "$@" "$i"; done
     IFACES="$*"
     for i in $IFACES; do
-        for f in /tmp/dhclient.$i.*; do
-            [ -f $f ] && cp -f $f /tmp/net.${f#/tmp/dhclient.}
+        for f in "/tmp/dhclient.$i."*; do
+            [ -f "$f" ] && cp -f "$f" /tmp/net."${f#/tmp/dhclient.}"
         done
     done
-    echo $IFACES > /tmp/.net.ifaces.new
+    echo "$IFACES" > /tmp/.net.ifaces.new
     mv /tmp/.net.ifaces.new /tmp/net.ifaces
 }
 
@@ -205,31 +224,34 @@ set_ifname() {
     local name="$1" mac="$2" num=-1 n=""
     # if it's already set, return the existing name
     for n in $(getargs ifname=); do
-        strstr "$n" "$mac" && echo ${n%%:*} && return
+        strstr "$n" "$mac" && echo "${n%%:*}" && return
     done
+    [ ! -f "/tmp/set_ifname_$name" ] || read -r num < "/tmp/set_ifname_$name"
     # otherwise, pick a new name and use that
     while :; do
-        num=$(($num+1));
-        [ -e /sys/class/net/$name$num ] && continue
+        num=$((num + 1))
+        [ -e /sys/class/net/"$name"$num ] && continue
         for n in $(getargs ifname=); do
             [ "$name$num" = "${n%%:*}" ] && continue 2
         done
         break
     done
     echo "ifname=$name$num:$mac" >> /etc/cmdline.d/45-ifname.conf
+    echo "$num" > "/tmp/set_ifname_$name"
     echo "$name$num"
 }
 
 # pxelinux provides macaddr '-' separated, but we need ':'
 fix_bootif() {
-    local macaddr=${1}
+    local macaddr="${1}"
     local IFS='-'
+    # shellcheck disable=SC2086
     macaddr=$(printf '%s:' ${macaddr})
     macaddr=${macaddr%:}
     # strip hardware type field from pxelinux
     [ -n "${macaddr%??:??:??:??:??:??}" ] && macaddr=${macaddr#??:}
     # return macaddr with lowercase alpha characters expected by udev
-    echo $macaddr | sed 'y/ABCDEF/abcdef/'
+    echo "$macaddr" | sed 'y/ABCDEF/abcdef/'
 }
 
 ibft_to_cmdline() {
@@ -241,23 +263,25 @@ ibft_to_cmdline() {
             local dhcp="" ip="" gw="" mask="" hostname=""
             local dns1 dns2
 
-            [ -e ${iface}/mac ] || continue
-            mac=$(read a < ${iface}/mac; echo $a)
+            [ -e "${iface}"/mac ] || continue
+            read -r mac < "${iface}"/mac
             [ -z "$mac" ] && continue
-            dev=$(set_ifname ibft $mac)
+            dev=$(set_ifname ibft "$mac")
 
-            [ -e /tmp/net.${dev}.has_ibft_config ] && continue
+            [ -e /tmp/net."${dev}".has_ibft_config ] && continue
 
-            [ -e ${iface}/flags ] && flags=$(read a < ${iface}/flags; echo $a)
+            [ -e "${iface}"/flags ] && read -r flags < "${iface}"/flags
             # Skip invalid interfaces
-            (( $flags & 1 )) || continue
-            # Skip interfaces not used for booting
-            (( $flags & 2 )) || continue
-            [ -e ${iface}/dhcp ] && dhcp=$(read a < ${iface}/dhcp; echo $a)
-            [ -e ${iface}/origin ] && origin=$(read a < ${iface}/origin; echo $a)
-            [ -e ${iface}/ip-addr ] && ip=$(read a < ${iface}/ip-addr; echo $a)
-
-            if [ -n "$ip" ] ; then
+            awk -- 'BEGIN { exit (!and('"$flags"',1)) }' || continue
+            # Skip interfaces not used for booting unless using multipath
+            if ! getargbool 0 rd.iscsi.mp; then
+                awk -- 'BEGIN { exit (!and('"$flags"',2)) }' || continue
+            fi
+            [ -e "${iface}"/dhcp ] && read -r dhcp < "${iface}"/dhcp
+            [ -e "${iface}"/origin ] && read -r origin < "${iface}"/origin
+            [ -e "${iface}"/ip-addr ] && read -r ip < "${iface}"/ip-addr
+
+            if [ -n "$ip" ]; then
                 case "$ip" in
                     *.*.*.*)
                         family=ipv4
@@ -268,31 +292,30 @@ ibft_to_cmdline() {
                 esac
             fi
             if [ -n "$dhcp" ] || [ "$origin" -eq 3 ]; then
-                if [ "$family" = "ipv6" ] ; then
+                if [ "$family" = "ipv6" ]; then
                     echo "ip=$dev:dhcp6"
                 else
                     echo "ip=$dev:dhcp"
                 fi
-            elif [ -e ${iface}/ip-addr ]; then
-                # skip not assigned ip adresses
+            elif [ -e "${iface}"/ip-addr ]; then
+                # skip not assigned ip addresses
                 [ "$ip" = "0.0.0.0" ] && continue
-                [ -e ${iface}/gateway ] && gw=$(read a < ${iface}/gateway; echo $a)
-                [ "$gateway" = "0.0.0.0" ] && unset $gateway
-                [ -e ${iface}/subnet-mask ] && mask=$(read a < ${iface}/subnet-mask; echo $a)
-                [ -e ${iface}/prefix-len ] && prefix=$(read a < ${iface}/prefix-len; echo $a)
-                [ -e ${iface}/primary-dns ] && dns1=$(read a < ${iface}/primary-dns; echo $a)
-                [ "$dns1" = "0.0.0.0" ] && unset $dns1
-                [ -e ${iface}/secondary-dns ] && dns2=$(read a < ${iface}/secondary-dns; echo $a)
-                [ "$dns2" = "0.0.0.0" ] && unset $dns2
-                [ -e ${iface}/hostname ] && hostname=$(read a < ${iface}/hostname; echo $a)
-                if [ "$family" = "ipv6" ] ; then
-                    if [ -n "$ip" ] ; then
-                        ip="[$ip]"
-                        [ -n "$prefix" ] || prefix=64
-                        ip="[${ip}/${prefix}]"
-                        mask=
+                [ -e "${iface}"/gateway ] && read -r gw < "${iface}"/gateway
+                [ "$gw" = "0.0.0.0" ] && unset gw
+                [ -e "${iface}"/subnet-mask ] && read -r mask < "${iface}"/subnet-mask
+                [ -e "${iface}"/prefix-len ] && read -r prefix < "${iface}"/prefix-len
+                [ -e "${iface}"/primary-dns ] && read -r dns1 < "${iface}"/primary-dns
+                [ "$dns1" = "0.0.0.0" ] && unset dns1
+                [ -e "${iface}"/secondary-dns ] && read -r dns2 < "${iface}"/secondary-dns
+                [ "$dns2" = "0.0.0.0" ] && unset dns
+                [ -e "${iface}"/hostname ] && read -r hostname < "${iface}"/hostname
+                if [ "$family" = "ipv6" ]; then
+                    if [ -n "$ip" ]; then
+                        [ -n "$prefix" ] || prefix=128
+                        ip="[${ip}]"
+                        mask=$prefix
                     fi
-                    if [ -n "$gw" ] ; then
+                    if [ -n "$gw" ]; then
                         gw="[${gw}]"
                     fi
                 fi
@@ -307,35 +330,35 @@ ibft_to_cmdline() {
                 fi
             else
                 info "${iface} does not contain a valid iBFT configuration"
-                ls -l ${iface} | vinfo
+                # shellcheck disable=SC2012
+                ls -l "${iface}" | vinfo
             fi
 
-            if [ -e ${iface}/vlan ]; then
-                vlan=$(read a < ${iface}/vlan; echo $a)
+            if [ -e "${iface}"/vlan ]; then
+                read -r vlan < "${iface}"/vlan
                 if [ "$vlan" -ne "0" ]; then
                     case "$vlan" in
                         [0-9]*)
                             echo "vlan=$dev.$vlan:$dev"
-                            echo $mac > /tmp/net.${dev}.${vlan}.has_ibft_config
+                            echo "$mac" > /tmp/net."${dev}"."${vlan}".has_ibft_config
                             ;;
                         *)
                             echo "vlan=$vlan:$dev"
-                            echo $mac > /tmp/net.${vlan}.has_ibft_config
+                            echo "$mac" > /tmp/net."${vlan}".has_ibft_config
                             ;;
                     esac
                 else
-                    echo $mac > /tmp/net.${dev}.has_ibft_config
+                    echo "$mac" > /tmp/net."${dev}".has_ibft_config
                 fi
             else
-                echo $mac > /tmp/net.${dev}.has_ibft_config
+                echo "$mac" > /tmp/net."${dev}".has_ibft_config
             fi
 
         done
     ) >> /etc/cmdline.d/40-ibft.conf
 }
 
-parse_iscsi_root()
-{
+parse_iscsi_root() {
     local v
     v=${1#iscsi:}
 
@@ -349,6 +372,7 @@ parse_iscsi_root()
             if [ -n "$authinfo" ]; then
                 OLDIFS="$IFS"
                 IFS=:
+                # shellcheck disable=SC2086
                 set $authinfo
                 IFS="$OLDIFS"
                 if [ $# -gt 4 ]; then
@@ -369,12 +393,13 @@ parse_iscsi_root()
     case "$v" in
         [[]*[]]:*)
             iscsi_target_ip=${v#[[]}
-                iscsi_target_ip=${iscsi_target_ip%%[]]*}
-            v=${v#[[]$iscsi_target_ip[]]:}
+            iscsi_target_ip=${iscsi_target_ip%%[]]*}
+            # shellcheck disable=SC1087
+            v=${v#[[]"$iscsi_target_ip"[]]:}
             ;;
         *)
             iscsi_target_ip=${v%%[:]*}
-            v=${v#$iscsi_target_ip:}
+            v=${v#"$iscsi_target_ip":}
             ;;
     esac
 
@@ -398,20 +423,26 @@ parse_iscsi_root()
     # parse the rest
     OLDIFS="$IFS"
     IFS=:
+    # shellcheck disable=SC2086
     set $v
     IFS="$OLDIFS"
 
-    iscsi_protocol=$1; shift # ignored
-    iscsi_target_port=$1; shift
+    iscsi_protocol=$1
+    shift # ignored
+    iscsi_target_port=$1
+    shift
 
     if [ -n "$iscsi_target_name" ]; then
         if [ $# -eq 3 ]; then
-            iscsi_iface_name=$1; shift
+            iscsi_iface_name=$1
+            shift
         fi
         if [ $# -eq 2 ]; then
-            iscsi_netdev_name=$1; shift
+            iscsi_netdev_name=$1
+            shift
         fi
-        iscsi_lun=$1; shift
+        iscsi_lun=$1
+        shift
         if [ $# -ne 0 ]; then
             warn "Invalid parameter in iscsi: parameter!"
             return 1
@@ -419,22 +450,24 @@ parse_iscsi_root()
         return 0
     fi
 
-
     if [ $# -gt 3 ] && [ -n "$1$2" ]; then
-        if [ -z "$3" ] || [ "$3" -ge 0 ]  2>/dev/null ; then
-            iscsi_iface_name=$1; shift
-            iscsi_netdev_name=$1; shift
+        if [ -z "$3" ] || [ "$3" -ge 0 ] 2> /dev/null; then
+            iscsi_iface_name=$1
+            shift
+            iscsi_netdev_name=$1
+            shift
         fi
     fi
 
-    iscsi_lun=$1; shift
+    iscsi_lun=$1
+    shift
 
     iscsi_target_name=$(printf "%s:" "$@")
     iscsi_target_name=${iscsi_target_name%:}
 }
 
 ip_to_var() {
-    local v=${1}:
+    local v="${1}":
     local i
     set --
     while [ -n "$v" ]; do
@@ -443,7 +476,7 @@ ip_to_var() {
             i="${v%%\]:*}"
             i="${i##\[}"
             set -- "$@" "$i"
-            v=${v#\[$i\]:}
+            v=${v#\["$i"\]:}
         else
             set -- "$@" "${v%%:*}"
             v=${v#*:}
@@ -458,7 +491,7 @@ ip_to_var() {
     fi
 
     if [ $# -eq 1 ]; then
-        # format: ip={dhcp|on|any|dhcp6|auto6|either6}
+        # format: ip={dhcp|on|any|dhcp6|auto6|either6|single-dhcp}
         # or
         #         ip=<ipv4-address> means anaconda-style static config argument cluster
         autoconf="$1"
@@ -477,7 +510,7 @@ ip_to_var() {
 
             # handle special values for ksdevice
             case "$dev" in
-                bootif|BOOTIF) dev=$(fix_bootif $(getarg BOOTIF=)) ;;
+                bootif | BOOTIF) dev=$(fix_bootif "$(getarg BOOTIF=)") ;;
                 link) dev="" ;; # FIXME: do something useful with this
                 ibft) dev="" ;; # ignore - ibft is handled elsewhere
             esac
@@ -508,7 +541,7 @@ ip_to_var() {
     [ -n "$6" ] && dev=$6
     [ -n "$7" ] && autoconf=$7
     case "$8" in
-        [0-9]*:*|[0-9]*.[0-9]*.[0-9]*.[0-9]*)
+        [0-9a-fA-F]*:* | [0-9]*.[0-9]*.[0-9]*.[0-9]*)
             dns1="$8"
             [ -n "$9" ] && dns2="$9"
             ;;
@@ -526,13 +559,13 @@ ip_to_var() {
             elif [ -n "${9}" -a -n "${10}" -a -n "${11}" -a -n "${12}" -a -n "${13}" -a -n "${14}" ]; then
                 macaddr="${9}:${10}:${11}:${12}:${13}:${14}"
             fi
-           ;;
+            ;;
     esac
     return 0
 }
 
 route_to_var() {
-    local v=${1}:
+    local v="${1}":
     local i
     set --
     while [ -n "$v" ]; do
@@ -541,7 +574,7 @@ route_to_var() {
             i="${v%%\]:*}"
             i="${i##\[}"
             set -- "$@" "$i"
-            v=${v#\[$i\]:}
+            v=${v#\["$i"\]:}
         else
             set -- "$@" "${v%%:*}"
             v=${v#*:}
@@ -550,23 +583,36 @@ route_to_var() {
 
     unset route_mask route_gw route_dev
     case $# in
-        2)  [ -n "$1" ] && route_mask="$1"; [ -n "$2" ] && route_gw="$2"
-            return 0;;
-        3)  [ -n "$1" ] && route_mask="$1"; [ -n "$2" ] && route_gw="$2"; [ -n "$3" ] && route_dev="$3"
-            return 0;;
-        *)  return 1;;
+        2)
+            [ -n "$1" ] && route_mask="$1"
+            [ -n "$2" ] && route_gw="$2"
+            return 0
+            ;;
+        3)
+            [ -n "$1" ] && route_mask="$1"
+            [ -n "$2" ] && route_gw="$2"
+            [ -n "$3" ] && route_dev="$3"
+            return 0
+            ;;
+        *) return 1 ;;
     esac
 }
 
 parse_ifname_opts() {
     local IFS=:
-    set $1
+    # shellcheck disable=SC2086
+    set -- $1
 
     case $# in
         7)
             ifname_if=$1
             # udev requires MAC addresses to be lower case
-            ifname_mac=$(echo $2:$3:$4:$5:$6:$7 | sed 'y/ABCDEF/abcdef/')
+            ifname_mac=$(echo "$2:$3:$4:$5:$6:$7" | sed 'y/ABCDEF/abcdef/')
+            ;;
+        21)
+            ifname_if=$1
+            # udev requires MAC addresses to be lower case
+            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/')
             ;;
         *)
             die "Invalid arguments for ifname="
@@ -574,10 +620,10 @@ parse_ifname_opts() {
     esac
 
     case $ifname_if in
-        eth[0-9]|eth[0-9][0-9]|eth[0-9][0-9][0-9]|eth[0-9][0-9][0-9][0-9])
+        eth[0-9] | eth[0-9][0-9] | eth[0-9][0-9][0-9] | eth[0-9][0-9][0-9][0-9])
             warn "ifname=$ifname_if uses the kernel name space for interfaces"
             warn "This can fail for multiple network interfaces and is discouraged!"
-            warn "Please use a custom name like \"netboot\" or \"bluesocket\""
+            warn 'Please use a custom name like "netboot" or "bluesocket"'
             warn "or use biosdevname and no ifname= at all."
             ;;
     esac
@@ -588,15 +634,16 @@ parse_ifname_opts() {
 wait_for_if_link() {
     local cnt=0
     local li
-    local timeout="$(getargs rd.net.timeout.iflink=)"
+    local timeout
+    timeout=$(getargs rd.net.timeout.iflink=)
     timeout=${timeout:-60}
-    timeout=$(($timeout*10))
+    timeout=$((timeout * 10))
 
     while [ $cnt -lt $timeout ]; do
-        li=$(ip -o link show dev $1 2>/dev/null)
+        li=$(ip link show dev "$@" 2> /dev/null)
         [ -n "$li" ] && return 0
         sleep 0.1
-        cnt=$(($cnt+1))
+        cnt=$((cnt + 1))
     done
     return 1
 }
@@ -604,139 +651,147 @@ wait_for_if_link() {
 wait_for_if_up() {
     local cnt=0
     local li
-    local timeout="$(getargs rd.net.timeout.ifup=)"
+    local timeout
+    timeout=$(getargs rd.net.timeout.ifup=)
     timeout=${timeout:-20}
-    timeout=$(($timeout*10))
+    timeout=$((timeout * 10))
 
     while [ $cnt -lt $timeout ]; do
-        li=$(ip -o link show up dev $1)
+        li=$(ip link show up dev "$@")
         if [ -n "$li" ]; then
             case "$li" in
                 *\<UP*)
-                    return 0;;
+                    return 0
+                    ;;
                 *\<*,UP\>*)
-                    return 0;;
+                    return 0
+                    ;;
                 *\<*,UP,*\>*)
-                    return 0;;
+                    return 0
+                    ;;
             esac
         fi
         if strstr "$li" "LOWER_UP" \
-                && strstr "$li" "state UNKNOWN" \
-                && ! strstr "$li" "DORMANT"; then
+            && strstr "$li" "state UNKNOWN" \
+            && ! strstr "$li" "DORMANT"; then
             return 0
         fi
         sleep 0.1
-        cnt=$(($cnt+1))
+        cnt=$((cnt + 1))
     done
     return 1
 }
 
 wait_for_route_ok() {
     local cnt=0
-    local timeout="$(getargs rd.net.timeout.route=)"
+    local timeout
+    timeout=$(getargs rd.net.timeout.route=)
     timeout=${timeout:-20}
-    timeout=$(($timeout*10))
+    timeout=$((timeout * 10))
 
     while [ $cnt -lt $timeout ]; do
         li=$(ip route show)
-        [ -n "$li" ] && [ -z "${li##*$1*}" ] && return 0
+        [ -n "$li" ] && [ -z "${li##*"$1"*}" ] && return 0
         sleep 0.1
-        cnt=$(($cnt+1))
+        cnt=$((cnt + 1))
     done
     return 1
 }
 
 wait_for_ipv6_dad_link() {
     local cnt=0
-    local timeout="$(getargs rd.net.timeout.ipv6dad=)"
+    local timeout
+    timeout=$(getargs rd.net.timeout.ipv6dad=)
     timeout=${timeout:-50}
-    timeout=$(($timeout*10))
+    timeout=$((timeout * 10))
 
     while [ $cnt -lt $timeout ]; do
-        [ -z "$(ip -6 addr show dev "$1" scope link tentative)" ] \
-            && [ -n "$(ip -6 route list proto ra dev "$1" | grep ^default)" ] \
+        [ -n "$(ip -6 addr show dev "$@" scope link)" ] \
+            && [ -z "$(ip -6 addr show dev "$@" scope link tentative)" ] \
             && return 0
-        [ -n "$(ip -6 addr show dev "$1" scope link dadfailed)" ] \
+        [ -n "$(ip -6 addr show dev "$@" scope link dadfailed)" ] \
             && return 1
         sleep 0.1
-        cnt=$(($cnt+1))
+        cnt=$((cnt + 1))
     done
     return 1
 }
 
 wait_for_ipv6_dad() {
     local cnt=0
-    local timeout="$(getargs rd.net.timeout.ipv6dad=)"
+    local timeout
+    timeout=$(getargs rd.net.timeout.ipv6dad=)
     timeout=${timeout:-50}
-    timeout=$(($timeout*10))
+    timeout=$((timeout * 10))
 
     while [ $cnt -lt $timeout ]; do
-        [ -z "$(ip -6 addr show dev "$1" tentative)" ] \
-            && [ -n "$(ip -6 route list proto ra dev "$1" | grep ^default)" ] \
+        [ -n "$(ip -6 addr show dev "$@")" ] \
+            && [ -z "$(ip -6 addr show dev "$@" tentative)" ] \
             && return 0
-        [ -n "$(ip -6 addr show dev "$1" dadfailed)" ] \
+        [ -n "$(ip -6 addr show dev "$@" dadfailed)" ] \
             && return 1
         sleep 0.1
-        cnt=$(($cnt+1))
+        cnt=$((cnt + 1))
     done
     return 1
 }
 
 wait_for_ipv6_auto() {
     local cnt=0
-    local timeout="$(getargs rd.net.timeout.ipv6auto=)"
+    local timeout
+    timeout=$(getargs rd.net.timeout.ipv6auto=)
     timeout=${timeout:-40}
-    timeout=$(($timeout*10))
+    timeout=$((timeout * 10))
 
     while [ $cnt -lt $timeout ]; do
-        [ -z "$(ip -6 addr show dev "$1" tentative)" ] \
-            && [ -n "$(ip -6 route list proto ra dev "$1" | grep ^default)" ] \
+        [ -z "$(ip -6 addr show dev "$@" tentative)" ] \
+            && { ip -6 route list proto ra dev "$@" | grep -q ^default; } \
             && return 0
         sleep 0.1
-        cnt=$(($cnt+1))
+        cnt=$((cnt + 1))
     done
     return 1
 }
 
 linkup() {
-    wait_for_if_link $1 2>/dev/null\
-     && ip link set $1 up 2>/dev/null\
-     && wait_for_if_up $1 2>/dev/null
+    wait_for_if_link "$@" 2> /dev/null && ip link set "$@" up 2> /dev/null && wait_for_if_up "$@" 2> /dev/null
 }
 
-type hostname >/dev/null 2>&1 || \
-    hostname() {
-    cat /proc/sys/kernel/hostname
-}
+type hostname > /dev/null 2>&1 \
+    || hostname() {
+        cat /proc/sys/kernel/hostname
+    }
 
 iface_has_carrier() {
     local cnt=0
-    local interface="$1" flags=""
-    [ -n "$interface" ] || return 2
-    interface="/sys/class/net/$interface"
-    [ -d "$interface" ] || return 2
-    local timeout="$(getargs rd.net.timeout.carrier=)"
-    timeout=${timeout:-5}
-    timeout=$(($timeout*10))
+    local iface="$1" flags=""
+    local timeout
+    local iface_sys_path
+    [ -n "$iface" ] || return 2
+    iface_sys_path="/sys/class/net/$iface"
+    [ -d "$iface_sys_path" ] || return 2
+    timeout=$(getargs rd.net.timeout.carrier=)
+    timeout=${timeout:-10}
+    timeout=$((timeout * 10))
 
     linkup "$1"
 
-    li=$(ip -o link show up dev $1)
+    li=$(ip link show up dev "$iface")
     strstr "$li" "NO-CARRIER" && _no_carrier_flag=1
 
     while [ $cnt -lt $timeout ]; do
         if [ -n "$_no_carrier_flag" ]; then
-            li=$(ip -o link show up dev $1)
+            li=$(ip link show up dev "$iface")
             # NO-CARRIER flag was cleared
             strstr "$li" "NO-CARRIER" || return 0
-        elif ! [ -e "$interface/carrier" ]; then
+        elif ! [ -e "$iface_sys_path/carrier" ]; then
             # sysfs not available and "NO-CARRIER" not displayed
             return 0
         fi
         # double check the syscfs carrier flag
-        [ -e "$interface/carrier" ] && [ "$(cat $interface/carrier)" = 1 ] && return 0
+        [ -e "$iface_sys_path/carrier" ] && [ "$(cat "$iface_sys_path"/carrier)" = 1 ] && return 0
         sleep 0.1
-        cnt=$(($cnt+1))
+        cnt=$((cnt + 1))
     done
     return 1
 }
@@ -747,8 +802,8 @@ iface_has_link() {
 
 iface_is_enslaved() {
     local _li
-    _li=$(ip -o link show dev $1)
-    strstr "$li" " master " || return 1
+    _li=$(ip link show dev "$@")
+    strstr "$_li" " master " || return 1
     return 0
 }
 
@@ -757,7 +812,7 @@ find_iface_with_link() {
     for iface_path in /sys/class/net/*; do
         iface=${iface_path##*/}
         str_starts "$iface" "lo" && continue
-        if iface_has_link $iface; then
+        if iface_has_link "$iface"; then
             echo "$iface"
             return 0
         fi
@@ -770,7 +825,7 @@ is_persistent_ethernet_name() {
     local _name_assign_type="0"
 
     [ -f "/sys/class/net/$_netif/name_assign_type" ] \
-        && _name_assign_type=$(cat "/sys/class/net/$_netif/name_assign_type")
+        && read -r _name_assign_type < "/sys/class/net/$_netif/name_assign_type" 2> /dev/null
 
     # NET_NAME_ENUM 1
     [ "$_name_assign_type" = "1" ] && return 1
@@ -780,21 +835,22 @@ is_persistent_ethernet_name() {
 
     case "$_netif" in
         # udev persistent interface names
-        eno[0-9]|eno[0-9][0-9]|eno[0-9][0-9][0-9]*)
-            ;;
-        ens[0-9]|ens[0-9][0-9]|ens[0-9][0-9][0-9]*)
-            ;;
-        enp[0-9]s[0-9]*|enp[0-9][0-9]s[0-9]*|enp[0-9][0-9][0-9]*s[0-9]*)
-            ;;
-        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]*)
-            ;;
-        # biosdevname
-        em[0-9]|em[0-9][0-9]|em[0-9][0-9][0-9]*)
-            ;;
-        p[0-9]p[0-9]*|p[0-9][0-9]p[0-9]*|p[0-9][0-9][0-9]*p[0-9]*)
-            ;;
+        eno[0-9] | eno[0-9][0-9] | eno[0-9][0-9][0-9]*) ;;
+
+        ens[0-9] | ens[0-9][0-9] | ens[0-9][0-9][0-9]*) ;;
+
+        enp[0-9]s[0-9]* | enp[0-9][0-9]s[0-9]* | enp[0-9][0-9][0-9]*s[0-9]*) ;;
+
+        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]*) ;;
+
+            # biosdevname
+        em[0-9] | em[0-9][0-9] | em[0-9][0-9][0-9]*) ;;
+
+        p[0-9]p[0-9]* | p[0-9][0-9]p[0-9]* | p[0-9][0-9][0-9]*p[0-9]*) ;;
+
         *)
             return 1
+            ;;
     esac
     return 0
 }
@@ -804,16 +860,16 @@ is_kernel_ethernet_name() {
     local _name_assign_type="1"
 
     if [ -e "/sys/class/net/$_netif/name_assign_type" ]; then
-        _name_assign_type=$(cat "/sys/class/net/$_netif/name_assign_type")
+        read -r _name_assign_type < "/sys/class/net/$_netif/name_assign_type"
 
         case "$_name_assign_type" in
-            2|3|4)
+            2 | 3 | 4)
                 # NET_NAME_PREDICTABLE 2
                 # NET_NAME_USER 3
                 # NET_NAME_RENAMED 4
                 return 1
                 ;;
-            1|*)
+            1 | *)
                 # NET_NAME_ENUM 1
                 return 0
                 ;;
@@ -822,11 +878,12 @@ is_kernel_ethernet_name() {
 
     # fallback to error prone manual name check
     case "$_netif" in
-        eth[0-9]|eth[0-9][0-9]|eth[0-9][0-9][0-9]*)
+        eth[0-9] | eth[0-9][0-9] | eth[0-9][0-9][0-9]*)
             return 0
             ;;
         *)
             return 1
+            ;;
     esac
 
 }
@@ -838,13 +895,13 @@ iface_get_subchannels() {
     _netif="$1"
 
     _subchannels=$({
-                      for i in /sys/class/net/$_netif/device/cdev[0-9]*; do
-                          [ -e $i ] || continue
-                          channel=$(readlink -f $i)
-                          printf -- "%s" "${channel##*/},"
-                      done
-                  })
+        for i in /sys/class/net/"$_netif"/device/cdev[0-9]*; do
+            [ -e "$i" ] || continue
+            channel=$(readlink -f "$i")
+            printf -- "%s" "${channel##*/},"
+        done
+    })
     [ -n "$_subchannels" ] || return 1
 
-    printf -- "%s" ${_subchannels%,}
+    printf -- "%s" "${_subchannels%,}"
 }