summaryrefslogtreecommitdiffstats
path: root/builder/modules.d/slx-network/scripts/setup-bootif-network.stage3
blob: 507188949859dc135448fe39b421353e00e74f6c (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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/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" 300; 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
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

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" "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
} &>> "/run/openslx/initramfs-network.log.$$"