mirror of
https://github.com/kernelkit/infix.git
synced 2026-08-01 13:23:01 +02:00
- New log() function replaces stdout logging
- New set_dhcp_routes() and clr_dhcp_routes() functions
- Set all option 121 routes with same metric
- Set all option 3 routers with increasing metric (this is what the
reference udhcpc scripts do, and RFC says the routers should be
listed in order of preference ...)
- Clearing routes must, like IP addresses, be done both by interface
and protocol. This refactor makes sure to delete any DHCP routes
set on the given interface (in case options change)
- Use resolvconf per-interface search+nameserver
- Cache IP lease so we can ask for it back later
- On deconfig|leasefail|nak, make sure to clean up anything that might
be lingering from this interface. E.g., we can get leasefail when a
server denies our request to prolong a lease.
- On renew|bound, refresh routes, and set search+dns + NTP servers
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
156 lines
3.8 KiB
Bash
Executable File
156 lines
3.8 KiB
Bash
Executable File
#!/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" ] && NETMASK="$subnet"
|
|
[ -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/$NETMASK $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
|
|
|
|
# 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
|