summaryrefslogtreecommitdiffstats
path: root/builder/modules.d/slx-network/scripts/setup-bootif-network.stage3
blob: 4535ccd369887c3df09520e6a2fc80ba22aceb13 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/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

# guard to not run until the phsyical interface is not ready yet
if [ ! -e "/sys/class/net/${SLX_PXE_NETIF}/device" ]; then
	exit 1
fi

wait_for_iface() {
	local _iface="$1"
	local _timeout="${2:-50}"
	while [ "$_timeout" -ne 0 ]; do
		[ "$(cat /sys/class/net/${_iface}/operstate)" = "up" ] && break
		(( _timeout -- ))
		usleep 100000
	done
	[ "$_timeout" -ne 0 ]
}

# For debugging...
{
set -x

ip link set dev "$SLX_PXE_NETIF" up
if ! wait_for_iface "$SLX_PXE_NETIF" 100; then
	warn "'$SLX_PXE_NETIF' still not up after 10sec ... trying anyway."
	# TODO handle case where we waited for 10sec 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
if [ -n "$SLX_PXE_CLIENT_IP" ]; then
	ip addr add \
		"${SLX_PXE_CLIENT_IP}/$(ipcalc -s -p "$SLX_PXE_CLIENT_IP" "$SLX_PXE_NETMASK" | sed "s/.*=//")" \
		broadcast "$(ipcalc -s -b "$SLX_PXE_CLIENT_IP" "$SLX_PXE_NETMASK" | sed "s/.*=//")" \
		dev "$MAIN_NETIF"
fi

if [ "$USE_DHCP_UUID" = "yes" ] && [ -s "/run/system-uuid" ]; then
	UUID="$(cat /run/system-uuid)"
fi

# 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}" \
		"${SLX_PXE_CLIENT_IP:+-r $SLX_PXE_CLIENT_IP}" \
		"${UUID:+-x 0x3d:$UUID}" \
		-O ntpsrv -O domain -O wpad -O search -O nisdomain \
		-s "/usr/local/bin/udhcpc-trigger"
	# success?
	[ "$?" -eq 0 ] && break
	# nope, keep trying...
	warn "DHCP failed, retrying in 1sec..."
	sleep $i
done

set +x
} &>> "/run/openslx/initramfs-network.log.$$"