summaryrefslogtreecommitdiffstats
path: root/builder/modules.d/systemd-networkd-ext
diff options
context:
space:
mode:
authorJonathan Bauer2017-08-03 11:19:48 +0200
committerJonathan Bauer2017-08-03 11:19:48 +0200
commit032af49e415855895e0408294c4ce9951e4c8096 (patch)
treee3d927d7dee1859a1849092811d36ef6eb821398 /builder/modules.d/systemd-networkd-ext
parentdeclare root directory instead of calling dirname ...all the time... (diff)
downloadsystemd-init-032af49e415855895e0408294c4ce9951e4c8096.tar.gz
systemd-init-032af49e415855895e0408294c4ce9951e4c8096.tar.xz
systemd-init-032af49e415855895e0408294c4ce9951e4c8096.zip
added systemd-networkd extension module
Diffstat (limited to 'builder/modules.d/systemd-networkd-ext')
-rw-r--r--builder/modules.d/systemd-networkd-ext/hooks/parse-kcl-for-networkd.sh98
-rwxr-xr-xbuilder/modules.d/systemd-networkd-ext/module-setup.sh49
2 files changed, 147 insertions, 0 deletions
diff --git a/builder/modules.d/systemd-networkd-ext/hooks/parse-kcl-for-networkd.sh b/builder/modules.d/systemd-networkd-ext/hooks/parse-kcl-for-networkd.sh
new file mode 100644
index 00000000..cdf080a3
--- /dev/null
+++ b/builder/modules.d/systemd-networkd-ext/hooks/parse-kcl-for-networkd.sh
@@ -0,0 +1,98 @@
+#!/bin/bash
+#
+# This script was mostly stolen from 40network/parse-ip-opts.sh. Its
+# actions are adapted to write .network files to /etc/systemd/network
+# in the initramfs instead o
+
+command -v getarg >/dev/null || . /lib/dracut-lib.sh
+
+main_work() {
+ local IPCONF="$(getarg ip=)"
+ local BOOTIF="$(getarg BOOTIF=)"
+
+ if [ -z "${IPCONF}" ] && [ -z "${BOOTIF}" ]; then
+ # No ip= argument(s) given by PXE, TODO try dhcp
+ return;
+ fi
+
+ # ip= is expected in following format (syslinux IPAPPEND3):
+ # <CLIENT_IP>:<PXE_SERVER_IP>:<GATEWAY_IP>:<NETMASK>
+ local CLIENT_IP=
+ local SERVER_IP=
+ local GATEWAY_IP=
+ local NETMASK=
+ read -r CLIENT_IP SERVER_IP GATEWAY_IP NETMASK <<< $( awk -F: '{print $1" "$2" "$3" "$4}' <<< "${IPCONF}" )
+
+ # BOOTIF= contains the MAC address of the boot interface
+ # and a hardware type prefix of length 2, e.g. "01-"
+ # So if BOOTIF has 20 chars, then we got the prefix.
+ # This needs to be stripped to get the MAC address only
+ [ -n "${BOOTIF}" ] && [ ${#BOOTIF} -eq 20 ] && BOOTIF="${BOOTIF#???}"
+ BOOTIF="$(tr '-' ':' <<< $BOOTIF)"
+
+ # TODO sanity checks
+
+ # Taken from parse-ip-opts.sh
+ # Convert the netmask to CIDR notation
+ if [[ "x$NETMASK" =~ ^x[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
+ CIDR=$(mask2cidr "$NETMASK")
+ elif [ -n "$NETMASK" -a "x${NETMASK//[0-9]/}" = 'x' ]; then
+ # The mask is already a prefix length (uint), so validate it
+ [[ "x$CLIENT_IP" == x*:*:* && "$NETMASK" -le 128 || "$NETMASK" -le 32 ]] && CIDR=$NETMASK
+ fi
+
+
+ # Generate network and link file for networkd
+ NETWORK_FILE=/etc/systemd/network/01-boot-lan.network
+ mkdir -p $(dirname $NETWORK_FILE)
+ echo '[Match]' > $NETWORK_FILE
+ echo 'Name=bootnet' >> $NETWORK_FILE
+ # Hardcode bootnet as our boot interface
+ [ -n "$BOOTIF" ] && echo "MACAddress=$BOOTIF" >> $NETWORK_FILE
+ echo '[Network]' >> $NETWORK_FILE
+ echo 'Bridge=br0' >> $NETWORK_FILE
+
+ ## Boot interface has 'bootnet' as dedicated name
+ LINK_FILE=/etc/systemd/network/00-boot-lan.link
+ echo '[Match]' > $LINK_FILE
+ [ -n "$BOOTIF" ] && echo "MACAddress=$BOOTIF" >> $LINK_FILE
+ echo '[Link]' >> $LINK_FILE
+ echo "Name=bootnet" >> $LINK_FILE
+
+ # HACK pro bridge setup
+ BRIDGE_DEV_CONF=/etc/systemd/network/10-bridge-lan.netdev
+ echo '[NetDev]' > $BRIDGE_DEV_CONF
+ echo 'Name=br0' >> $BRIDGE_DEV_CONF
+ echo 'Kind=bridge' >> $BRIDGE_DEV_CONF
+
+ BRIDGE_IF_CONF=/etc/systemd/network/11-bridge-lan.network
+ echo '[Match]' > $BRIDGE_IF_CONF
+ echo "Name=br0" >> $BRIDGE_IF_CONF
+ echo '[Network]' >> $BRIDGE_IF_CONF
+ [ -n "$CLIENT_IP" ] && echo "Address=${CLIENT_IP}/${CIDR:-24}" >> $BRIDGE_IF_CONF
+ [ -n "$GATEWAY_IP" ] && echo "Gateway=${GATEWAY_IP}" >> $BRIDGE_IF_CONF
+
+}
+# from parse-ip-opts.sh
+# Takes a netmask and outputs the corresponding CIDR
+# e.g.
+# mask2cidr 255.255.255.0
+# returns: 24
+function mask2cidr() {
+ local -i bits=0
+ for octet in ${1//./ }; do
+ for i in {0..8}; do
+ [ "$octet" -eq $(( 256 - (1 << i) )) ] && bits+=$((8-i)) && break
+ done
+ [ $i -eq 8 -a "$octet" -ne 0 ] && warn "Bad netmask $mask" && return
+ [ $i -gt 0 ] && break
+ done
+ echo $bits
+}
+
+main_work
+
+# HACK to wait for network during udev loop...
+touch /lib/dracut/need-initqueue
+/sbin/initqueue --finished /bin/busybox timeout -t 10 /lib/systemd/systemd-networkd-wait-online -i br0
+
diff --git a/builder/modules.d/systemd-networkd-ext/module-setup.sh b/builder/modules.d/systemd-networkd-ext/module-setup.sh
new file mode 100755
index 00000000..3b3aabd6
--- /dev/null
+++ b/builder/modules.d/systemd-networkd-ext/module-setup.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+
+# called by dracut
+check() {
+ if ! dracut_module_included "systemd-networkd"; then
+ derror "systemd-networkd-ext needs systemd-networkd in the initramfs"
+ return 1
+ fi
+
+ return 255
+}
+
+# called by dracut
+depends() {
+ echo "systemd-networkd"
+}
+
+installkernel() {
+ return 0
+}
+
+# called by dracut
+install() {
+ # need initqueue to get a clean network start
+ dracut_need_initqueue
+
+ inst_multiple -o \
+ $systemdutildir/systemd-networkd \
+ $systemdutildir/systemd-networkd-wait-online \
+ $systemdsystemunitdir/systemd-networkd-wait-online.service \
+ $systemdsystemunitdir/systemd-networkd.service \
+ $systemdsystemunitdir/systemd-networkd.socket \
+ networkctl ip
+
+ # the hook script that will parse the "ip=" kernel command line
+ # parameter and generate the .link and .network files needed
+ # by systemd-networkd.
+ inst_hook cmdline 10 "$moddir/hooks/parse-kcl-for-networkd.sh"
+ for i in \
+ systemd-networkd-wait-online.service \
+ systemd-networkd.service \
+ systemd-networkd.socket
+ do
+ systemctl --root "$initdir" enable "$i"
+ done
+ # HACK: disables udev new persitent naming scheme
+ rm $systemdutildir/network/99-default.link
+}
+