blob: 7a2d7410ec1b79c644dffdcb01e36c38711b83a5 (
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
|
#!/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
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.$$"
|