diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-03 13:54:25 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-03 13:54:25 +0000 |
commit | 9cb1c4df7b9ce1a9ad1312621b0f2b16a94fba3a (patch) | |
tree | 2efb72864cc69e174c9c5ee33efb88a5f1553b48 /modules.d/35network-legacy | |
parent | Initial commit. (diff) | |
download | dracut-9cb1c4df7b9ce1a9ad1312621b0f2b16a94fba3a.tar.xz dracut-9cb1c4df7b9ce1a9ad1312621b0f2b16a94fba3a.zip |
Adding upstream version 060+5.upstream/060+5
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'modules.d/35network-legacy')
-rwxr-xr-x | modules.d/35network-legacy/dhclient-script.sh | 275 | ||||
-rw-r--r-- | modules.d/35network-legacy/dhclient.conf | 11 | ||||
-rwxr-xr-x | modules.d/35network-legacy/dhcp-multi.sh | 133 | ||||
-rwxr-xr-x | modules.d/35network-legacy/ifup.sh | 563 | ||||
-rwxr-xr-x | modules.d/35network-legacy/kill-dhclient.sh | 15 | ||||
-rwxr-xr-x | modules.d/35network-legacy/module-setup.sh | 99 | ||||
-rwxr-xr-x | modules.d/35network-legacy/net-genrules.sh | 125 | ||||
-rwxr-xr-x | modules.d/35network-legacy/parse-bond.sh | 76 | ||||
-rwxr-xr-x | modules.d/35network-legacy/parse-bridge.sh | 49 | ||||
-rwxr-xr-x | modules.d/35network-legacy/parse-ibft.sh | 10 | ||||
-rwxr-xr-x | modules.d/35network-legacy/parse-ifname.sh | 24 | ||||
-rwxr-xr-x | modules.d/35network-legacy/parse-ip-opts.sh | 151 | ||||
-rwxr-xr-x | modules.d/35network-legacy/parse-team.sh | 66 | ||||
-rwxr-xr-x | modules.d/35network-legacy/parse-vlan.sh | 37 |
14 files changed, 1634 insertions, 0 deletions
diff --git a/modules.d/35network-legacy/dhclient-script.sh b/modules.d/35network-legacy/dhclient-script.sh new file mode 100755 index 0000000..b3e5e75 --- /dev/null +++ b/modules.d/35network-legacy/dhclient-script.sh @@ -0,0 +1,275 @@ +#!/bin/sh + +PATH=/usr/sbin:/usr/bin:/sbin:/bin + +type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh +type ip_to_var > /dev/null 2>&1 || . /lib/net-lib.sh + +# We already need a set netif here +netif=$interface + +setup_interface() { + ip=$new_ip_address + mtu=$new_interface_mtu + mask=$new_subnet_mask + bcast=$new_broadcast_address + gw=${new_routers%%,*} + domain=$new_domain_name + # get rid of control chars + search=$(printf -- "%s" "$new_domain_search" | tr -d '[:cntrl:]') + namesrv=$new_domain_name_servers + hostname=$new_host_name + [ -n "$new_dhcp_lease_time" ] && lease_time=$new_dhcp_lease_time + [ -n "$new_max_life" ] && lease_time=$new_max_life + preferred_lft=$lease_time + [ -n "$new_preferred_life" ] && preferred_lft=$new_preferred_life + + # shellcheck disable=SC1090 + [ -f /tmp/net."$netif".override ] && . /tmp/net."$netif".override + + # Taken from debian dhclient-script: + # The 576 MTU is only used for X.25 and dialup connections + # where the admin wants low latency. Such a low MTU can cause + # problems with UDP traffic, among other things. As such, + # disallow MTUs from 576 and below by default, so that broken + # MTUs are ignored, but higher stuff is allowed (1492, 1500, etc). + if [ -n "$mtu" ] && [ "$mtu" -gt 576 ]; then + if ! ip link set "$netif" mtu "$mtu"; then + ip link set "$netif" down + ip link set "$netif" mtu "$mtu" + linkup "$netif" + fi + fi + + ip addr add "$ip"${mask:+/$mask} ${bcast:+broadcast $bcast} dev "$netif" \ + ${lease_time:+valid_lft $lease_time} \ + ${preferred_lft:+preferred_lft ${preferred_lft}} + + if [ -n "$gw" ]; then + if [ "$mask" = "255.255.255.255" ]; then + # point-to-point connection => set explicit route to gateway + echo ip route add "$gw" dev "$netif" > /tmp/net."$netif".gw + fi + + echo "$gw" | { + IFS=' ' read -r main_gw other_gw + echo ip route replace default via "$main_gw" dev "$netif" >> /tmp/net."$netif".gw + if [ -n "$other_gw" ]; then + for g in $other_gw; do + echo ip route add default via "$g" dev "$netif" >> /tmp/net."$netif".gw + done + fi + } + fi + + if getargbool 1 rd.peerdns; then + [ -n "${search}${domain}" ] && echo "search $search $domain" > /tmp/net."$netif".resolv.conf + if [ -n "$namesrv" ]; then + for s in $namesrv; do + echo nameserver "$s" + done + fi >> /tmp/net."$netif".resolv.conf + fi + # Note: hostname can be fqdn OR short hostname, so chop off any + # trailing domain name and explicitly add any domain if set. + [ -n "$hostname" ] && echo "echo ${hostname%."$domain"}${domain:+.$domain} > /proc/sys/kernel/hostname" > /tmp/net."$netif".hostname +} + +setup_interface6() { + domain=$new_domain_name + # get rid of control chars + search=$(printf -- "%s" "$new_dhcp6_domain_search" | tr -d '[:cntrl:]') + namesrv=$new_dhcp6_name_servers + hostname=$new_host_name + [ -n "$new_dhcp_lease_time" ] && lease_time=$new_dhcp_lease_time + [ -n "$new_max_life" ] && lease_time=$new_max_life + preferred_lft=$lease_time + [ -n "$new_preferred_life" ] && preferred_lft=$new_preferred_life + + # shellcheck disable=SC1090 + [ -f /tmp/net."$netif".override ] && . /tmp/net."$netif".override + + ip -6 addr add "${new_ip6_address}"/"${new_ip6_prefixlen}" \ + dev "${netif}" scope global \ + ${lease_time:+valid_lft $lease_time} \ + ${preferred_lft:+preferred_lft ${preferred_lft}} + + if getargbool 1 rd.peerdns; then + [ -n "${search}${domain}" ] && echo "search $search $domain" > /tmp/net."$netif".resolv.conf + if [ -n "$namesrv" ]; then + for s in $namesrv; do + echo nameserver "$s" + done + fi >> /tmp/net."$netif".resolv.conf + fi + + # Note: hostname can be fqdn OR short hostname, so chop off any + # trailing domain name and explicitly add any domain if set. + [ -n "$hostname" ] && echo "echo ${hostname%."$domain"}${domain:+.$domain} > /proc/sys/kernel/hostname" > /tmp/net."$netif".hostname +} + +parse_option_121() { + while [ $# -ne 0 ]; do + mask="$1" + shift + + # Is the destination a multicast group? + if [ "$1" -ge 224 -a "$1" -lt 240 ]; then + multicast=1 + else + multicast=0 + fi + + # Parse the arguments into a CIDR net/mask string + if [ "$mask" -gt 24 ]; then + destination="$1.$2.$3.$4/$mask" + shift + shift + shift + shift + elif [ "$mask" -gt 16 ]; then + destination="$1.$2.$3.0/$mask" + shift + shift + shift + elif [ "$mask" -gt 8 ]; then + destination="$1.$2.0.0/$mask" + shift + shift + elif [ "$mask" -gt 0 ]; then + destination="$1.0.0.0/$mask" + shift + else + destination="0.0.0.0/$mask" + fi + + # Read the gateway + gateway="$1.$2.$3.$4" + shift + shift + shift + shift + + # Multicast routing on Linux + # - If you set a next-hop address for a multicast group, this breaks with Cisco switches + # - If you simply leave it link-local and attach it to an interface, it works fine. + if [ $multicast -eq 1 -o "$gateway" = "0.0.0.0" ]; then + temp_result="$destination dev $interface" + else + temp_result="$destination via $gateway dev $interface" + fi + + echo "/sbin/ip route replace $temp_result" + done +} + +case $reason in + PREINIT) + echo "dhcp: PREINIT $netif up" + linkup "$netif" + ;; + + PREINIT6) + echo "dhcp: PREINIT6 $netif up" + linkup "$netif" + wait_for_ipv6_dad_link "$netif" + ;; + + BOUND) + echo "dhcp: BOUND setting up $netif" + unset layer2 + if [ -f /sys/class/net/"$netif"/device/layer2 ]; then + read -r layer2 < /sys/class/net/"$netif"/device/layer2 + fi + if [ "$layer2" != "0" ]; then + if command -v arping2 > /dev/null; then + if arping2 -q -C 1 -c 2 -I "$netif" -0 "$new_ip_address"; then + warn "Duplicate address detected for $new_ip_address while doing dhcp. retrying" + exit 1 + fi + else + if ! arping -f -q -D -c 2 -I "$netif" "$new_ip_address"; then + warn "Duplicate address detected for $new_ip_address while doing dhcp. retrying" + exit 1 + fi + fi + fi + unset layer2 + setup_interface + set | while read -r line || [ -n "$line" ]; do + [ "${line#new_}" = "$line" ] && continue + echo "$line" + done > /tmp/dhclient."$netif".dhcpopts + + { + echo '. /lib/net-lib.sh' + echo "setup_net $netif" + if [ -n "$new_classless_static_routes" ]; then + OLDIFS="$IFS" + IFS=".$IFS" + parse_option_121 "$new_classless_static_routes" + IFS="$OLDIFS" + fi + echo "source_hook initqueue/online $netif" + [ -e /tmp/net."$netif".manualup ] || echo "/sbin/netroot $netif" + echo "rm -f -- $hookdir/initqueue/setup_net_$netif.sh" + } > "$hookdir"/initqueue/setup_net_"$netif".sh + + echo "[ -f /tmp/net.$netif.did-setup ]" > "$hookdir"/initqueue/finished/dhclient-"$netif".sh + : > /tmp/net."$netif".up + if [ -e /sys/class/net/"${netif}"/address ]; then + : > "/tmp/net.$(cat /sys/class/net/"${netif}"/address).up" + fi + + ;; + + RENEW | REBIND) + unset lease_time + [ -n "$new_dhcp_lease_time" ] && lease_time=$new_dhcp_lease_time + [ -n "$new_max_life" ] && lease_time=$new_max_life + preferred_lft=$lease_time + [ -n "$new_preferred_life" ] && preferred_lft=$new_preferred_life + ip -4 addr change "${new_ip_address}"/"${new_subnet_mask}" broadcast "${new_broadcast_address}" dev "${interface}" \ + ${lease_time:+valid_lft $lease_time} ${preferred_lft:+preferred_lft ${preferred_lft}} \ + > /dev/null 2>&1 + ;; + + BOUND6) + echo "dhcp: BOUND6 setting up $netif" + setup_interface6 + + set | while read -r line || [ -n "$line" ]; do + [ "${line#new_}" = "$line" ] && continue + echo "$line" + done > /tmp/dhclient."$netif".dhcpopts + + { + echo '. /lib/net-lib.sh' + echo "setup_net $netif" + echo "source_hook initqueue/online $netif" + [ -e /tmp/net."$netif".manualup ] || echo "/sbin/netroot $netif" + echo "rm -f -- $hookdir/initqueue/setup_net_$netif.sh" + } > "$hookdir"/initqueue/setup_net_"$netif".sh + + echo "[ -f /tmp/net.$netif.did-setup ]" > "$hookdir"/initqueue/finished/dhclient-"$netif".sh + : > /tmp/net."$netif".up + if [ -e /sys/class/net/"${netif}"/address ]; then + : > "/tmp/net.$(cat /sys/class/net/"${netif}"/address).up" + fi + ;; + + RENEW6 | REBIND6) + unset lease_time + [ -n "$new_dhcp_lease_time" ] && lease_time=$new_dhcp_lease_time + [ -n "$new_max_life" ] && lease_time=$new_max_life + preferred_lft=$lease_time + [ -n "$new_preferred_life" ] && preferred_lft=$new_preferred_life + ip -6 addr change "${new_ip6_address}"/"${new_ip6_prefixlen}" dev "${interface}" scope global \ + ${lease_time:+valid_lft $lease_time} ${preferred_lft:+preferred_lft ${preferred_lft}} \ + > /dev/null 2>&1 + ;; + + *) echo "dhcp: $reason" ;; +esac + +exit 0 diff --git a/modules.d/35network-legacy/dhclient.conf b/modules.d/35network-legacy/dhclient.conf new file mode 100644 index 0000000..ffd24ef --- /dev/null +++ b/modules.d/35network-legacy/dhclient.conf @@ -0,0 +1,11 @@ + +option classless-static-routes code 121 = array of unsigned integer 8; + +send dhcp-client-identifier = hardware; + +request subnet-mask, broadcast-address, time-offset, routers, + domain-name, domain-name-servers, domain-search, host-name, + root-path, interface-mtu, classless-static-routes, + netbios-name-servers, netbios-scope, ntp-servers, + dhcp6.domain-search, dhcp6.fqdn, + dhcp6.name-servers, dhcp6.sntp-servers; diff --git a/modules.d/35network-legacy/dhcp-multi.sh b/modules.d/35network-legacy/dhcp-multi.sh new file mode 100755 index 0000000..60e0374 --- /dev/null +++ b/modules.d/35network-legacy/dhcp-multi.sh @@ -0,0 +1,133 @@ +#!/bin/sh +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh +# +PATH=/usr/sbin:/usr/bin:/sbin:/bin + +# File to start dhclient requests on different interfaces in parallel + +. /lib/dracut-lib.sh +. /lib/net-lib.sh + +netif=$1 +do_vlan=$2 +arg=$3 + +# Run dhclient in parallel +do_dhclient() { + local _COUNT=0 + local _timeout + local _DHCPRETRY + _timeout=$(getarg rd.net.timeout.dhcp=) + _DHCPRETRY=$(getargnum 1 1 1000000000 rd.net.dhcp.retry=) + + if [ -n "$_timeout" ]; then + if ! (dhclient --help 2>&1 | grep -q -F -- '--timeout' 2> /dev/null); then + warn "rd.net.timeout.dhcp has no effect because dhclient does not implement the --timeout option" + unset _timeout + fi + fi + + while [ $_COUNT -lt "$_DHCPRETRY" ]; do + info "Starting dhcp for interface $netif" + dhclient "$arg" \ + ${_timeout:+--timeout "$_timeout"} \ + -q \ + -1 \ + -cf /etc/dhclient.conf \ + -pf /tmp/dhclient."$netif".pid \ + -lf /tmp/dhclient."$netif".lease \ + "$netif" & + wait $! 2> /dev/null + + # wait will return the return value of dhclient + retv=$? + + # dhclient and hence wait returned success, 0. + if [ $retv -eq 0 ]; then + return 0 + fi + + # If dhclient exited before wait was called, or it was killed by + # another thread for interface whose DHCP succeeded, then it will not + # find the process with that pid and return error code 127. In that + # case we need to check if /tmp/dhclient.$netif.lease exists. If it + # does, it means dhclient finished executing before wait was called, + # and it was successful (return 0). If /tmp/dhclient.$netif.lease + # does not exist, then it means dhclient was killed by another thread + # or it finished execution but failed dhcp on that interface. + + if [ $retv -eq 127 ]; then + read -r pid < /tmp/dhclient."$netif".pid + info "PID $pid was not found by wait for $netif" + if [ -e /tmp/dhclient."$netif".lease ]; then + info "PID $pid not found but DHCP successful on $netif" + return 0 + fi + fi + + _COUNT=$((_COUNT + 1)) + [ $_COUNT -lt "$_DHCPRETRY" ] && sleep 1 + done + warn "dhcp for interface $netif failed" + # nuke those files since we failed; we might retry dhcp again if it's e.g. + # `ip=dhcp,dhcp6` and we check for the PID file earlier + rm -f /tmp/dhclient."$netif".pid /tmp/dhclient."$netif".lease + return 1 +} + +do_dhclient +ret=$? + +# setup nameserver +for s in "$dns1" "$dns2" $(getargs nameserver); do + [ -n "$s" ] || continue + echo nameserver "$s" >> /tmp/net."$netif".resolv.conf +done + +if [ $ret -eq 0 ]; then + : > /tmp/net."${netif}".up + + if [ -z "$do_vlan" ] && [ -e /sys/class/net/"${netif}"/address ]; then + : > "/tmp/net.$(cat /sys/class/net/"${netif}"/address).up" + fi + + # Check if DHCP also succeeded on another interface before this one. + # We will always use the first one on which DHCP succeeded, by using + # a common file $IFNETFILE, to synchronize between threads. + # Consider the race condition in which multiple threads + # corresponding to different interfaces may try to read $IFNETFILE + # and find it does not exist; they may all end up thinking they are the + # first to succeed (hence more than one thread may end up writing to + # $IFNETFILE). To take care of this, instead of checking if $IFNETFILE + # exists to determine if we are the first, we create a symbolic link + # in $IFNETFILE, pointing to the interface name ($netif), thus storing + # the interface name in the link pointer. + # Creating a link will fail, if the link already exists, hence kernel + # will take care of allowing only first thread to create link, which + # takes care of the race condition for us. Subsequent threads will fail. + # Also, the link points to the interface name, which will tell us which + # interface succeeded. + + if ln -s "$netif" "$IFNETFILE" 2> /dev/null; then + intf=$(readlink "$IFNETFILE") + if [ -e /tmp/dhclient."$intf".lease ]; then + info "DHCP successful on interface $intf" + # Kill all existing dhclient calls for other interfaces, since we + # already got one successful interface + + read -r npid < /tmp/dhclient."$netif".pid + pidlist=$(pgrep dhclient) + for pid in $pidlist; do + [ "$pid" -eq "$npid" ] && continue + kill -9 "$pid" > /dev/null 2>&1 + done + else + echo "ERROR! $IFNETFILE exists but /tmp/dhclient.$intf.lease does not exist!!!" + fi + else + info "DHCP success on $netif, and also on $intf" + exit 0 + fi + exit $ret +fi diff --git a/modules.d/35network-legacy/ifup.sh b/modules.d/35network-legacy/ifup.sh new file mode 100755 index 0000000..3b54b6c --- /dev/null +++ b/modules.d/35network-legacy/ifup.sh @@ -0,0 +1,563 @@ +#!/bin/sh +# +# We don't need to check for ip= errors here, that is handled by the +# cmdline parser script +# +# without $2 means this is for real netroot case +# or it is for manually bring up network ie. for kdump scp vmcore +PATH=/usr/sbin:/usr/bin:/sbin:/bin + +type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh +type ip_to_var > /dev/null 2>&1 || . /lib/net-lib.sh + +# Huh? No $1? +[ -z "$1" ] && exit 1 + +# $netif reads easier than $1 +netif=$1 + +# loopback is always handled the same way +if [ "$netif" = "lo" ]; then + ip link set lo up + ip addr add 127.0.0.1/8 dev lo + exit 0 +fi + +do_dhcp_parallel() { + # dhclient-script will mark the netif up and generate the online + # event for nfsroot + # XXX add -V vendor class and option parsing per kernel + + [ -e "/tmp/dhclient.$netif.pid" ] && return 0 + + if ! iface_has_carrier "$netif"; then + warn "No carrier detected on interface $netif" + return 1 + fi + + bootintf=$(readlink "$IFNETFILE") + if [ -n "$bootintf" ] && [ -e "/tmp/dhclient.${bootintf}.lease" ]; then + info "DHCP already succeeded for $bootintf, exiting for $netif" + return 1 + fi + + if [ ! -e /run/NetworkManager/conf.d/10-dracut-dhclient.conf ]; then + mkdir -p /run/NetworkManager/conf.d + echo '[main]' > /run/NetworkManager/conf.d/10-dracut-dhclient.conf + echo 'dhcp=dhclient' >> /run/NetworkManager/conf.d/10-dracut-dhclient.conf + fi + + chmod +x /sbin/dhcp-multi.sh + /sbin/dhcp-multi.sh "$netif" "$DO_VLAN" "$@" & + return 0 +} + +# Run dhclient +do_dhcp() { + # dhclient-script will mark the netif up and generate the online + # event for nfsroot + # XXX add -V vendor class and option parsing per kernel + + local _COUNT + local _timeout + local _DHCPRETRY + + _COUNT=0 + _timeout=$(getarg rd.net.timeout.dhcp=) + _DHCPRETRY=$(getargnum 1 1 1000000000 rd.net.dhcp.retry=) + + [ -e "/tmp/dhclient.${netif}.pid" ] && return 0 + + if ! iface_has_carrier "$netif"; then + warn "No carrier detected on interface $netif" + return 1 + fi + + if [ -n "$_timeout" ]; then + if ! (dhclient --help 2>&1 | grep -q -F -- '--timeout' 2> /dev/null); then + warn "rd.net.timeout.dhcp has no effect because dhclient does not implement the --timeout option" + unset _timeout + fi + fi + + if [ ! -e /run/NetworkManager/conf.d/10-dracut-dhclient.conf ]; then + mkdir -p /run/NetworkManager/conf.d + echo '[main]' > /run/NetworkManager/conf.d/10-dracut-dhclient.conf + echo 'dhcp=dhclient' >> /run/NetworkManager/conf.d/10-dracut-dhclient.conf + fi + + while [ "$_COUNT" -lt "$_DHCPRETRY" ]; do + info "Starting dhcp for interface $netif" + dhclient "$@" \ + ${_timeout:+--timeout "$_timeout"} \ + -q \ + -1 \ + -cf /etc/dhclient.conf \ + -pf "/tmp/dhclient.${netif}.pid" \ + -lf "/tmp/dhclient.${netif}.lease" \ + "$netif" \ + && return 0 + _COUNT=$((_COUNT + 1)) + [ "$_COUNT" -lt "$_DHCPRETRY" ] && sleep 1 + done + warn "dhcp for interface $netif failed" + # nuke those files since we failed; we might retry dhcp again if it's e.g. + # `ip=dhcp,dhcp6` and we check for the PID file at the top + rm -f /tmp/dhclient."$netif".pid /tmp/dhclient."$netif".lease + return 1 +} + +load_ipv6() { + [ -d /proc/sys/net/ipv6 ] && return + modprobe ipv6 + i=0 + while [ ! -d /proc/sys/net/ipv6 ]; do + i=$((i + 1)) + [ $i -gt 10 ] && break + sleep 0.1 + done +} + +do_ipv6auto() { + local ret + load_ipv6 + echo 0 > /proc/sys/net/ipv6/conf/"${netif}"/forwarding + echo 1 > /proc/sys/net/ipv6/conf/"${netif}"/accept_ra + echo 1 > /proc/sys/net/ipv6/conf/"${netif}"/accept_redirects + linkup "$netif" + wait_for_ipv6_auto "$netif" + ret=$? + + [ -n "$hostname" ] && echo "echo $hostname > /proc/sys/kernel/hostname" > "/tmp/net.${netif}.hostname" + + return "$ret" +} + +do_ipv6link() { + local ret + load_ipv6 + echo 0 > /proc/sys/net/ipv6/conf/"${netif}"/forwarding + echo 0 > /proc/sys/net/ipv6/conf/"${netif}"/accept_ra + echo 0 > /proc/sys/net/ipv6/conf/"${netif}"/accept_redirects + linkup "$netif" + + [ -n "$hostname" ] && echo "echo $hostname > /proc/sys/kernel/hostname" > "/tmp/net.${netif}.hostname" + + return "$ret" +} + +# Handle static ip configuration +do_static() { + strglobin "$ip" '*:*:*' && load_ipv6 + + if ! iface_has_carrier "$netif"; then + warn "No carrier detected on interface $netif" + return 1 + elif ! linkup "$netif"; then + warn "Could not bring interface $netif up!" + return 1 + fi + + ip route get "$ip" 2> /dev/null | { + read -r a rest + if [ "$a" = "local" ]; then + warn "Not assigning $ip to interface $netif, cause it is already assigned!" + return 1 + fi + return 0 + } || return 1 + + [ -n "$macaddr" ] && ip link set address "$macaddr" dev "$netif" + [ -n "$mtu" ] && ip link set mtu "$mtu" dev "$netif" + if strglobin "$ip" '*:*:*'; then + # note no ip addr flush for ipv6 + ip addr add "$ip/$mask" ${srv:+peer "$srv"} dev "$netif" + echo 0 > /proc/sys/net/ipv6/conf/"${netif}"/forwarding + echo 1 > /proc/sys/net/ipv6/conf/"${netif}"/accept_ra + echo 1 > /proc/sys/net/ipv6/conf/"${netif}"/accept_redirects + wait_for_ipv6_dad "$netif" + else + if [ -z "$srv" ]; then + if command -v arping2 > /dev/null; then + if arping2 -q -C 1 -c 2 -I "$netif" -0 "$ip"; then + warn "Duplicate address detected for $ip for interface $netif." + return 1 + fi + else + if ! arping -f -q -D -c 2 -I "$netif" "$ip"; then + warn "Duplicate address detected for $ip for interface $netif." + return 1 + fi + fi + fi + ip addr flush dev "$netif" + ip addr add "$ip/$mask" ${srv:+peer "$srv"} brd + dev "$netif" + fi + + [ -n "$gw" ] && echo "ip route replace default via '$gw' dev '$netif'" > "/tmp/net.$netif.gw" + [ -n "$hostname" ] && echo "echo '$hostname' > /proc/sys/kernel/hostname" > "/tmp/net.$netif.hostname" + + return 0 +} + +get_vid() { + case "$1" in + vlan*) + echo "${1#vlan}" + ;; + *.*) + echo "${1##*.}" + ;; + esac +} + +# check, if we need VLAN's for this interface +if [ -z "$DO_VLAN_PHY" ] && [ -e "/tmp/vlan.${netif}.phy" ]; then + unset DO_VLAN + NO_AUTO_DHCP=yes DO_VLAN_PHY=yes ifup "$netif" + modprobe -b -q 8021q + + for i in /tmp/vlan.*."${netif}"; do + [ -e "$i" ] || continue + unset vlanname + unset phydevice + # shellcheck disable=SC1090 + . "$i" + if [ -n "$vlanname" ]; then + linkup "$phydevice" + ip link add dev "$vlanname" link "$phydevice" type vlan id "$(get_vid "$vlanname")" + ifup "$vlanname" + fi + done + exit 0 +fi + +# Check, if interface is VLAN interface +if ! [ -e "/tmp/vlan.${netif}.phy" ]; then + for i in "/tmp/vlan.${netif}".*; do + [ -e "$i" ] || continue + export DO_VLAN=yes + break + done +fi + +# bridge this interface? +if [ -z "$NO_BRIDGE_MASTER" ]; then + for i in /tmp/bridge.*.info; do + [ -e "$i" ] || continue + unset bridgeslaves + unset bridgename + # shellcheck disable=SC1090 + . "$i" + for ethname in $bridgeslaves; do + [ "$netif" != "$ethname" ] && continue + + NO_BRIDGE_MASTER=yes NO_AUTO_DHCP=yes ifup "$ethname" + linkup "$ethname" + if [ ! -e "/tmp/bridge.$bridgename.up" ]; then + ip link add name "$bridgename" type bridge + echo 0 > "/sys/devices/virtual/net/$bridgename/bridge/forward_delay" + : > "/tmp/bridge.$bridgename.up" + fi + ip link set dev "$ethname" master "$bridgename" + ifup "$bridgename" + exit 0 + done + done +fi + +# enslave this interface to bond? +if [ -z "$NO_BOND_MASTER" ]; then + for i in /tmp/bond.*.info; do + [ -e "$i" ] || continue + unset bondslaves + unset bondname + # shellcheck disable=SC1090 + . "$i" + for testslave in $bondslaves; do + [ "$netif" != "$testslave" ] && continue + + # already setup + [ -e "/tmp/bond.$bondname.up" ] && exit 0 + + # wait for all slaves to show up + for slave in $bondslaves; do + # try to create the slave (maybe vlan or bridge) + NO_BOND_MASTER=yes NO_AUTO_DHCP=yes ifup "$slave" + + if ! ip link show dev "$slave" > /dev/null 2>&1; then + # wait for the last slave to show up + exit 0 + fi + done + + modprobe -q -b bonding + echo "+$bondname" > /sys/class/net/bonding_masters 2> /dev/null + ip link set "$bondname" down + + # Stolen from ifup-eth + # add the bits to setup driver parameters here + for arg in $bondoptions; do + key=${arg%%=*} + value=${arg##*=} + # %{value:0:1} is replaced with non-bash specific construct + if [ "${key}" = "arp_ip_target" -a "${#value}" != "0" -a "+${value%%+*}" != "+" ]; then + OLDIFS=$IFS + IFS=',' + for arp_ip in $value; do + echo "+$arp_ip" > "/sys/class/net/${bondname}/bonding/$key" + done + IFS=$OLDIFS + else + echo "$value" > "/sys/class/net/${bondname}/bonding/$key" + fi + done + + linkup "$bondname" + + for slave in $bondslaves; do + cat "/sys/class/net/$slave/address" > "/tmp/net.${bondname}.${slave}.hwaddr" + ip link set "$slave" down + echo "+$slave" > "/sys/class/net/$bondname/bonding/slaves" + linkup "$slave" + done + + # Set mtu on bond master + [ -n "$bondmtu" ] && ip link set mtu "$bondmtu" dev "$bondname" + + # add the bits to setup the needed post enslavement parameters + for arg in $bondoptions; do + key=${arg%%=*} + value=${arg##*=} + if [ "${key}" = "primary" ]; then + echo "$value" > "/sys/class/net/${bondname}/bonding/$key" + fi + done + + : > "/tmp/bond.$bondname.up" + + NO_BOND_MASTER=yes ifup "$bondname" + exit $? + done + done +fi + +if [ -z "$NO_TEAM_MASTER" ]; then + for i in /tmp/team.*.info; do + [ -e "$i" ] || continue + unset teammaster + unset teamslaves + # shellcheck disable=SC1090 + . "$i" + for testslave in $teamslaves; do + [ "$netif" != "$testslave" ] && continue + + [ -e "/tmp/team.$teammaster.up" ] && exit 0 + + # wait for all slaves to show up + for slave in $teamslaves; do + # try to create the slave (maybe vlan or bridge) + NO_TEAM_MASTER=yes NO_AUTO_DHCP=yes ifup "$slave" + + if ! ip link show dev "$slave" > /dev/null 2>&1; then + # wait for the last slave to show up + exit 0 + fi + done + + if [ ! -e "/tmp/team.$teammaster.up" ]; then + # We shall only bring up those _can_ come up + # in case of some slave is gone in active-backup mode + working_slaves="" + for slave in $teamslaves; do + teamdctl "${teammaster}" port present "${slave}" 2> /dev/null \ + && continue + ip link set dev "$slave" up 2> /dev/null + if wait_for_if_up "$slave"; then + working_slaves="$working_slaves$slave " + fi + done + # Do not add slaves now + teamd -d -U -n -N -t "$teammaster" -f "/etc/teamd/${teammaster}.conf" + for slave in $working_slaves; do + # team requires the slaves to be down before joining team + ip link set dev "$slave" down + ( + unset TEAM_PORT_CONFIG + read -r _hwaddr < "/sys/class/net/$slave/address" + _subchannels=$(iface_get_subchannels "$slave") + if [ -n "$_hwaddr" ] && [ -e "/etc/sysconfig/network-scripts/mac-${_hwaddr}.conf" ]; then + # shellcheck disable=SC1090 + . "/etc/sysconfig/network-scripts/mac-${_hwaddr}.conf" + elif [ -n "$_subchannels" ] && [ -e "/etc/sysconfig/network-scripts/ccw-${_subchannels}.conf" ]; then + # shellcheck disable=SC1090 + . "/etc/sysconfig/network-scripts/ccw-${_subchannels}.conf" + elif [ -e "/etc/sysconfig/network-scripts/ifcfg-${slave}" ]; then + # shellcheck disable=SC1090 + . "/etc/sysconfig/network-scripts/ifcfg-${slave}" + fi + + if [ -n "${TEAM_PORT_CONFIG}" ]; then + /usr/bin/teamdctl "${teammaster}" port config update "${slave}" "${TEAM_PORT_CONFIG}" + fi + ) + teamdctl "$teammaster" port add "$slave" + done + + ip link set dev "$teammaster" up + + : > "/tmp/team.$teammaster.up" + NO_TEAM_MASTER=yes ifup "$teammaster" + exit $? + fi + done + done +fi + +# all synthetic interfaces done.. now check if the interface is available +if ! ip link show dev "$netif" > /dev/null 2>&1; then + exit 1 +fi + +# disable manual ifup while netroot is set for simplifying our logic +# in netroot case we prefer netroot to bringup $netif automatically +[ -n "$2" -a "$2" = "-m" ] && [ -z "$netroot" ] && manualup="$2" + +if [ -n "$manualup" ]; then + : > "/tmp/net.$netif.manualup" + rm -f "/tmp/net.${netif}.did-setup" +else + [ -e "/tmp/net.${netif}.did-setup" ] && exit 0 + [ -z "$DO_VLAN" ] \ + && [ -e "/sys/class/net/$netif/address" ] \ + && [ -e "/tmp/net.$(cat "/sys/class/net/$netif/address").did-setup" ] && exit 0 +fi + +# Specific configuration, spin through the kernel command line +# looking for ip= lines +for p in $(getargs ip=); do + ip_to_var "$p" + # skip ibft + [ "$autoconf" = "ibft" ] && continue + + case "$dev" in + ??:??:??:??:??:??) # MAC address + _dev=$(iface_for_mac "$dev") + [ -n "$_dev" ] && dev="$_dev" + ;; + ??-??-??-??-??-??) # MAC address in BOOTIF form + _dev=$(iface_for_mac "$(fix_bootif "$dev")") + [ -n "$_dev" ] && dev="$_dev" + ;; + esac + + # If this option isn't directed at our interface, skip it + if [ -n "$dev" ]; then + if [ "$dev" != "$netif" ]; then + [ ! -e "/sys/class/net/$dev" ] \ + && warn "Network interface '$dev' does not exist!" + continue + fi + else + iface_is_enslaved "$netif" && continue + fi + + # Store config for later use + for i in ip srv gw mask hostname macaddr mtu dns1 dns2; do + eval '[ "$'$i'" ] && echo '$i'="$'$i'"' + done > "/tmp/net.$netif.override" + + for autoopt in $(str_replace "$autoconf" "," " "); do + case $autoopt in + dhcp | on | any) + do_dhcp -4 + ;; + single-dhcp) + do_dhcp_parallel -4 + exit 0 + ;; + dhcp6) + load_ipv6 + do_dhcp -6 + ;; + auto6) + do_ipv6auto + ;; + either6) + do_ipv6auto || do_dhcp -6 + ;; + link6) + do_ipv6link + ;; + *) + do_static + ;; + esac + done + ret=$? + + # setup nameserver + for s in "$dns1" "$dns2" $(getargs nameserver); do + [ -n "$s" ] || continue + echo "nameserver $s" >> "/tmp/net.$netif.resolv.conf" + done + + if [ $ret -eq 0 ]; then + : > "/tmp/net.${netif}.up" + + if [ -z "$DO_VLAN" ] && [ -e "/sys/class/net/${netif}/address" ]; then + : > "/tmp/net.$(cat "/sys/class/net/${netif}/address").up" + fi + + # and finally, finish interface set up if there isn't already a script + # to do so (which is the case in the dhcp path) + if [ ! -e "$hookdir/initqueue/setup_net_$netif.sh" ]; then + setup_net "$netif" + source_hook initqueue/online "$netif" + if [ -z "$manualup" ]; then + /sbin/netroot "$netif" + fi + fi + + exit $ret + fi +done + +# no ip option directed at our interface? +if [ -z "$NO_AUTO_DHCP" ] && [ ! -e "/tmp/net.${netif}.up" ]; then + ret=1 + if [ -e /tmp/net.bootdev ]; then + read -r BOOTDEV < /tmp/net.bootdev + if [ "$netif" = "$BOOTDEV" ] || [ "$BOOTDEV" = "$(cat "/sys/class/net/${netif}/address")" ]; then + do_dhcp + ret=$? + fi + else + # No ip lines, no bootdev -> default to dhcp + ip=$(getarg ip) + + if getargs 'ip=dhcp6' > /dev/null || [ -z "$ip" -a "$netroot" = "dhcp6" ]; then + load_ipv6 + do_dhcp -6 + ret=$? + fi + if getargs 'ip=dhcp' > /dev/null || [ -z "$ip" -a "$netroot" != "dhcp6" ]; then + do_dhcp -4 + ret=$? + fi + fi + + for s in $(getargs nameserver); do + [ -n "$s" ] || continue + echo "nameserver $s" >> "/tmp/net.$netif.resolv.conf" + done + + if [ "$ret" -eq 0 ] && [ -n "$(ls "/tmp/leaseinfo.${netif}"* 2> /dev/null)" ]; then + : > "/tmp/net.${netif}.did-setup" + if [ -e "/sys/class/net/${netif}/address" ]; then + : > "/tmp/net.$(cat "/sys/class/net/${netif}/address").did-setup" + fi + fi +fi + +exit 0 diff --git a/modules.d/35network-legacy/kill-dhclient.sh b/modules.d/35network-legacy/kill-dhclient.sh new file mode 100755 index 0000000..9ed615f --- /dev/null +++ b/modules.d/35network-legacy/kill-dhclient.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +for f in /tmp/dhclient.*.pid; do + [ -e "$f" ] || continue + read -r PID < "$f" + kill "$PID" > /dev/null 2>&1 +done + +sleep 0.1 + +for f in /tmp/dhclient.*.pid; do + [ -e "$f" ] || continue + read -r PID < "$f" + kill -9 "$PID" > /dev/null 2>&1 +done diff --git a/modules.d/35network-legacy/module-setup.sh b/modules.d/35network-legacy/module-setup.sh new file mode 100755 index 0000000..868ea8f --- /dev/null +++ b/modules.d/35network-legacy/module-setup.sh @@ -0,0 +1,99 @@ +#!/bin/bash + +# called by dracut +check() { + require_binaries ip dhclient sed awk grep pgrep tr expr || return 1 + require_any_binary arping arping2 || return 1 + + return 255 +} + +# called by dracut +depends() { + return 0 +} + +# called by dracut +installkernel() { + # arping depends on af_packet + hostonly='' instmods af_packet +} + +# called by dracut +install() { + local _arch + + #Adding default link + if dracut_module_included "systemd"; then + inst_multiple -o "${systemdnetwork}/99-default.link" + [[ $hostonly ]] && inst_multiple -H -o "${systemdnetworkconfdir}/*.link" + fi + + inst_multiple ip dhclient sed awk grep pgrep tr expr + + inst_multiple -o arping arping2 + strstr "$(arping 2>&1)" "ARPing 2" && mv "$initdir/bin/arping" "$initdir/bin/arping2" + + inst_multiple -o ping ping6 + inst_multiple -o teamd teamdctl teamnl + inst_simple /etc/libnl/classid + inst_script "$moddir/ifup.sh" "/sbin/ifup" + inst_script "$moddir/dhcp-multi.sh" "/sbin/dhcp-multi.sh" + inst_script "$moddir/dhclient-script.sh" "/sbin/dhclient-script" + inst_simple -H "/etc/dhclient.conf" + cat "$moddir/dhclient.conf" >> "${initdir}/etc/dhclient.conf" + inst_hook pre-udev 60 "$moddir/net-genrules.sh" + inst_hook cmdline 92 "$moddir/parse-ibft.sh" + inst_hook cmdline 95 "$moddir/parse-vlan.sh" + inst_hook cmdline 96 "$moddir/parse-bond.sh" + inst_hook cmdline 96 "$moddir/parse-team.sh" + inst_hook cmdline 97 "$moddir/parse-bridge.sh" + inst_hook cmdline 98 "$moddir/parse-ip-opts.sh" + inst_hook cmdline 99 "$moddir/parse-ifname.sh" + inst_hook cleanup 10 "$moddir/kill-dhclient.sh" + + # install all config files for teaming + unset TEAM_MASTER + unset TEAM_CONFIG + unset TEAM_PORT_CONFIG + unset HWADDR + unset SUBCHANNELS + for i in /etc/sysconfig/network-scripts/ifcfg-*; do + [ -e "$i" ] || continue + case "$i" in + *~ | *.bak | *.orig | *.rpmnew | *.rpmorig | *.rpmsave) + continue + ;; + esac + ( + # shellcheck disable=SC1090 + . "$i" + if ! [ "${ONBOOT}" = "no" -o "${ONBOOT}" = "NO" ] \ + && [ -n "${TEAM_MASTER}${TEAM_CONFIG}${TEAM_PORT_CONFIG}" ]; then + if [ -n "$TEAM_CONFIG" ] && [ -n "$DEVICE" ]; then + mkdir -p "$initdir"/etc/teamd + printf -- "%s" "$TEAM_CONFIG" > "$initdir/etc/teamd/${DEVICE}.conf" + elif [ -n "$TEAM_PORT_CONFIG" ]; then + inst_simple "$i" + + HWADDR="$(echo "$HWADDR" | sed 'y/ABCDEF/abcdef/')" + if [ -n "$HWADDR" ]; then + ln_r "$i" "/etc/sysconfig/network-scripts/mac-${HWADDR}.conf" + fi + + SUBCHANNELS="$(echo "$SUBCHANNELS" | sed 'y/ABCDEF/abcdef/')" + if [ -n "$SUBCHANNELS" ]; then + ln_r "$i" "/etc/sysconfig/network-scripts/ccw-${SUBCHANNELS}.conf" + fi + fi + fi + ) + done + + _arch=${DRACUT_ARCH:-$(uname -m)} + + inst_libdir_file {"tls/$_arch/",tls/,"$_arch/",}"libnss_dns.so.*" \ + {"tls/$_arch/",tls/,"$_arch/",}"libnss_mdns4_minimal.so.*" + + dracut_need_initqueue +} diff --git a/modules.d/35network-legacy/net-genrules.sh b/modules.d/35network-legacy/net-genrules.sh new file mode 100755 index 0000000..686db59 --- /dev/null +++ b/modules.d/35network-legacy/net-genrules.sh @@ -0,0 +1,125 @@ +#!/bin/sh + +getargbool 0 rd.neednet && NEEDNET=1 + +# Don't continue if we don't need network +if [ -z "$netroot" ] && [ ! -e "/tmp/net.ifaces" ] && [ "$NEEDNET" != "1" ]; then + return +fi + +command -v fix_bootif > /dev/null || . /lib/net-lib.sh + +# Write udev rules +{ + # bridge: attempt only the defined interface + for i in /tmp/bridge.*.info; do + [ -e "$i" ] || continue + unset bridgeslaves + unset bridgename + # shellcheck disable=SC1090 + . "$i" + RAW_IFACES="$RAW_IFACES $bridgeslaves" + MASTER_IFACES="$MASTER_IFACES $bridgename" + done + + # bond: attempt only the defined interface (override bridge defines) + for i in /tmp/bond.*.info; do + [ -e "$i" ] || continue + unset bondslaves + unset bondname + # shellcheck disable=SC1090 + . "$i" + # It is enough to fire up only one + RAW_IFACES="$RAW_IFACES $bondslaves" + MASTER_IFACES="$MASTER_IFACES ${bondname}" + done + + for i in /tmp/team.*.info; do + [ -e "$i" ] || continue + unset teamslaves + unset teammaster + # shellcheck disable=SC1090 + . "$i" + RAW_IFACES="$RAW_IFACES ${teamslaves}" + MASTER_IFACES="$MASTER_IFACES ${teammaster}" + done + + for i in /tmp/vlan.*.phy; do + [ -e "$i" ] || continue + unset phydevice + # shellcheck disable=SC1090 + . "$i" + RAW_IFACES="$RAW_IFACES $phydevice" + for j in /tmp/vlan.*".${phydevice}"; do + [ -e "$j" ] || continue + unset vlanname + # shellcheck disable=SC1090 + . "$j" + MASTER_IFACES="$MASTER_IFACES ${vlanname}" + done + done + + MASTER_IFACES="$(trim "$MASTER_IFACES")" + RAW_IFACES="$(trim "$RAW_IFACES")" + + if [ -z "$IFACES" ]; then + [ -e /tmp/net.ifaces ] && read -r IFACES < /tmp/net.ifaces + fi + + if [ -e /tmp/net.bootdev ]; then + read -r bootdev < /tmp/net.bootdev + fi + + # shellcheck disable=SC2016 + ifup='/sbin/ifup $name' + + runcmd="RUN+=\"/sbin/initqueue --name ifup-\$name --unique --onetime $ifup\"" + + # We have some specific interfaces to handle + if [ -n "${RAW_IFACES}${IFACES}" ]; then + echo 'SUBSYSTEM!="net", GOTO="net_end"' + echo 'ACTION!="add|change|move", GOTO="net_end"' + for iface in $IFACES $RAW_IFACES; do + case "$iface" in + ??:??:??:??:??:??) # MAC address + cond="ATTR{address}==\"$iface\"" + echo "$cond, $runcmd, GOTO=\"net_end\"" + ;; + ??-??-??-??-??-??) # MAC address in BOOTIF form + cond="ATTR{address}==\"$(fix_bootif "$iface")\"" + echo "$cond, $runcmd, GOTO=\"net_end\"" + ;; + *) # an interface name + cond="ENV{INTERFACE}==\"$iface\"" + echo "$cond, $runcmd, GOTO=\"net_end\"" + cond="NAME==\"$iface\"" + echo "$cond, $runcmd, GOTO=\"net_end\"" + ;; + esac + # The GOTO prevents us from trying to ifup the same device twice + done + echo 'LABEL="net_end"' + + for iface in $IFACES; do + if [ "$bootdev" = "$iface" ] || [ "$NEEDNET" = "1" ]; then + if [ -n "$netroot" ] && [ -n "$DRACUT_SYSTEMD" ]; then + echo "systemctl is-active initrd-root-device.target || [ -f /tmp/net.${iface}.did-setup ]" + else + echo "[ -f /tmp/net.${iface}.did-setup ]" + fi > "$hookdir"/initqueue/finished/wait-"$iface".sh + fi + done + # Default: We don't know the interface to use, handle all + # Fixme: waiting for the interface as well. + else + cond='ACTION=="add", SUBSYSTEM=="net", ENV{DEVTYPE}!="wlan|wwan"' + # if you change the name of "91-default-net.rules", also change modules.d/80cms/cmssetup.sh + echo "$cond, $runcmd" > /etc/udev/rules.d/91-default-net.rules + if [ "$NEEDNET" = "1" ]; then + # shellcheck disable=SC2016 + echo 'for i in /tmp/net.*.did-setup; do [ -f "$i" ] && exit 0; done; exit 1' > "$hookdir"/initqueue/finished/wait-network.sh + fi + fi + + # if you change the name of "90-net.rules", also change modules.d/80cms/cmssetup.sh +} > /etc/udev/rules.d/90-net.rules diff --git a/modules.d/35network-legacy/parse-bond.sh b/modules.d/35network-legacy/parse-bond.sh new file mode 100755 index 0000000..ba30a3b --- /dev/null +++ b/modules.d/35network-legacy/parse-bond.sh @@ -0,0 +1,76 @@ +#!/bin/sh +# +# Format: +# bond=<bondname>[:<bondslaves>[:<options>[:<mtu>]]] +# +# bondslaves is a comma-separated list of physical (ethernet) interfaces +# options is a comma-separated list on bonding options (modinfo bonding for details) in format compatible with initscripts +# if options include multi-valued arp_ip_target option, then its values should be separated by semicolon. +# +# bond without parameters assumes bond=bond0:eth0,eth1:mode=balance-rr +# +# if the mtu is specified, it will be set on the bond master +# + +# We translate list of slaves to space-separated here to make it easier to loop over them in ifup +# Ditto for bonding options +parsebond() { + local v="${1}": + set -- + while [ -n "$v" ]; do + set -- "$@" "${v%%:*}" + v=${v#*:} + done + + case $# in + 0) + bondname=bond0 + bondslaves="eth0 eth1" + ;; + 1) + bondname=$1 + bondslaves="eth0 eth1" + ;; + 2) + bondname=$1 + bondslaves=$(str_replace "$2" "," " ") + ;; + 3) + bondname=$1 + bondslaves=$(str_replace "$2" "," " ") + bondoptions=$(str_replace "$3" "," " ") + ;; + 4) + bondname=$1 + bondslaves=$(str_replace "$2" "," " ") + bondoptions=$(str_replace "$3" "," " ") + bondmtu=$4 + ;; + *) die "bond= requires zero to four parameters" ;; + esac +} + +# Parse bond for bondname, bondslaves, bondmode, bondoptions and bondmtu +for bond in $(getargs bond=); do + unset bondname + unset bondslaves + unset bondoptions + unset bondmtu + if [ "$bond" != "bond" ]; then + parsebond "$bond" + fi + # Simple default bond + if [ -z "$bondname" ]; then + bondname=bond0 + bondslaves="eth0 eth1" + fi + # Make it suitable for initscripts export + bondoptions=$(str_replace "$bondoptions" ";" ",") + + { + echo "bondname=$bondname" + echo "bondslaves=\"$bondslaves\"" + echo "bondoptions=\"$bondoptions\"" + echo "bondmtu=\"$bondmtu\"" + } > "/tmp/bond.${bondname}.info" +done diff --git a/modules.d/35network-legacy/parse-bridge.sh b/modules.d/35network-legacy/parse-bridge.sh new file mode 100755 index 0000000..caea1da --- /dev/null +++ b/modules.d/35network-legacy/parse-bridge.sh @@ -0,0 +1,49 @@ +#!/bin/sh +# +# Format: +# bridge=<bridgename>:<bridgeslaves> +# +# <bridgeslaves> is a comma-separated list of physical (ethernet) interfaces +# bridge without parameters assumes bridge=br0:eth0 +# + +parsebridge() { + local v="${1}": + set -- + while [ -n "$v" ]; do + set -- "$@" "${v%%:*}" + v=${v#*:} + done + case $# in + 0) + bridgename=br0 + bridgeslaves=$iface + ;; + 1) die "bridge= requires two parameters" ;; + 2) + bridgename=$1 + bridgeslaves=$(str_replace "$2" "," " ") + ;; + *) die "bridge= requires two parameters" ;; + esac +} + +# Parse bridge for bridgename and bridgeslaves +for bridge in $(getargs bridge=); do + unset bridgename + unset bridgeslaves + iface=eth0 + # Read bridge= parameters if they exist + if [ "$bridge" != "bridge" ]; then + parsebridge "$bridge" + fi + # Simple default bridge + if [ -z "$bridgename" ]; then + bridgename=br0 + bridgeslaves=$iface + fi + { + echo "bridgename=$bridgename" + echo "bridgeslaves=\"$bridgeslaves\"" + } > /tmp/bridge.${bridgename}.info +done diff --git a/modules.d/35network-legacy/parse-ibft.sh b/modules.d/35network-legacy/parse-ibft.sh new file mode 100755 index 0000000..1937f13 --- /dev/null +++ b/modules.d/35network-legacy/parse-ibft.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +command -v getarg > /dev/null || . /lib/dracut-lib.sh +command -v ibft_to_cmdline > /dev/null || . /lib/net-lib.sh + +if getargbool 0 rd.iscsi.ibft -d "ip=ibft"; then + modprobe -b -q iscsi_boot_sysfs 2> /dev/null + modprobe -b -q iscsi_ibft + ibft_to_cmdline +fi diff --git a/modules.d/35network-legacy/parse-ifname.sh b/modules.d/35network-legacy/parse-ifname.sh new file mode 100755 index 0000000..be7b6ad --- /dev/null +++ b/modules.d/35network-legacy/parse-ifname.sh @@ -0,0 +1,24 @@ +#!/bin/sh +# +# Format: +# ifname=<interface>:<mac> +# +# Note letters in the macaddress must be lowercase! +# +# Examples: +# ifname=eth0:4a:3f:4c:04:f8:d7 +# +# Note when using ifname= to get persistent interface names, you must specify +# an ifname= argument for each interface used in an ip= or fcoe= argument + +# check if there are any ifname parameters +if ! getarg ifname= > /dev/null; then + return +fi + +command -v parse_ifname_opts > /dev/null || . /lib/net-lib.sh + +# Check ifname= lines +for p in $(getargs ifname=); do + parse_ifname_opts "$p" +done diff --git a/modules.d/35network-legacy/parse-ip-opts.sh b/modules.d/35network-legacy/parse-ip-opts.sh new file mode 100755 index 0000000..8263321 --- /dev/null +++ b/modules.d/35network-legacy/parse-ip-opts.sh @@ -0,0 +1,151 @@ +#!/bin/sh +# +# Format: +# ip=[dhcp|on|any|single-dhcp] +# +# ip=<interface>:[dhcp|on|any][:[<mtu>][:<macaddr>]] +# +# ip=<client-IP-number>:<server-IP-number>:<gateway-IP-number>:<netmask>:<client-hostname>:<interface>:{dhcp|on|any|none|off}[:[<mtu>][:<macaddr>]] +# +# When supplying more than only ip= line, <interface> is mandatory and +# bootdev= must contain the name of the primary interface to use for +# routing,dns,dhcp-options,etc. +# + +# we really need to use `expr substr` with dash +# shellcheck disable=SC2003 disable=SC2308 + +command -v getarg > /dev/null || . /lib/dracut-lib.sh + +if [ -n "$netroot" ] && [ -z "$(getarg ip=)" ] && [ -z "$(getarg BOOTIF=)" ]; then + # No ip= argument(s) for netroot provided, defaulting to DHCP + return +fi + +# Count ip= lines to decide whether we need bootdev= or not +if [ -z "$NEEDBOOTDEV" ]; then + count=0 + for p in $(getargs ip=); do + case "$p" in + ibft) + continue + ;; + esac + count=$((count + 1)) + done + [ $count -gt 1 ] && NEEDBOOTDEV=1 +fi +unset count + +# If needed, check if bootdev= contains anything usable +BOOTDEV=$(getarg bootdev=) + +if [ -n "$NEEDBOOTDEV" ] && getargbool 1 rd.neednet; then + #[ -z "$BOOTDEV" ] && warn "Please supply bootdev argument for multiple ip= lines" + echo "rd.neednet=1" > /etc/cmdline.d/dracut-neednet.conf + info "Multiple ip= arguments: assuming rd.neednet=1" +else + unset NEEDBOOTDEV +fi + +# Check ip= lines +# XXX Would be nice if we could errorcheck ip addresses here as well +for p in $(getargs ip=); do + ip_to_var "$p" + + # make first device specified the BOOTDEV + if [ -n "$NEEDBOOTDEV" ] && [ -z "$BOOTDEV" ] && [ -n "$dev" ]; then + BOOTDEV="$dev" + info "Setting bootdev to '$BOOTDEV'" + fi + + # skip ibft since we did it above + [ "$autoconf" = "ibft" ] && continue + + # Empty autoconf defaults to 'dhcp' + if [ -z "$autoconf" ]; then + warn "Empty autoconf values default to dhcp" + autoconf="dhcp" + fi + + # Error checking for autoconf in combination with other values + for autoopt in $(str_replace "$autoconf" "," " "); do + case $autoopt in + error) die "Error parsing option 'ip=$p'" ;; + bootp | rarp | both) die "Sorry, ip=$autoopt is currently unsupported" ;; + none | off) + [ -z "$ip" ] \ + && die "For argument 'ip=$p'\nValue '$autoopt' without static configuration does not make sense" + [ -z "$mask" ] \ + && die "Sorry, automatic calculation of netmask is not yet supported" + ;; + auto6 | link6) ;; + either6) ;; + dhcp | dhcp6 | on | any | single-dhcp) + [ -n "$NEEDBOOTDEV" ] && [ -z "$dev" ] \ + && die "Sorry, 'ip=$p' does not make sense for multiple interface configurations" + [ -n "$ip" ] \ + && die "For argument 'ip=$p'\nSorry, setting client-ip does not make sense for '$autoopt'" + ;; + *) die "For argument 'ip=$p'\nSorry, unknown value '$autoopt'" ;; + esac + done + + if [ -n "$dev" ]; then + # We don't like duplicate device configs + if [ -n "$IFACES" ]; then + for i in $IFACES; do + [ "$dev" = "$i" ] && die "For argument 'ip=$p'\nDuplication configurations for '$dev'" + done + fi + # IFACES list for later use + IFACES="$IFACES $dev" + + # Interface should exist + if [ ! -e "/sys/class/net/$dev" ]; then + warn "Network interface '$dev' does not exist" + fi + fi + + # Do we need to check for specific options? + if [ -n "$NEEDDHCP" ] || [ -n "$DHCPORSERVER" ]; then + # Correct device? (Empty is ok as well) + [ "$dev" = "$BOOTDEV" ] || continue + # Server-ip is there? + [ -n "$DHCPORSERVER" ] && [ -n "$srv" ] && continue + # dhcp? (It's simpler to check for a set ip. Checks above ensure that if + # ip is there, we're static + [ -z "$ip" ] && continue + # Not good! + die "Server-ip or dhcp for netboot needed, but current arguments say otherwise" + fi + + if str_starts "$dev" "enx" && [ ${#dev} -eq 15 ]; then + # shellcheck disable=SC2003 + printf -- "ifname=%s:%s:%s:%s:%s:%s:%s\n" \ + "$dev" \ + "$(expr substr "$dev" 3 2)" \ + "$(expr substr "$dev" 5 2)" \ + "$(expr substr "$dev" 7 2)" \ + "$(expr substr "$dev" 9 2)" \ + "$(expr substr "$dev" 11 2)" \ + "$(expr substr "$dev" 13 2)" \ + >> /etc/cmdline.d/80-enx.conf + fi +done + +# put BOOTIF in IFACES to make sure it comes up +if getargbool 1 "rd.bootif" && BOOTIF="$(getarg BOOTIF=)"; then + BOOTDEV=$(fix_bootif "$BOOTIF") + IFACES="$BOOTDEV $IFACES" +fi + +# This ensures that BOOTDEV is always first in IFACES +if [ -n "$BOOTDEV" ] && [ -n "$IFACES" ]; then + IFACES="${IFACES%"$BOOTDEV"*} ${IFACES#*"$BOOTDEV"}" + IFACES="$BOOTDEV $IFACES" +fi + +# Store BOOTDEV and IFACES for later use +[ -n "$BOOTDEV" ] && echo "$BOOTDEV" > /tmp/net.bootdev +[ -n "$IFACES" ] && echo "$IFACES" > /tmp/net.ifaces diff --git a/modules.d/35network-legacy/parse-team.sh b/modules.d/35network-legacy/parse-team.sh new file mode 100755 index 0000000..83badc9 --- /dev/null +++ b/modules.d/35network-legacy/parse-team.sh @@ -0,0 +1,66 @@ +#!/bin/sh +# +# Format: +# team=<teammaster>:<teamslaves>[:<teamrunner>] +# +# teamslaves is a comma-separated list of physical (ethernet) interfaces +# teamrunner is the runner type to be used (see teamd.conf(5)); defaults to activebackup +# +# team without parameters assumes team=team0:eth0,eth1:activebackup +# + +parseteam() { + local v="${1}": + set -- + while [ -n "$v" ]; do + set -- "$@" "${v%%:*}" + v=${v#*:} + done + + case $# in + 0) + teammaster=team0 + teamslaves="eth0 eth1" + teamrunner="activebackup" + ;; + 1) + teammaster=$1 + teamslaves="eth0 eth1" + teamrunner="activebackup" + ;; + 2) + teammaster=$1 + teamslaves=$(str_replace "$2" "," " ") + teamrunner="activebackup" + ;; + 3) + teammaster=$1 + teamslaves=$(str_replace "$2" "," " ") + teamrunner=$3 + ;; + *) die "team= requires zero to three parameters" ;; + esac + return 0 +} + +for team in $(getargs team); do + [ "$team" = "team" ] && continue + + unset teammaster + unset teamslaves + unset teamrunner + + parseteam "$team" || continue + + { + echo "teammaster=$teammaster" + echo "teamslaves=\"$teamslaves\"" + echo "teamrunner=\"$teamrunner\"" + } > /tmp/team."${teammaster}".info + + if ! [ -e /etc/teamd/"${teammaster}".conf ]; then + warn "Team master $teammaster specified, but no /etc/teamd/$teammaster.conf present. Using $teamrunner." + mkdir -p /etc/teamd + printf -- "%s" "{\"runner\": {\"name\": \"$teamrunner\"}, \"link_watch\": {\"name\": \"ethtool\"}}" > "/tmp/${teammaster}.conf" + fi +done diff --git a/modules.d/35network-legacy/parse-vlan.sh b/modules.d/35network-legacy/parse-vlan.sh new file mode 100755 index 0000000..c23f833 --- /dev/null +++ b/modules.d/35network-legacy/parse-vlan.sh @@ -0,0 +1,37 @@ +#!/bin/sh +# +# Format: +# vlan=<vlanname>:<phydevice> +# + +parsevlan() { + local v="${1}": + set -- + while [ -n "$v" ]; do + set -- "$@" "${v%%:*}" + v=${v#*:} + done + + unset vlanname phydevice + case $# in + 2) + vlanname=$1 + phydevice=$2 + ;; + *) die "vlan= requires two parameters" ;; + esac +} + +for vlan in $(getargs vlan=); do + unset vlanname + unset phydevice + if [ ! "$vlan" = "vlan" ]; then + parsevlan "$vlan" + fi + + echo "phydevice=\"$phydevice\"" > /tmp/vlan."${phydevice}".phy + { + echo "vlanname=\"$vlanname\"" + echo "phydevice=\"$phydevice\"" + } > /tmp/vlan."${vlanname}"."${phydevice}" +done |