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
|
#!/bin/bash
#
# Script parsing the kernel command line to get the IP configuration from
# (i)PXE. Supports either the older
# ip=<CLIENT_IP>:<PXE_SERVER_IP>:<GATEWAY>:<NETMASK> format or our new format
# consisting of 'ipv4.<attr>' key/value pairs. Valid attributes are: ip, router,
# dns, hostname, domain, search, if, ntpsrv, subnet.
command -v getarg >/dev/null || . /lib/dracut-lib.sh
# static names for the boot interface and its bridge
declare -rg bootif_name="boot0"
declare -rg bridge_name="br0"
# parse old syslinux style 'ip=...' and 'BOOTIF=...' parameters
parse_kcl_ip() {
declare -g if="$(getarg BOOTIF=)"
if [ -n "$if" ] && [ ${#if} -eq 20 ]; then
if="${if#???}"
if="${if//-/:}"
fi
local ip_line="$(getarg ip=)"
[ -z "$ip_line" ] && return 0
read -r ip bootsrv router subnet \
<<< $( awk -F: '{print $1" "$2" "$3" "$4}' <<< "${ip_line}" )
declare -g ip bootsrv router subnet
}
# parse new style 'ipv4.*=...' parameters
parse_kcl_ipv4() {
local param
for param in "ip" "router" "dns" "hostname" "domain" "search" "if" "ntpsrv" "subnet"; do
local current="$(getarg ipv4.${param}=)"
echo "ipv4.'$param'='$current'"
[ -z "$current" ] && continue
declare -g "${param}=${current}"
done
}
parse_kcl() {
# backwards compat for old style hostname/dns/domain
local conf
for conf in hostname dns domain; do
conf_value="$(getarg ${conf}=)"
if [ -n "$conf_value" ]; then
echo "legacy '$conf'='$conf_value'"
declare -g "${conf}=${conf_value}"
fi
done
# we assume (and we should) that both variants contain the
# same information if they are present simultaneously.
parse_kcl_ip
parse_kcl_ipv4
# if not boot server was given, use slxsrv
if [ -z "$bootsrv" ]; then
kclsrv="$(getarg slxsrv=)"
if [ -n "$kclsrv" ]; then
declare -g bootsrv="$kclsrv"
fi
fi
# calculate network mask
declare -g mask="$(ipcalc -s -p "$ip" "$subnet" | sed 's/.*=//')"
# vlan specified?
declare -g vlan="$(getarg vlan=)"
# Bridged the boot interface?
grep -wqE 'bridged' /proc/cmdline && declare -g bridged="y"
# Sanitize
if [[ $hostname = *.* ]]; then
[ -z "$domain" ] && domain="${hostname#*.}"
hostname="${hostname%%.*}"
echo "Fixed up to '$hostname' and '$domain'"
fi
domain="${domain%% *}"
}
save_network_config() {
declare -rg network_conf="/run/openslx/network.conf"
mkdir -p "${network_conf%/*}"
cat <<-EOF > "$network_conf"
SLX_PXE_CLIENT_IP='$ip'
SLX_PXE_SERVER_IP='$bootsrv'
SLX_PXE_GATEWAY='$router'
SLX_PXE_NETMASK='$mask'
SLX_PXE_SUBNET='$subnet'
SLX_PXE_MAC='$if'
SLX_PXE_NETIF='$bootif_name'
SLX_PXE_DNS='${dns//,/ }'
SLX_PXE_HOSTNAME='$hostname'
SLX_PXE_DOMAIN='${domain}'
SLX_PXE_SEARCH='${search//,/ }'
SLX_PXE_NTP='${ntpsrv//,/ }'
SLX_BRIDGE='${bridged:+${bridge_name}}'
SLX_VLAN_ID='$vlan'
EOF
echo "network.conf written."
}
# Create udev rule to rename the PXE boot interface to BOOTIF_NAME
create_udev_bootif_name_rule() {
if [ -z "$if" ]; then
echo "MAC address of boot interface not set!"
return 1
fi
# priority 70 < 80-net-name-slot.rules.
echo 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="'$if'", NAME="'$bootif_name'"' > /etc/udev/rules.d/70-pxe-boot-interface.rules
}
## MAIN ##
parse_kcl
if [ -z "$if" ]; then
emergency_shell "MAC address of primary interface not given on command line"
exit 1
fi
# Create the udev rule to rename the boot interface to the declared BOOTIF_NAME
create_udev_bootif_name_rule &
# Save network config for later use
save_network_config &
# set hostname asap
[ -n "$hostname" ] && echo "$hostname" > /proc/sys/kernel/hostname
wait
exit 0
|