blob: 1f8fb9ee93f744a397bf8f93c35473a881394e35 (
plain) (
tree)
|
|
#!/bin/bash
#
# This script sets up the main network interface we booted from,
# as designated by SLX_PXE_NETIF (parsed from the PXE KCL in the
# cmdline dracut hook).
# It is run inside dracut's initqueue, on settles to detect the
# physical network interface as fast as possible.
type emergency_shell >/dev/null 2>&1 || . /lib/dracut-lib.sh
. /run/openslx/network.conf
# do not run until the physical interface is not ready yet
if [ ! -e "/sys/class/net/${SLX_PXE_NETIF}/device" ]; then
exit 1
fi
# wrapper around splashtool to disable it if its not present
_splashtool() {
:
}
if grep -wq splash /proc/cmdline && hash splashtool &> /dev/null; then
_splashtool() {
splashtool "$@"
}
fi
wait_for_iface() {
local _iface="$1"
local _timeout="${2:-50}"
if [ "$_iface" = "$SLX_PXE_NETIF" ]; then
img="??-nic"
elif [ "$_iface" = "$SLX_BRIDGE" ]; then
img="??-bridge"
fi
while [ "$_timeout" -ne 0 ]; do
[ "$(cat /sys/class/net/${_iface}/operstate)" = "up" ] && break
(( _timeout -- ))
# every 500ms
usleep 500000
in=
[ "$(( _timeout % 2 ))" = 0 ] && in=in
_splashtool --icon "/opt/openslx/icons/${in}active/${img}.ppm" &
done
if [ "$_timeout" -ne 0 ]; then
_splashtool --icon "/opt/openslx/icons/active/${img}.ppm" &
return 0
else
_splashtool --icon "/opt/openslx/icons/inactive/${img}.ppm" &
return 1
fi
}
# For debugging...
{
set -x
ip link set dev "$SLX_PXE_NETIF" up
if ! wait_for_iface "$SLX_PXE_NETIF" 60; then
warn "'$SLX_PXE_NETIF' still not up after 30sec ... trying anyway."
# TODO handle case where we waited for 30sec and it is still not up
fi
# now determine whether we are in bridged/vlan/plain mode
MAIN_NETIF="$SLX_PXE_NETIF"
if [ -n "$SLX_VLAN_ID" ]; then
# create VLAN interface
modprobe 8021q || warn "Loading '8021q' failed - missing module?"
ip link add link "$SLX_PXE_NETIF" name "${SLX_PXE_NETIF}.${SLX_VLAN_ID}" \
type vlan id "$SLX_VLAN_ID"
ip link set dev "${SLX_PXE_NETIF}.${SLX_VLAN_ID}" up
if wait_for_iface "${SLX_PXE_NETIF}.${SLX_VLAN_ID}"; then
MAIN_NETIF="${SLX_PXE_NETIF}.${SLX_VLAN_ID}"
else
warn "Setting up VLAN '$SLX_VLAN_ID' failed, trying plain..."
fi
fi
if [ -n "$SLX_BRIDGE" ]; then
for try in {1..10} ""; do
(
set -e
brctl addbr "$SLX_BRIDGE"
brctl stp "$SLX_BRIDGE" 0
brctl setfd "$SLX_BRIDGE" 0.000000000001
ip link set addr "$SLX_PXE_MAC" "$SLX_BRIDGE"
brctl addif "$SLX_BRIDGE" "$MAIN_NETIF"
ip link set dev "$SLX_BRIDGE" up
wait_for_iface "$SLX_BRIDGE"
)
# success?
if [ "$?" -eq 0 ]; then
MAIN_NETIF="$SLX_BRIDGE"
break
fi
# nope, handle
if [ -z "$try" ]; then
emergency_shell "Failed to setup main network bridge, giving up!"
fi
warn "Failed to setup main network bridge on try $try. Retrying ..."
# delete bridge, inc try and sleep 100ms before trying again
[ -e "/sys/class/net/${SLX_BRIDGE}" ] && brctl delbr "$SLX_BRIDGE"
usleep 100000
done
fi
# Finally add the IP address on the main NIC.
# Note: we should never have ip & netmask without the other.
if [ -n "$SLX_PXE_CLIENT_IP" ] && [ -n "$SLX_PXE_NETMASK" ]; then
ip addr add "${SLX_PXE_CLIENT_IP}/${SLX_PXE_NETMASK}" dev "$MAIN_NETIF"
# now if we got everything from the KCL and skip dhcp if so
if [ -n "$SLX_PXE_GATEWAY" ] && [ -n "$SLX_PXE_DNS" ]; then
info "Got network configuration from KCL, skipping DHCP."
if ! interface="$MAIN_NETIF" \
ip="$SLX_PXE_CLIENT_IP" \
router="$SLX_PXE_GATEWAY" \
dns="$SLX_PXE_DNS" \
hostname="$SLX_PXE_HOSTNAME" \
/usr/local/bin/udhcpc-trigger bound; then
warn "Failed to launch DHCP trigger with KCL configuration - will DHCP."
fi
exit 0
fi
fi
## DHCP
# Try to work around some buggy e1000e variants by waiting a bit
sleep 1
additional_opts=()
# we need to send the same UID (without '-') as the PXE firmware did, so use the plain
# one read with dmidecode (and not the one by get-system-uuid).
if [ "$USE_DHCP_UUID" = "yes" ]; then
UID="$(dmidecode -s system-uuid | sed -r 's/^(..)(..)(..)(..)-(..)(..)-(..)(..)-(....)-/00\4\3\2\1\6\5\8\7\9/')"
if [ "${#UID}" = 34 ]; then
echo "Using SMBIOS UID for DHCP"
additional_opts+=("-x" "0x3d:$UID")
fi
fi
if [ -n "$SLX_PXE_CLIENT_IP" ]; then
additional_opts+=("-r" "$SLX_PXE_CLIENT_IP")
fi
# DHCP options to request
request_opts=("-O" "hostname")
request_opts+=("-O" "dns")
request_opts+=("-O" "ntpsrv")
request_opts+=("-O" "domain")
request_opts+=("-O" "wpad")
request_opts+=("-O" "search")
request_opts+=("-O" "nisdomain")
# udhcpc
for i in 1 1 1 fail; do
[ "$i" = "fail" ] && emergency_shell "DHCP failed 3 times... cannot continue."
udhcpc -t 4 -T 3 -f -n -q \
-i "${MAIN_NETIF}" \
"${request_opts[@]}" \
"${additional_opts[@]}" \
-s "/usr/local/bin/udhcpc-trigger"
# success?
[ "$?" -eq 0 ] && break
# nope, keep trying...
warn "DHCP failed, retrying in 1sec..."
sleep $i
done
set +x
} {BASH_XTRACEFD}> "/run/openslx/initramfs-network.log.$$"
|