]> git.ipfire.org Git - thirdparty/dracut.git/blobdiff - modules.d/40network/net-lib.sh
network: skip already enslaved interfaces
[thirdparty/dracut.git] / modules.d / 40network / net-lib.sh
index 005ad1bb82b1438f73a709bf616a0067cfbd1090..964ed3ab81576d5c70f4262c62ef64bc02da084f 100755 (executable)
@@ -101,7 +101,8 @@ ifdown() {
     ip addr flush dev $netif
     echo "#empty" > /etc/resolv.conf
     rm -f -- /tmp/net.$netif.did-setup
-    [ -e /sys/class/net/$netif/address ] && \
+    [ -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?
 }
@@ -110,7 +111,8 @@ setup_net() {
     local netif="$1" f="" gw_ip="" netroot_ip="" iface="" IFACES=""
     local _p
     [ -e /tmp/net.$netif.did-setup ] && return
-    [ -e /sys/class/net/$netif/address ] && \
+    [ -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
     [ -z "$IFACES" ] && IFACES="$netif"
@@ -169,12 +171,17 @@ setup_net() {
     fi
 
     if [ "$layer2" != "0" ] && [ -n "$dest" ] && ! strstr "$dest" ":"; then
-        arping -q -f -w 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"
+        fi
     fi
     unset layer2
 
     > /tmp/net.$netif.did-setup
-    [ -e /sys/class/net/$netif/address ] && \
+    [ -z "$DO_VLAN" ] && \
+       [ -e /sys/class/net/$netif/address ] && \
         > /tmp/net.$(cat /sys/class/net/$netif/address).did-setup
 }
 
@@ -241,23 +248,55 @@ ibft_to_cmdline() {
 
             [ -e /tmp/net.${dev}.has_ibft_config ] && continue
 
+            [ -e ${iface}/flags ] && flags=$(read a < ${iface}/flags; echo $a)
+            # 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)
-
-            if [ -n "$dhcp" ]; then
-                echo "ip=$dev:dhcp"
+            [ -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
+                case "$ip" in
+                    *.*.*.*)
+                        family=ipv4
+                        ;;
+                    *:*)
+                        family=ipv6
+                        ;;
+                esac
+            fi
+            if [ -n "$dhcp" ] || [ "$origin" -eq 3 ]; then
+                if [ "$family" = "ipv6" ] ; then
+                    echo "ip=$dev:dhcp6"
+                else
+                    echo "ip=$dev:dhcp"
+                fi
             elif [ -e ${iface}/ip-addr ]; then
-                [ -e ${iface}/ip-addr ] && ip=$(read a < ${iface}/ip-addr; echo $a)
                 # skip not assigned ip adresses
                 [ "$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 [ -n "$ip" ] && [ -n "$mask" ]; then
+                if [ "$family" = "ipv6" ] ; then
+                    if [ -n "$ip" ] ; then
+                        ip="[$ip]"
+                        [ -n "$prefix" ] || prefix=64
+                        ip="[${ip}/${prefix}]"
+                        mask=
+                    fi
+                    if [ -n "$gw" ] ; then
+                        gw="[${gw}]"
+                    fi
+                fi
+                if [ -n "$ip" ] && [ -n "$mask" -o -n "$prefix" ]; then
                     echo "ip=$ip::$gw:$mask:$hostname:$dev:none${dns1:+:$dns1}${dns2:+:$dns2}"
                 else
                     warn "${iface} does not contain a valid iBFT configuration"
@@ -412,53 +451,84 @@ ip_to_var() {
     done
 
     unset ip srv gw mask hostname dev autoconf macaddr mtu dns1 dns2
-    case $# in
-        0)  autoconf="error" ;;
-        1)  autoconf=$1 ;;
-        2)  [ -n "$1" ] && dev=$1; [ -n "$2" ] && autoconf=$2 ;;
-        3)  [ -n "$1" ] && dev=$1; [ -n "$2" ] && autoconf=$2; [ -n "$3" ] && mtu=$3 ;;
-        4)  [ -n "$1" ] && dev=$1; [ -n "$2" ] && autoconf=$2; [ -n "$3" ] && mtu=$3; [ -n "$4" ] && macaddr=$4 ;;
-        *)  [ -n "$1" ] && ip=$1; [ -n "$2" ] && srv=$2; [ -n "$3" ] && gw=$3; [ -n "$4" ] && mask=$4;
-            [ -n "$5" ] && hostname=$5; [ -n "$6" ] && dev=$6; [ -n "$7" ] && autoconf=$7;
-            case "$8" in
-                [0-9]*:*|[0-9]*.[0-9]*.[0-9]*.[0-9]*)
-                    dns1="$8"
-                    [ -n "$9" ] && dns2="$9"
-                    ;;
-                [0-9]*)
-                    mtu="$8"
-                    if [ -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
-                    ;;
-                *)
-                    if [ -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
-                    ;;
+
+    if [ $# -eq 0 ]; then
+        autoconf="error"
+        return 0
+    fi
+
+    if [ $# -eq 1 ]; then
+        # format: ip={dhcp|on|any|dhcp6|auto6|either6}
+        # or
+        #         ip=<ipv4-address> means anaconda-style static config argument cluster
+        autoconf="$1"
+
+        if strstr "$autoconf" "*.*.*.*"; then
+            # ip=<ipv4-address> means anaconda-style static config argument cluster:
+            # ip=<ip> gateway=<gw> netmask=<nm> hostname=<host> mtu=<mtu>
+            # ksdevice={link|bootif|ibft|<MAC>|<ifname>}
+            ip="$autoconf"
+            gw=$(getarg gateway=)
+            mask=$(getarg netmask=)
+            hostname=$(getarg hostname=)
+            dev=$(getarg ksdevice=)
+            autoconf="none"
+            mtu=$(getarg mtu=)
+
+            # handle special values for ksdevice
+            case "$dev" in
+                bootif|BOOTIF) dev=$(fix_bootif $(getarg BOOTIF=)) ;;
+                link) dev="" ;; # FIXME: do something useful with this
+                ibft) dev="" ;; # ignore - ibft is handled elsewhere
             esac
-            ;;
-    esac
+        fi
+        return 0
+    fi
 
-    # ip=<ipv4-address> means anaconda-style static config argument cluster:
-    # ip=<ip> gateway=<gw> netmask=<nm> hostname=<host> mtu=<mtu>
-    # ksdevice={link|bootif|ibft|<MAC>|<ifname>}
-    if strglob "$autoconf" "*.*.*.*"; then
-        ip="$autoconf"
-        gw=$(getarg gateway=)
-        mask=$(getarg netmask=)
-        hostname=$(getarg hostname=)
-        dev=$(getarg ksdevice=)
-        autoconf="none"
-        mtu=$(getarg mtu=)
-
-        # handle special values for ksdevice
-        case "$dev" in
-            bootif|BOOTIF) dev=$(fix_bootif $(getarg BOOTIF=)) ;;
-            link) dev="" ;; # FIXME: do something useful with this
-            ibft) dev="" ;; # ignore - ibft is handled elsewhere
-        esac
+    if [ "$2" = "dhcp" -o "$2" = "on" -o "$2" = "any" -o "$2" = "dhcp6" -o "$2" = "auto6" -o "$2" = "either6" ]; then
+        # format: ip=<interface>:{dhcp|on|any|dhcp6|auto6}[:[<mtu>][:<macaddr>]]
+        [ -n "$1" ] && dev="$1"
+        [ -n "$2" ] && autoconf="$2"
+        [ -n "$3" ] && mtu=$3
+        if [ -z "$5" ]; then
+            macaddr="$4"
+        else
+            macaddr="${4}:${5}:${6}:${7}:${8}:${9}"
+        fi
+        return 0
     fi
