[Buildroot] DHCP default.script
David Laight
David.Laight at ACULAB.COM
Mon Nov 29 17:19:49 UTC 2021
I was looking at the DHCP default.script (that ends up in /usr/share/udhcpd)
and found some quite nasty problems.
I've fixed them locally and ended up with the script below.
(Which is probably easier to read than a diff.)
I've ripped out ahavi - we don't need it (and i don't know what it does!).
The main problems:
1) On a 'renew' indication it would delete all the routes and then
add the supplied routes back in.
This leaves the system missing routes (typically the default one)
for a while - which can lead to lost transmit packets.
I've done a 'mark and scan' to only delete routes that no longer exist.
2) On a 'renew' it would delete all routes, not just the one added
by dhcp.
The 'proto dhcp' parameter can be used to identify routes added by
dhcp so that they are the only ones deleted (this matches my desktop).
3) If both IPv6 and IPv4 DHCP are used the entries for both protocols
get removed from resolve.conf.
They should only remove their own entries.
It is also not necessary to use a temporary file.
4) When 'deconfig' is done for IPv6 it removes the IPv4 address!
I've split the IPv4 and IPv6 paths to ensure they don't tread
on each other.
The IPv6 address is saved in a file - I think it should be possible
to 'tag' the address (much like the routes).
In reality it needs quite a few patches - but I've not got the git
tree and generating them is quite hard for me even if I download it.
Thoughts?
David
#!/bin/sh
# udhcpc script losely based on the buildroot default.script
[ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1
nl="$(printf '\nx')"
nl="${nl%x}"
update_resolv_conf()
{
: ${RESOLV_CONF:=/etc/resolv.conf}
marker=$interface$1
# drop info from this interface
# resolv.conf may be a symlink to /tmp/, so take care
resolv_conf="$(grep -vE "# $marker\$" $RESOLV_CONF 2>/dev/null)"
if [ "$2" = update ]; then
# prefer rfc3397 domain search list (option 119) if available
if [ -n "$search" ]; then
search_list=$search
elif [ -n "$domain" ]; then
search_list=$domain
fi
[ -n "$search_list" ] &&
resolv_conf="${resolv_conf}${nl}search $search_list # $marker"
for i in $dns ; do
echo adding dns $i
resolv_conf="${resolv_conf}${nl}nameserver $i # $marker"
done
fi
# Hopefully nothing tries a lookup while the file is empty.
echo "$resolv_conf" >$RESOLV_CONF
}
update_routes()
{
ipv=$1
# RFC3442: If the DHCP server returns both a Classless
# Static Routes option and a Router option, the DHCP
# client MUST ignore the Router option.
if [ -z "$staticroutes" ]; then
for gw in $router ; do
staticroutes="${staticroutes} default $gw"
done
fi
old_routes=' '
routes="$(ip $ipv route show proto dhcp dev "$interface" 2>/dev/null)"
IFS="$nl"
for rt in $routes; do
IFS=' '
set -- $rt # addr via gateway ...
[ "$2" = via ] && old_routes="$old_routes$1@$3 "
done
IFS=' '
# format: dest1/mask gw1 ... destn/mask gwn
set -- $staticroutes
while [ "$#" -ge 2 ]; do
x="${old_routes#* $1@$2 }"
if [ "$x" = "$old_routes" ]; then
ip $ipv route add "$1" via "$2" proto dhcp dev "$interface"
else
old_routes="${old_routes% $1@$2 } $x"
fi
shift 2
done
# Delete any routes that have gone away
for route in $old_routes; do
echo ip $ipv route delete ${route%@*} via ${route#*@} proto dhcp dev "$interface"
done
}
if [ -z "$ipv6" ]; then
case "$1" in
deconfig)
/sbin/ifconfig $interface up
/sbin/ifconfig $interface 0.0.0.0
update_resolv_conf -4
;;
leasefail|nak)
;;
renew|bound)
/sbin/ifconfig $interface $ip ${broadcast:+broadcast $broadcast} ${subnet:+netmask $subnet}
update_routes -4
update_resolv_conf -4 update
;;
esac
else
case "$1" in
deconfig)
addr=`cat /var/run/dhcp.$interface.addr`
if [ "$addr" != "" ]; then
ip -6 addr del $addr dev $interface
echo "" > /var/run/dhcp.$interface.addr
fi
update_resolv_conf -6
;;
leasefail|nak)
;;
renew|bound)
ip -6 addr add $ipv6 dev $interface
echo $ipv6 > /var/run/dhcp.$interface.addr
update_routes -6
update_resolv_conf -6 update
;;
esac
fi
exit 0
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
More information about the buildroot
mailing list