All of lore.kernel.org
 help / color / mirror / Atom feed
* [Buildroot] DHCP default.script
@ 2021-11-29 17:19 David Laight
  2021-11-29 21:15 ` Nicolas Cavallari
  0 siblings, 1 reply; 3+ messages in thread
From: David Laight @ 2021-11-29 17:19 UTC (permalink / raw)
  To: buildroot

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)

_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Buildroot] DHCP default.script
  2021-11-29 17:19 [Buildroot] DHCP default.script David Laight
@ 2021-11-29 21:15 ` Nicolas Cavallari
  2021-11-30  9:10   ` David Laight
  0 siblings, 1 reply; 3+ messages in thread
From: Nicolas Cavallari @ 2021-11-29 21:15 UTC (permalink / raw)
  To: David Laight, buildroot

On 29/11/2021 18:19, David Laight wrote:
> 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!).

It gives IPv4 link-local addresses (169.254.0.0/16) when DHCP fails.

> 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).

Busybox's iproute is very limited (e.g. it does not display the proto 
when listing routes) and 'dhcp' is not a builtin proto, so this needs a 
/etc/iproute2/rt_protos file to list 'dhcp'...

> nl="$(printf '\nx')"
> nl="${nl%x}"

or just

nl='
'
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [Buildroot] DHCP default.script
  2021-11-29 21:15 ` Nicolas Cavallari
@ 2021-11-30  9:10   ` David Laight
  0 siblings, 0 replies; 3+ messages in thread
From: David Laight @ 2021-11-30  9:10 UTC (permalink / raw)
  To: 'Nicolas Cavallari', buildroot

From: Nicolas Cavallari
> Sent: 29 November 2021 21:16
> 
> On 29/11/2021 18:19, David Laight wrote:
> > 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!).
> 
> It gives IPv4 link-local addresses (169.254.0.0/16) when DHCP fails.

Ah - that 'useful' feature.
I thought it was also responsible to the 'popup windows' every time
someone turns on/off a printer - that I don't seem to be able to disable.

> > 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).
> 
> Busybox's iproute is very limited (e.g. it does not display the proto
> when listing routes) and 'dhcp' is not a builtin proto, so this needs a
> /etc/iproute2/rt_protos file to list 'dhcp'...

I've got the full 'ip' program installed to get namespace support.
The number could be used instead of the name - but that might
still need minor enhancements to the program.
If you've got dhcp installed the extra bit of code probably isn't
a problem - I suspect even the smallest embedded systems have more
memory and 'disk' space for slightly larger versions of many of
the 'busybox' programs - especially if they are running a recent
Linux kernel.

> > nl="$(printf '\nx')"
> > nl="${nl%x}"
> 
> or just
> 
> nl='
> '

Yes, but I've fallen foul of shell script files with dos line endings.
So I always use the longer form for safety.

	David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-11-30  9:10 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-29 17:19 [Buildroot] DHCP default.script David Laight
2021-11-29 21:15 ` Nicolas Cavallari
2021-11-30  9:10   ` David Laight

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.