#!/bin/sh # This script expect a system with resolvconf (openresolv) and iproute2 [ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1 ACTION="$1" IP_CACHE="/var/lib/misc/${interface}.cache" RESOLV_CONF="/run/resolvconf/interfaces/${interface}.conf" NTPFILE="/run/chrony/dhcp-sources.d/${interface}.sources" [ -n "$broadcast" ] && BROADCAST="broadcast $broadcast" [ -n "$subnet" ] || subnet=32 [ -n "$metric" ] || metric=100 # Handle stateful DHCPv6 like DHCPv4 [ -n "$ipv6" ] && ip="$ipv6/128" if [ -z "${IF_WAIT_DELAY}" ]; then IF_WAIT_DELAY=10 fi log() { logger -I $$ -t udhcpc -p user.notice "$*" } wwait_for_ipv6_default_route() { log "waiting for IPv6 default route to be installed." while [ $IF_WAIT_DELAY -gt 0 ]; do if ip -6 route list proto dhcp dev $interface | grep -q default; then return fi sleep 1 printf "." : $((IF_WAIT_DELAY -= 1)) done log "Timed out witing for IPv6 default route!" } # RFC3442: If the DHCP server returns both a Classless # Static Routes option and a Router option, the DHCP # client MUST ignore the Router option. set_dhcp_routes() { if [ -n "$staticroutes" ]; then # format: dest1/mask gw1 ... destn/mask gwn set -- $staticroutes while [ -n "$1" -a -n "$2" ]; do log "adding route $1 via $2 dev $interface proto dhcp" ip route add "$1" via "$2" dev $interface metric $metric proto dhcp shift 2 done elif [ -n "$router" ] ; then for i in $router ; do ip route add default via $i dev $interface metric $((metric++)) proto dhcp done fi } clr_dhcp_routes() { log "deleting DHCP routes from $interface" ip route show proto dhcp dev $interface | while read rt via nh dev dev; do log "removing $rt nh $nh on $dev" ip route del $rt via $nh dev $dev proto dhcp done } clr_dhcp_addresses() { addrs=$(ip -j addr show dev $interface \ | jq -c '.[0].addr_info[] | select(.family == "inet") | select(.protocol == "dhcp")') for addr in $addrs; do ip="$(echo "$addr" | jq -r '."local"')" prefix="$(echo "$addr" | jq -r '."prefixlen"')" log "removing $ip/$prefix from $interface" ip addr del "$ip/$prefix" dev "$interface" done } log "action $ACTION" case "$ACTION" in deconfig) clr_dhcp_addresses clr_dhcp_routes /bin/ip link set dev $interface up # drop info from this interface rm -f "$RESOLV_CONF" rm -f "$NTPFILE" if [ -x /usr/sbin/avahi-autoipd ]; then /usr/sbin/avahi-autoipd -c $interface && /usr/sbin/avahi-autoipd -k $interface fi ;; leasefail|nak) if [ -x /usr/sbin/avahi-autoipd ]; then /usr/sbin/avahi-autoipd -c $interface || /usr/sbin/avahi-autoipd -wD $interface --no-chroot fi ;; renew|bound) if [ -x /usr/sbin/avahi-autoipd ]; then /usr/sbin/avahi-autoipd -c $interface && /usr/sbin/avahi-autoipd -k $interface fi if /bin/ip addr add dev $interface $ip/$subnet $BROADCAST proto 5; then echo "$ip" > "$IP_CACHE" fi if [ -n "$ipv6" ] ; then wait_for_ipv6_default_route fi clr_dhcp_routes set_dhcp_routes # set hostname if given if [ -n "$hostname" ]; then log "setting new hostname: $hostname" hostname "$hostname" augtool -s "set /files/etc/hosts/*[ipaddr='127.0.1.1']/canonical $hostname" fi # drop info from this interface truncate -s 0 "$RESOLV_CONF" # prefer rfc3397 domain search list (option 119) if available if [ -n "$search" ]; then search_list=$search elif [ -n "$domain" ]; then search_list=$domain fi if [ -n "$search_list" ]; then log "adding search $search_list" echo "search $search_list # $interface" >> $RESOLV_CONF fi for i in $dns ; do log "adding dns $i" echo "nameserver $i # $interface" >> $RESOLV_CONF resolvconf -u done if [ -n "$ntpsrv" ]; then truncate -s 0 "$NTPFILE" for srv in $ntpsrv; do log "got NTP server $srv" echo "server $srv iburst" >> "$NTPFILE" done chronyc reload sources >/dev/null fi esac HOOK_DIR="$0.d" for hook in "${HOOK_DIR}/"*; do [ -f "${hook}" -a -x "${hook}" ] || continue "${hook}" "$ACTION" done exit 0