+
+    # format: ip=<client-IP>:[<peer>]:<gateway-IP>:<netmask>:<client_hostname>:<interface>:{none|off|dhcp|on|any|dhcp6|auto6|ibft}:[:[<mtu>][:<macaddr>]]
+
+    [ -n "$1" ] && ip=$1
+    [ -n "$2" ] && srv=$2
+    [ -n "$3" ] && gw=$3
+    [ -n "$4" ] && mask=$4
+    [ -n "$5" ] && hostname=$5
+    [ -n "$6" ] && dev=$6
+    [ -n "$7" ] && autoconf=$7
+    case "$8" in
+        [0-9]*:*|[0-9]*.[0-9]*.[0-9]*.[0-9]*)
+            dns1="$8"
+            [ -n "$9" ] && dns2="$9"
+            ;;
+        [0-9]*)
+            mtu="$8"
+            if [ -n "${9}" -a -z "${10}" ]; then
+                macaddr="${9}"
+            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
+            ;;
+        *)
+            if [ -n "${9}" -a -z "${10}" ]; then
+                macaddr="${9}"
+            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() {
@@ -576,16 +646,36 @@ wait_for_route_ok() {
     return 1
 }
 
+wait_for_ipv6_dad_link() {
+    local cnt=0
+    local timeout="$(getargs rd.net.timeout.ipv6dad=)"
+    timeout=${timeout:-50}
+    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)" ] \
+            && return 0
+        [ -n "$(ip -6 addr show dev "$1" scope link dadfailed)" ] \
+            && return 1
+        sleep 0.1
+        cnt=$(($cnt+1))
+    done
+    return 1
+}
+
 wait_for_ipv6_dad() {
     local cnt=0
-    local li
     local timeout="$(getargs rd.net.timeout.ipv6dad=)"
     timeout=${timeout:-50}
     timeout=$(($timeout*10))
 
     while [ $cnt -lt $timeout ]; do
-        li=$(ip -6 addr show dev $1 scope link)
-        strstr "$li" "tentative" || return 0
+        [ -z "$(ip -6 addr show dev "$1" tentative)" ] \
+            && [ -n "$(ip -6 route list proto ra dev "$1" | grep ^default)" ] \
+            && return 0
+        [ -n "$(ip -6 addr show dev "$1" dadfailed)" ] \
+            && return 1
         sleep 0.1
         cnt=$(($cnt+1))
     done
@@ -594,16 +684,14 @@ wait_for_ipv6_dad() {
 
 wait_for_ipv6_auto() {
     local cnt=0
-    local li
     local timeout="$(getargs rd.net.timeout.ipv6auto=)"
     timeout=${timeout:-40}
     timeout=$(($timeout*10))
 
     while [ $cnt -lt $timeout ]; do
-        li=$(ip -6 addr show dev $1)
-        if ! strstr "$li" "tentative"; then
-            strstr "$li" "dynamic" && return 0
-        fi
+        [ -z "$(ip -6 addr show dev "$1" tentative)" ] \
+            && [ -n "$(ip -6 route list proto ra dev "$1" | grep ^default)" ] \
+            && return 0
         sleep 0.1
         cnt=$(($cnt+1))
     done
@@ -638,8 +726,12 @@ iface_has_carrier() {
 
     while [ $cnt -lt $timeout ]; do
         if [ -n "$_no_carrier_flag" ]; then
+            li=$(ip -o link show up dev $1)
             # NO-CARRIER flag was cleared
             strstr "$li" "NO-CARRIER" || return 0
+        elif ! [ -e "$interface/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
@@ -653,6 +745,13 @@ iface_has_link() {
     iface_has_carrier "$@"
 }
 
+iface_is_enslaved() {
+    local _li
+    _li=$(ip -o link show dev $1)
+    strstr "$li" " master " || return 1
+    return 0
+}
+
 find_iface_with_link() {
     local iface_path="" iface=""
     for iface_path in /sys/class/net/*; do
@@ -731,3 +830,21 @@ is_kernel_ethernet_name() {
     esac
 
 }
+
+iface_get_subchannels() {
+    local _netif
+    local _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
+                  })
+    [ -n "$_subchannels" ] || return 1
+
+    printf -- "%s" ${_subchannels%,}
+}