summaryrefslogtreecommitdiffstats
path: root/modules.d/slx-network/scripts/udhcpc-trigger.stage4
diff options
context:
space:
mode:
Diffstat (limited to 'modules.d/slx-network/scripts/udhcpc-trigger.stage4')
-rwxr-xr-xmodules.d/slx-network/scripts/udhcpc-trigger.stage4208
1 files changed, 208 insertions, 0 deletions
diff --git a/modules.d/slx-network/scripts/udhcpc-trigger.stage4 b/modules.d/slx-network/scripts/udhcpc-trigger.stage4
new file mode 100755
index 00000000..b4dfeafa
--- /dev/null
+++ b/modules.d/slx-network/scripts/udhcpc-trigger.stage4
@@ -0,0 +1,208 @@
+#!/bin/bash
+#
+# This script is triggered by udhcpc and handle the DHCP information
+# given to this script as parameters.
+
+export PATH=$PATH:/opt/openslx/sbin:/opt/openslx/bin
+
+. /opt/openslx/config
+
+if [ -z "$SLX_PXE_NETIF" ]; then
+ echo "Missing PXE network interface information."
+ exit 1
+fi
+
+MAIN_NETIF="$SLX_PXE_NETIF"
+[ -n "$SLX_VLAN_ID" ] && MAIN_NETIF="${SLX_PXE_NETIF}.${SLX_VLAN_ID}"
+[ -n "$SLX_BRIDGE" ] && MAIN_NETIF="$SLX_BRIDGE"
+readonly MAIN_NETIF
+
+RESOLV_CONF="/opt/openslx/resolv.conf"
+THIS_RESOLV="/run/network/${MAIN_NETIF}.resolv"
+
+rebuild_resolv_conf () {
+ # Don't do anything if the active resolv.conf is not ours
+ # Also this will not run resolvconf update.d... No idea if we should still do so...
+ [ -L "/etc/resolv.conf" ] || return 0
+ [ "x$(readlink "/etc/resolv.conf")" == "x${RESOLV_CONF}" ] || return 0
+ # Maybe make this smarter some time, if anyone is using clients that are on multiple networks at once etc...
+ # This is a little braindead but should work most of the time
+ sort -u /run/network/*.resolv > "$RESOLV_CONF" 2> /dev/null
+
+ # add support for resolv.conf update scripts // see man(8) resolvconf
+ for s in /etc/resolvconf/update.d/*.sh; do
+ [ -f "$s" ] && [ -x "$s" ] && "$s"
+ done
+}
+
+escape_search() {
+ echo "$@" | sed -e 's/[]\/()$*.^|[]/\\&/g'
+}
+
+escape_replace() {
+ echo "$@" | sed -e 's/[\/&]/\\&/g'
+}
+
+check_env() {
+ if [ -z "$ip" ] || [ -z "$subnet" ] || [ -z "$interface" ]; then
+ echo "$1 event with missing data" >&2
+ echo "ip = '$ip'" >&2
+ echo "subnet = '$subnet'" >&2
+ echo "interface = '$interface'" >&2
+ exit 1
+ fi
+ # only run for the boot network interface
+ # TODO VLAN support
+ if [ "$interface" != "$MAIN_NETIF" ]; then
+ echo "Ignoring '$interface'..."
+ exit 1
+ fi
+}
+
+case "$1" in
+ bound|renew)
+ check_env "$1"
+ # Set address on interface
+ ip addr add "$ip/$(ipcalc -s -p "$ip" "$subnet" | sed s/.*=//)" dev "$interface"
+ # Set default route, if given
+ if [ -n "$router" ]; then
+ ip route replace default via "$router"
+ fi
+
+ # get domain, hostname and thus fqdn from DNS
+ dns_fqdn=$(busybox timeout -t 3 rdns "$ip")
+ dns_short="${dns_fqdn%%.*}"
+ # check if it is fqdn
+ if [ "$dns_fqdn" == "$dns_short" ]; then
+ unset dns_fqdn dns_short
+ fi
+
+ # Update resolver configuration file
+ conf_file="$(mktemp)"
+ # Own domain suffix
+ if [ -n "$domain" ]; then
+ :
+ elif [ -n "$dns_fqdn" ]; then
+ domain="${dns_fqdn#*.}"
+
+ elif [ -n "$SLX_NET_DOMAIN" ]; then
+ domain="$SLX_NET_DOMAIN"
+ fi
+ if [ -n "$domain" ]; then
+ echo "domain ${domain%% *}" >> "${conf_file}"
+ fi
+ # Add domain to list of search domains if not in there yet
+ if [ -n "$domain" ] && [ -n "$search" ]; then
+ FOUND=no
+ for sd in $search; do
+ [ "x$sd" = "x$domain" ] && FOUND=yes
+ done
+ [ "$FOUND" = "no" ] && search="$domain $search"
+ elif [ -n "$domain" ]; then
+ search="$domain"
+ fi
+ # Search domains
+ if [ -n "$search" ]; then
+ echo "search $search" >> "${conf_file}"
+ elif [ -n "$SLX_NET_SEARCH" ]; then
+ echo "search $SLX_NET_SEARCH" >> "${conf_file}"
+ elif [ -n "$SLX_NET_DOMAIN" ]; then
+ echo "search $SLX_NET_DOMAIN" >> "${conf_file}"
+ fi
+ for i in $dns; do
+ echo "$0: Adding DNS $i"
+ echo "nameserver $i" >> "${conf_file}"
+ done
+
+ if [ -x "/sbin/resolvconf" ] && [ -L "/etc/resolv.conf" ] && [ -d "/etc/resolvconf/update.d" ]; then
+ # Automatic handling :-)
+ resolvconf --create-runtime-directories
+ resolvconf --enable-updates
+ < "$conf_file" resolvconf -a "${interface}.udhcpc"
+ rm -- "$conf_file"
+ else
+ # Manual handling required :-(
+ mv -f "$conf_file" "$THIS_RESOLV"
+ rebuild_resolv_conf
+ fi
+
+ # TODO: check if we really want/need to overwrite the PXE_IP,
+ # it might be better/clearer to change the SLX_DHCP_CLIENT_IP...
+ sed -i "s/^\(SLX_PXE_CLIENT_IP=\).*$/\1'$ip'/" /opt/openslx/config
+ # Write DOMAIN and SEARCH to /opt/openslx/config if empty
+ if [ -z "$SLX_NET_DOMAIN" ] && [ -n "$domain" ]; then
+ sed -i "/^SLX_NET_DOMAIN=/d" /opt/openslx/config
+ echo "SLX_NET_DOMAIN='$domain'" >> /opt/openslx/config
+ fi
+ if [ -z "$SLX_NET_SEARCH" ] && [ -n "$search" ]; then
+ sed -i "/^SLX_NET_SEARCH=/d" /opt/openslx/config
+ echo "SLX_NET_SEARCH='$search'" >> /opt/openslx/config
+ fi
+ # Same for WINS servers
+ if [ -z "$SLX_NET_WINS" ] && [ -n "$wins" ]; then
+ sed -i "/^SLX_NET_WINS=/d" /opt/openslx/config
+ echo "SLX_NET_WINS='$wins'" >> /opt/openslx/config
+ fi
+
+ # TODO find a better way to trigger additional code, hook dir?
+ # Update /etc/issue for proper spacing
+ [ -x "/opt/openslx/scripts/openslx-create_issue" ] && /opt/openslx/scripts/openslx-create_issue
+
+ # Remove any stray addresses; we expect the primary interface to only have one
+ # address supplied via DHCP. We do this after adding the new one, obviously.
+ rem_list=$( ip -o addr show "$interface" | awk '{ for (i=1;i<NF;++i) if ($i == "inet") print $(i+1) }' | grep -v "^${ip}/" )
+ if [ -n "$rem_list" ]; then
+ echo "PRIMARY: Removing $rem_list since we just got assigned $ip"
+ echo 1 > "/proc/sys/net/ipv4/conf/$interface/promote_secondaries"
+ for addr in $rem_list; do
+ ip addr del "$addr" dev "$interface"
+ sed -i "/^$(escape_search "${addr%/*}")(\s|$)/d" /etc/hosts
+ done
+ fi
+
+ # Write to openslx-config
+ echo "# Config written by openslx-dhcp-script (2)" >> /opt/openslx/config
+ sed -i "/^SLX_DNS=/d" /opt/openslx/config
+ echo "SLX_DNS='$dns'" >> /opt/openslx/config
+ ;;
+
+ deconfig)
+ check_env "$1"
+ if [ "$interface" = "$primary" ]; then
+ echo "Ignoring deconfig for primary interface"
+ else
+ echo 1 > "/proc/sys/net/ipv4/conf/$interface/promote_secondaries"
+ clientip=${ip%%:*}
+ ip addr del "$clientip/$(ipcalc -s -p "$clientip" "$subnet" | sed s/.*=//)" dev "$interface"
+ sed -i "/^$(escape_search "$ip")(\s|$)/d" /etc/hosts
+ fi
+
+ if [ -x /sbin/resolvconf ] && [ -L /etc/resolv.conf ] && [ -d /etc/resolvconf/update.d ]; then
+ # Automatic handling :-)
+ resolvconf -d "${interface}.udhcpc"
+ else
+ # Manual handling required :-(
+ rm -f -- "$THIS_RESOLV"
+ rebuild_resolv_conf
+ fi
+ ;;
+
+ leasefail)
+ echo "$0: Lease failed: $message" >&2
+
+ ;;
+
+ nak)
+ echo "$0: Received a NAK: $message" >&2
+
+ ;;
+
+ *)
+ echo "$0: Unknown udhcpc command: $1" >&2
+ exit 1
+
+ ;;
+esac
+
+exit 0
+