mirror of
https://github.com/kernelkit/infix.git
synced 2026-08-06 23:43:20 +02:00
This patch changes the way Infix DHCP and ZerocConf clients set their routes in the system. Instead of setting them directly in the kernel we ask FRR staticd to set them for us. The reason for this change is to be able to override routes from these protocols with locally set static routes. The routes are now set with a distance of 5 and 254, respectively, while static routes by default have a distance of 1. In contrast, kernel routes are always treated by Frr as distance 0, i.e., they are preferred over static routes. Finally, this patch drops the use of Linux legacy interface aliases, or colon interfaces, in an effort to reduce confusion for end users. This may give some odd results if using older tools like ifconfig, so we recommend using 'show interfaces' or 'ipb a' instead. Fixes #640 Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
172 lines
4.1 KiB
Bash
Executable File
172 lines
4.1 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"
|
|
NAME="/etc/frr/static.d/${interface}-dhcp.conf"
|
|
NEXT="${NAME}+"
|
|
|
|
[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast"
|
|
[ -n "$subnet" ] || subnet=32
|
|
[ -n "$metric" ] || metric=5
|
|
|
|
# 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 "$*"
|
|
}
|
|
|
|
wait_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()
|
|
{
|
|
echo "! Generated by udhcpc" > "$NEXT"
|
|
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"
|
|
echo "ip route $1 $2 $metric tag 100" >> "$NEXT"
|
|
shift 2
|
|
done
|
|
elif [ -n "$router" ] ; then
|
|
for i in $router ; do
|
|
echo "ip route 0.0.0.0/0 $i $metric tag 100" >> "$NEXT"
|
|
done
|
|
fi
|
|
|
|
# Reduce changes needed by comparing with previous route(s)
|
|
cmp -s "$NAME" "$NEXT" && return
|
|
mv "$NEXT" "$NAME"
|
|
|
|
initctl -nbq restart staticd
|
|
}
|
|
|
|
clr_dhcp_routes()
|
|
{
|
|
log "deleting DHCP routes from $interface"
|
|
[ -f "$NAME" ] || return
|
|
rm "$NAME"
|
|
|
|
initctl -nbq restart staticd
|
|
}
|
|
|
|
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
|
|
|
|
set_dhcp_routes
|
|
|
|
# set hostname if given
|
|
if [ -n "$hostname" ]; then
|
|
log "setting new hostname: $hostname"
|
|
hostname "$hostname"
|
|
sed -i -E "s/^(127\.0\.1\.1\s+).*/\1$hostname/" /etc/hosts
|
|
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
|