public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
From: Pavel Valena <pvalena@redhat.com>
To: git-commits@fedoraproject.org
Subject: [rpms/dracut] rawhide: fix: various dhcp-related issues
Date: Wed, 17 Jun 2026 14:33:39 GMT [thread overview]
Message-ID: <178170681953.1.16693885681399144877.rpms-dracut-afdb098fe2f3@fedoraproject.org> (raw)
A new commit has been pushed.
Repo : rpms/dracut
Branch : rawhide
Commit : afdb098fe2f34ea675aa00e9b6dd0887c1c8030e
Author : Pavel Valena <pvalena@redhat.com>
Date : 2026-06-17T16:33:02+02:00
Stats : +2036/-1 in 6 file(s)
URL : https://src.fedoraproject.org/rpms/dracut/c/afdb098fe2f34ea675aa00e9b6dd0887c1c8030e?branch=rawhide
Log:
fix: various dhcp-related issues
From-source-git-commit: 6fcbaa90d87d0f6ff3a24f85500341559e97b696
---
diff --git a/0010-fix-network-legacy-remove-network-legacy-completely-.patch b/0010-fix-network-legacy-remove-network-legacy-completely-.patch
new file mode 100644
index 0000000..10c3b02
--- /dev/null
+++ b/0010-fix-network-legacy-remove-network-legacy-completely-.patch
@@ -0,0 +1,1753 @@
+From 2b6302d54965dd354768e5f8509a5e9eb5853754 Mon Sep 17 00:00:00 2001
+From: Pavel Valena <pvalena@redhat.com>
+Date: Thu, 7 May 2026 00:40:31 +0200
+Subject: [PATCH 10/14] fix(network-legacy): remove network-legacy completely
+ from the codebase
+
+(To not rely solely on a dracut.spec file.)
+---
+ modules.d/35network-legacy/dhclient-script.sh | 275 ---------
+ modules.d/35network-legacy/dhclient.conf | 11 -
+ modules.d/35network-legacy/dhcp-multi.sh | 133 -----
+ modules.d/35network-legacy/ifup.sh | 562 ------------------
+ modules.d/35network-legacy/kill-dhclient.sh | 15 -
+ modules.d/35network-legacy/module-setup.sh | 94 ---
+ modules.d/35network-legacy/net-genrules.sh | 125 ----
+ modules.d/35network-legacy/parse-bond.sh | 76 ---
+ modules.d/35network-legacy/parse-bridge.sh | 49 --
+ modules.d/35network-legacy/parse-ibft.sh | 10 -
+ modules.d/35network-legacy/parse-ifname.sh | 24 -
+ modules.d/35network-legacy/parse-ip-opts.sh | 151 -----
+ modules.d/35network-legacy/parse-team.sh | 66 --
+ modules.d/35network-legacy/parse-vlan.sh | 37 --
+ 14 files changed, 1628 deletions(-)
+ delete mode 100755 modules.d/35network-legacy/dhclient-script.sh
+ delete mode 100644 modules.d/35network-legacy/dhclient.conf
+ delete mode 100755 modules.d/35network-legacy/dhcp-multi.sh
+ delete mode 100755 modules.d/35network-legacy/ifup.sh
+ delete mode 100755 modules.d/35network-legacy/kill-dhclient.sh
+ delete mode 100755 modules.d/35network-legacy/module-setup.sh
+ delete mode 100755 modules.d/35network-legacy/net-genrules.sh
+ delete mode 100755 modules.d/35network-legacy/parse-bond.sh
+ delete mode 100755 modules.d/35network-legacy/parse-bridge.sh
+ delete mode 100755 modules.d/35network-legacy/parse-ibft.sh
+ delete mode 100755 modules.d/35network-legacy/parse-ifname.sh
+ delete mode 100755 modules.d/35network-legacy/parse-ip-opts.sh
+ delete mode 100755 modules.d/35network-legacy/parse-team.sh
+ delete mode 100755 modules.d/35network-legacy/parse-vlan.sh
+
+diff --git a/modules.d/35network-legacy/dhclient-script.sh b/modules.d/35network-legacy/dhclient-script.sh
+deleted file mode 100755
+index 6751f2d6..00000000
+--- a/modules.d/35network-legacy/dhclient-script.sh
++++ /dev/null
+@@ -1,275 +0,0 @@
+-#!/bin/sh
+-
+-PATH=/usr/sbin:/usr/bin:/sbin:/bin
+-
+-command -v getarg > /dev/null || . /lib/dracut-lib.sh
+-command -v ip_to_var > /dev/null || . /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 ] && [ "$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 ] || [ "$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
+deleted file mode 100644
+index ffd24ef6..00000000
+--- a/modules.d/35network-legacy/dhclient.conf
++++ /dev/null
+@@ -1,11 +0,0 @@
+-
+-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
+deleted file mode 100755
+index 1c5ee733..00000000
+--- a/modules.d/35network-legacy/dhcp-multi.sh
++++ /dev/null
+@@ -1,133 +0,0 @@
+-#!/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
+-
+-command -v getarg > /dev/null || . /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 -qs -F -- '--timeout'); 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
+deleted file mode 100755
+index b2ed4607..00000000
+--- a/modules.d/35network-legacy/ifup.sh
++++ /dev/null
+@@ -1,562 +0,0 @@
+-#!/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
+-
+-command -v getarg > /dev/null || . /lib/dracut-lib.sh
+-command -v ip_to_var > /dev/null || . /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
+-
+- /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 -qs -F -- '--timeout'); 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" ] && [ "${#value}" != "0" ] && [ "+${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" ] && [ "$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" ] && [ "$netroot" = "dhcp6" ]; then
+- load_ipv6
+- do_dhcp -6
+- ret=$?
+- fi
+- if getargs 'ip=dhcp' > /dev/null || [ -z "$ip" ] && [ "$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
+deleted file mode 100755
+index 9ed615fd..00000000
+--- a/modules.d/35network-legacy/kill-dhclient.sh
++++ /dev/null
+@@ -1,15 +0,0 @@
+-#!/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
+deleted file mode 100755
+index d7162ad5..00000000
+--- a/modules.d/35network-legacy/module-setup.sh
++++ /dev/null
+@@ -1,94 +0,0 @@
+-#!/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() {
+- echo net-lib kernel-network-modules initqueue
+- return 0
+-}
+-
+-# called by dracut
+-install() {
+- local _arch
+-
+- # Adding default link and (if exists) 98-default-mac-none.link
+- if dracut_module_included "systemd"; then
+- inst_multiple -o \
+- "${systemdnetwork}/99-default.link" \
+- "${systemdnetwork}/98-default-mac-none.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" ] || [ "${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.*"
+-}
+diff --git a/modules.d/35network-legacy/net-genrules.sh b/modules.d/35network-legacy/net-genrules.sh
+deleted file mode 100755
+index 13bcced3..00000000
+--- a/modules.d/35network-legacy/net-genrules.sh
++++ /dev/null
+@@ -1,125 +0,0 @@
+-#!/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
+deleted file mode 100755
+index ba30a3bc..00000000
+--- a/modules.d/35network-legacy/parse-bond.sh
++++ /dev/null
+@@ -1,76 +0,0 @@
+-#!/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
+deleted file mode 100755
+index d331f9d7..00000000
+--- a/modules.d/35network-legacy/parse-bridge.sh
++++ /dev/null
+@@ -1,49 +0,0 @@
+-#!/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
+deleted file mode 100755
+index 1937f138..00000000
+--- a/modules.d/35network-legacy/parse-ibft.sh
++++ /dev/null
+@@ -1,10 +0,0 @@
+-#!/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
+deleted file mode 100755
+index be7b6ad6..00000000
+--- a/modules.d/35network-legacy/parse-ifname.sh
++++ /dev/null
+@@ -1,24 +0,0 @@
+-#!/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
+deleted file mode 100755
+index eea71e40..00000000
+--- a/modules.d/35network-legacy/parse-ip-opts.sh
++++ /dev/null
+@@ -1,151 +0,0 @@
+-#!/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/20-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/20-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
+deleted file mode 100755
+index 83badc99..00000000
+--- a/modules.d/35network-legacy/parse-team.sh
++++ /dev/null
+@@ -1,66 +0,0 @@
+-#!/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
+deleted file mode 100755
+index c23f8331..00000000
+--- a/modules.d/35network-legacy/parse-vlan.sh
++++ /dev/null
+@@ -1,37 +0,0 @@
+-#!/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
+--
+2.54.0
+
diff --git a/0011-fix-iscsi-replace-echo-writes-with-printf-to-prevent.patch b/0011-fix-iscsi-replace-echo-writes-with-printf-to-prevent.patch
new file mode 100644
index 0000000..dddcead
--- /dev/null
+++ b/0011-fix-iscsi-replace-echo-writes-with-printf-to-prevent.patch
@@ -0,0 +1,97 @@
+From 137076e2918518e02a54d88e6045930ee1024983 Mon Sep 17 00:00:00 2001
+From: Pavel Valena <pvalena@redhat.com>
+Date: Thu, 7 May 2026 00:45:31 +0200
+Subject: [PATCH 11/14] fix(iscsi): replace `echo` writes with `printf` to
+ prevent variable injection
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Use printf with explicit variable escaping `%q` for shell scripts:
+ - mount-lun.sh hookdir script (iscsi_lun variable)
+ - udev rule (iscsi_lun sanitized via tr -d '"')
+ - initiatorname.iscsi (sourced as shell at iscsiroot.sh:161-163)
+
+Note: initiatorname.iscsi is also read by iscsid as plain text (no
+shell unquoting). For valid IQNs ([a-z0-9.:_-]), %q is a no-op, so
+iscsid sees the value unchanged. For malicious values with special
+characters, %q would produce shell escaping that iscsid reads
+literally — breaking the connection rather than allowing injection.
+---
+ modules.d/74iscsi/iscsiroot.sh | 10 +++++-----
+ modules.d/74iscsi/parse-iscsiroot.sh | 4 ++--
+ 2 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/modules.d/74iscsi/iscsiroot.sh b/modules.d/74iscsi/iscsiroot.sh
+index 50b10259..50030e20 100755
+--- a/modules.d/74iscsi/iscsiroot.sh
++++ b/modules.d/74iscsi/iscsiroot.sh
+@@ -144,7 +144,7 @@ handle_netroot() {
+
+ if [ -z "$iscsi_initiator" ] && [ -f /sys/firmware/ibft/initiator/initiator-name ] && ! [ -f /tmp/iscsi_set_initiator ]; then
+ iscsi_initiator=$(while read -r line || [ -n "$line" ]; do echo "$line"; done < /sys/firmware/ibft/initiator/initiator-name)
+- echo "InitiatorName=$iscsi_initiator" > /run/initiatorname.iscsi
++ printf 'InitiatorName=%q\n' "$iscsi_initiator" > /run/initiatorname.iscsi
+ rm -f /etc/iscsi/initiatorname.iscsi
+ mkdir -p /etc/iscsi
+ ln -fs /run/initiatorname.iscsi /etc/iscsi/initiatorname.iscsi
+@@ -165,7 +165,7 @@ handle_netroot() {
+
+ if [ -z "$iscsi_initiator" ]; then
+ iscsi_initiator=$(iscsi-iname)
+- echo "InitiatorName=$iscsi_initiator" > /run/initiatorname.iscsi
++ printf 'InitiatorName=%q\n' "$iscsi_initiator" > /run/initiatorname.iscsi
+ rm -f /etc/iscsi/initiatorname.iscsi
+ mkdir -p /etc/iscsi
+ ln -fs /run/initiatorname.iscsi /etc/iscsi/initiatorname.iscsi
+@@ -189,7 +189,7 @@ handle_netroot() {
+ iscsi_lun=0
+ fi
+
+- echo "InitiatorName=$iscsi_initiator" > /run/initiatorname.iscsi
++ printf 'InitiatorName=%q\n' "$iscsi_initiator" > /run/initiatorname.iscsi
+ ln -fs /run/initiatorname.iscsi /dev/.initiatorname.iscsi
+ if ! [ -e /etc/iscsi/initiatorname.iscsi ]; then
+ mkdir -p /etc/iscsi
+@@ -210,14 +210,14 @@ handle_netroot() {
+
+ if [ "$root" = "dhcp" ] || [ "$netroot" = "dhcp" ]; then
+ # if root is not specified try to mount the whole iSCSI LUN
+- printf 'SYMLINK=="disk/by-path/*-iscsi-*-%s", SYMLINK+="root"\n' "$iscsi_lun" >> /etc/udev/rules.d/99-iscsi-root.rules
++ printf 'SYMLINK=="disk/by-path/*-iscsi-*-%s", SYMLINK+="root"\n' "$(printf '%s' "$iscsi_lun" | tr -d '"')" >> /etc/udev/rules.d/99-iscsi-root.rules
+ udevadm control --reload
+ write_fs_tab /dev/root
+ wait_for_dev -n /dev/root
+
+ # install mount script
+ [ -z "${DRACUT_SYSTEMD-}" ] \
+- && echo "iscsi_lun=$iscsi_lun . /bin/mount-lun.sh " > "$hookdir"/mount/01-$$-iscsi.sh
++ && printf 'iscsi_lun=%q . /bin/mount-lun.sh\n' "$iscsi_lun" > "$hookdir"/mount/01-$$-iscsi.sh
+ fi
+
+ if strglobin "$iscsi_target_ip" '*:*:*' && ! strglobin "$iscsi_target_ip" '['; then
+diff --git a/modules.d/74iscsi/parse-iscsiroot.sh b/modules.d/74iscsi/parse-iscsiroot.sh
+index 0b12d35b..95860804 100755
+--- a/modules.d/74iscsi/parse-iscsiroot.sh
++++ b/modules.d/74iscsi/parse-iscsiroot.sh
+@@ -111,7 +111,7 @@ fi
+
+ if arg=$(getarg rd.iscsi.initiator -d iscsi_initiator=) && [ -n "$arg" ] && ! [ -f /run/initiatorname.iscsi ]; then
+ iscsi_initiator=$arg
+- echo "InitiatorName=$iscsi_initiator" > /run/initiatorname.iscsi
++ printf 'InitiatorName=%q\n' "$iscsi_initiator" > /run/initiatorname.iscsi
+ ln -fs /run/initiatorname.iscsi /dev/.initiatorname.iscsi
+ rm -f /etc/iscsi/initiatorname.iscsi
+ mkdir -p /etc/iscsi
+@@ -127,7 +127,7 @@ fi
+ if [ -z "$iscsi_initiator" ] && [ -f /sys/firmware/ibft/initiator/initiator-name ] && ! [ -f /tmp/iscsi_set_initiator ]; then
+ iscsi_initiator=$(while read -r line || [ -n "$line" ]; do echo "$line"; done < /sys/firmware/ibft/initiator/initiator-name)
+ if [ -n "$iscsi_initiator" ]; then
+- echo "InitiatorName=$iscsi_initiator" > /run/initiatorname.iscsi
++ printf 'InitiatorName=%q\n' "$iscsi_initiator" > /run/initiatorname.iscsi
+ rm -f /etc/iscsi/initiatorname.iscsi
+ mkdir -p /etc/iscsi
+ ln -fs /run/initiatorname.iscsi /etc/iscsi/initiatorname.iscsi
+--
+2.54.0
+
diff --git a/0012-fix-base-escape-arguments-in-initqueue-hook-script-g.patch b/0012-fix-base-escape-arguments-in-initqueue-hook-script-g.patch
new file mode 100644
index 0000000..b35f24c
--- /dev/null
+++ b/0012-fix-base-escape-arguments-in-initqueue-hook-script-g.patch
@@ -0,0 +1,71 @@
+From d68df76ef94362270bb5ffc77eb5f4ed45363496 Mon Sep 17 00:00:00 2001
+From: Pavel Valena <pvalena@redhat.com>
+Date: Thu, 14 May 2026 14:20:17 +0200
+Subject: [PATCH 12/14] fix(base): escape arguments in initqueue hook script
+ generation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+initqueue.sh writes arguments directly into generated hook scripts
+via `echo "$exe" "$@"`. These scripts are later sourced by
+dracut-initqueue.sh, so shell metacharacters in arguments (e.g.
+DHCP-derived $netroot passed from parse-iscsiroot.sh) execute as
+root in initramfs.
+
+Replace `echo` with `printf '%q'` to shell-escape all arguments
+before writing them into the hook script, preventing command
+injection via DHCP-controlled netroot values.
+
+Remove the fragile embedded single-quote wrapping ("'$var'") from
+parse-iscsiroot.sh call sites (lines 90, 102) — those relied on
+echo writing quotes verbatim for the shell to strip when sourcing.
+With printf '%q', initqueue now handles escaping centrally, so the
+manual wrapping is no longer needed and would cause literal quote
+characters to leak into iscsiroot arguments.
+
+Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
+---
+ modules.d/74iscsi/parse-iscsiroot.sh | 4 ++--
+ modules.d/77initqueue/initqueue.sh | 3 ++-
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/modules.d/74iscsi/parse-iscsiroot.sh b/modules.d/74iscsi/parse-iscsiroot.sh
+index 95860804..b87f19a1 100755
+--- a/modules.d/74iscsi/parse-iscsiroot.sh
++++ b/modules.d/74iscsi/parse-iscsiroot.sh
+@@ -89,7 +89,7 @@ if [ -n "$iscsi_firmware" ]; then
+ echo "${DRACUT_SYSTEMD+systemctl is-active initrd-root-device.target || }[ -f '/tmp/iscsistarted-firmware' ]" > "$hookdir"/initqueue/finished/iscsi_started.sh
+ /sbin/initqueue --unique --online /sbin/iscsiroot online "iscsi:" "$NEWROOT"
+ /sbin/initqueue --unique --onetime --timeout /sbin/iscsiroot timeout "iscsi:" "$NEWROOT"
+- /sbin/initqueue --unique --onetime --settled /sbin/iscsiroot online "iscsi:" "'$NEWROOT'"
++ /sbin/initqueue --unique --onetime --settled /sbin/iscsiroot online "iscsi:" "$NEWROOT"
+ fi
+
+ # ISCSI actually supported?
+@@ -105,7 +105,7 @@ modprobe -b -q be2iscsi
+
+ if [ -n "$netroot" ] && [ "$root" != "/dev/root" ] && [ "$root" != "dhcp" ]; then
+ if ! getargbool 1 rd.neednet > /dev/null || ! getarg "ip="; then
+- /sbin/initqueue --unique --onetime --settled /sbin/iscsiroot dummy "'$netroot'" "'$NEWROOT'"
++ /sbin/initqueue --unique --onetime --settled /sbin/iscsiroot dummy "$netroot" "$NEWROOT"
+ fi
+ fi
+
+diff --git a/modules.d/77initqueue/initqueue.sh b/modules.d/77initqueue/initqueue.sh
+index 46a00d2a..1caa5273 100755
+--- a/modules.d/77initqueue/initqueue.sh
++++ b/modules.d/77initqueue/initqueue.sh
+@@ -64,7 +64,8 @@ fi
+ # shellcheck disable=SC2016
+ [ -n "$onetime" ] && echo '[ -e "$job" ] && rm -f -- "$job"'
+ [ -n "$env" ] && echo "$env"
+- echo "$exe" "$@"
++ printf '%q ' "$exe" "$@"
++ printf '\n'
+ } > "/tmp/$$-${job}.sh"
+
+ mv -f "/tmp/$$-${job}.sh" "$hookdir/initqueue${qname}/${job}.sh"
+--
+2.54.0
+
diff --git a/0013-fix-net-lib-warn-on-suspicious-shell-metacharacters-.patch b/0013-fix-net-lib-warn-on-suspicious-shell-metacharacters-.patch
new file mode 100644
index 0000000..12b68d4
--- /dev/null
+++ b/0013-fix-net-lib-warn-on-suspicious-shell-metacharacters-.patch
@@ -0,0 +1,46 @@
+From 111138c4241343b873e42dc108718e1ef62d398b Mon Sep 17 00:00:00 2001
+From: Pavel Valena <pvalena@redhat.com>
+Date: Thu, 14 May 2026 14:25:07 +0200
+Subject: [PATCH 13/14] fix(net-lib): warn on suspicious shell metacharacters
+ in hostname file
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+setup_net() sources /tmp/net.$netif.hostname as shell, which is written
+by dhclient-script.sh or ifup.sh. Add a defensive check that warns if
+the file contains shell metacharacters ($, `, ;, &, |, () that should
+never appear in a legitimate hostname, indicating possible DHCP-based
+command injection attempts.
+
+The file is still sourced for compatibility — the writer-side fix
+(printf '%q') already prevents execution of injected content.
+
+Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
+---
+ modules.d/45net-lib/net-lib.sh | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/modules.d/45net-lib/net-lib.sh b/modules.d/45net-lib/net-lib.sh
+index a0b87408..a9c5cd3e 100755
+--- a/modules.d/45net-lib/net-lib.sh
++++ b/modules.d/45net-lib/net-lib.sh
+@@ -131,8 +131,13 @@ setup_net() {
+ [ -e "/tmp/net.ifaces" ] && read -r IFACES < /tmp/net.ifaces
+ [ -z "$IFACES" ] && IFACES="$netif"
+ # run the scripts written by ifup
+- # shellcheck disable=SC1090
+- [ -e /tmp/net."$netif".hostname ] && . /tmp/net."$netif".hostname
++ if [ -e /tmp/net."$netif".hostname ]; then
++ if grep -qE '[$`;&|(]' /tmp/net."$netif".hostname 2> /dev/null; then
++ warn "setup_net $netif: /tmp/net.$netif.hostname contains suspicious shell metacharacters"
++ fi
++ # shellcheck disable=SC1090
++ . /tmp/net."$netif".hostname
++ fi
+ # shellcheck disable=SC1090
+ [ -e /tmp/net."$netif".override ] && . /tmp/net."$netif".override
+ # shellcheck disable=SC1090
+--
+2.54.0
+
diff --git a/0014-fix-systemd-networkd-escape-DHCP-lease-values-in-dhc.patch b/0014-fix-systemd-networkd-escape-DHCP-lease-values-in-dhc.patch
new file mode 100644
index 0000000..562db61
--- /dev/null
+++ b/0014-fix-systemd-networkd-escape-DHCP-lease-values-in-dhc.patch
@@ -0,0 +1,46 @@
+From 24d7e205f754236acae25498782b8af943c9b270 Mon Sep 17 00:00:00 2001
+From: Pavel Valena <pvalena@redhat.com>
+Date: Thu, 14 May 2026 16:08:00 +0200
+Subject: [PATCH 14/14] fix(systemd-networkd): escape DHCP lease values in
+ dhcpopts generation
+
+networkd-run.sh converts DHCP lease values (ROOT_PATH, NEXT_SERVER)
+into shell variable assignments written to /tmp/dhclient.<ifname>.dhcpopts,
+which is later sourced by netroot.sh, net-lib.sh, and nfs-lib.sh. The
+previous sed-based pipeline wrapped values in single quotes without
+escaping embedded single quotes, allowing a rogue DHCP server to inject
+arbitrary shell commands via a crafted ROOT_PATH or NEXT_SERVER value.
+
+Replace the grep|sed pipeline with a while-read loop that uses
+printf '%q' to shell-escape values before writing, consistent with how
+the NetworkManager equivalent (nm-run.sh) already handles this.
+
+Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
+---
+ modules.d/11systemd-networkd/networkd-run.sh | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/modules.d/11systemd-networkd/networkd-run.sh b/modules.d/11systemd-networkd/networkd-run.sh
+index b14a43f4..d4a94e19 100755
+--- a/modules.d/11systemd-networkd/networkd-run.sh
++++ b/modules.d/11systemd-networkd/networkd-run.sh
+@@ -12,10 +12,12 @@ for ifpath in /sys/class/net/*; do
+ leases_file="/run/systemd/netif/leases/$(cat "$ifpath"/ifindex)"
+ dhcpopts_file="/tmp/dhclient.${ifname}.dhcpopts"
+ if [ -r "$leases_file" ]; then
+- grep -E "^(NEXT_SERVER|ROOT_PATH)=" "$leases_file" \
+- | sed -e "s/NEXT_SERVER=/new_next_server='/" \
+- -e "s/ROOT_PATH=/new_root_path='/" \
+- -e "s/$/'/" > "$dhcpopts_file" || true
++ while IFS='=' read -r key val; do
++ case "$key" in
++ NEXT_SERVER) printf 'new_next_server=%q\n' "$val" ;;
++ ROOT_PATH) printf 'new_root_path=%q\n' "$val" ;;
++ esac
++ done < "$leases_file" > "$dhcpopts_file"
+ fi
+
+ source_hook initqueue/online "$ifname"
+--
+2.54.0
+
diff --git a/dracut.spec b/dracut.spec
index bede6ad..dc6183e 100644
--- a/dracut.spec
+++ b/dracut.spec
@@ -8,7 +8,7 @@
Name: dracut
Version: 109
-Release: 4%{?dist}
+Release: 5%{?dist}
Summary: Initramfs generator using udev
@@ -49,6 +49,21 @@ Patch8: 0008-fix-systemd-cryptsetup-load-libcryptsetup-via-dlopen.patch
# feat(systemd-sysext): include systemd-{sys,conf}ext-sysroot services
# Author: Vitaly Kuznetsov <vkuznets@redhat.com>
Patch9: 0009-feat-systemd-sysext-include-systemd-sys-conf-ext-sys.patch
+# fix(network-legacy): remove network-legacy completely from the codebase
+# Author: Pavel Valena <pvalena@redhat.com>
+Patch10: 0010-fix-network-legacy-remove-network-legacy-completely-.patch
+# fix(iscsi): replace `echo` writes with `printf` to prevent variable injection
+# Author: Pavel Valena <pvalena@redhat.com>
+Patch11: 0011-fix-iscsi-replace-echo-writes-with-printf-to-prevent.patch
+# fix(base): escape arguments in initqueue hook script generation
+# Author: Pavel Valena <pvalena@redhat.com>
+Patch12: 0012-fix-base-escape-arguments-in-initqueue-hook-script-g.patch
+# fix(net-lib): warn on suspicious shell metacharacters in hostname file
+# Author: Pavel Valena <pvalena@redhat.com>
+Patch13: 0013-fix-net-lib-warn-on-suspicious-shell-metacharacters-.patch
+# fix(systemd-networkd): escape DHCP lease values in dhcpopts generation
+# Author: Pavel Valena <pvalena@redhat.com>
+Patch14: 0014-fix-systemd-networkd-escape-DHCP-lease-values-in-dhc.patch
# Please use source-git to work with this spec file:
# HowTo: https://packit.dev/source-git/work-with-source-git
@@ -482,6 +497,13 @@ echo 'dracut_rescue_image="yes"' > $RPM_BUILD_ROOT%{dracutlibdir}/dracut.conf.d/
%{_prefix}/lib/kernel/install.d/51-dracut-rescue.install
%changelog
+* Wed Jun 17 2026 Pavel Valena <pvalena@redhat.com> - 109-5
+- fix(base): escape arguments in initqueue hook script generation
+- fix(net-lib): warn on suspicious shell metacharacters in hostname file
+- fix(systemd-networkd): escape DHCP lease values in dhcpopts generation
+- fix(network-legacy): remove network-legacy completely from the codebase
+- fix(iscsi): replace `echo` writes with `printf` to prevent variable injection
+
* Fri Jun 12 2026 Yaakov Selkowitz <yselkowi@redhat.com> - 109-4
- Rebuilt for openssl 4.0
reply other threads:[~2026-06-17 14:33 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=178170681953.1.16693885681399144877.rpms-dracut-afdb098fe2f3@fedoraproject.org \
--to=pvalena@redhat.com \
--cc=git-commits@fedoraproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox