Discussion:
how to keep udhcpc from setting the default route?
Robert P. J. Day
2009-02-18 13:06:58 UTC
Permalink
based on what little i've been told about a situation here, we have
a BB-based system that, when it boots, uses udhcpc to assign an IP
address to both interfaces eth0 and eth1. it does this just fine --
so far, so good.

however, it also assigns two default addresses in the routing table,
one for each interface, and there is some suspicion that this is
causing a problem with the way this device communicates with other
network devices.

long story short: how to not have udhcpc add default entries to the
routing table. obviously, i can manually remove those entries later,
but i checked the doc for "udhcpc" and i don't see an obvious option
that says, "don't set a default route."

do i just do that manually after invoking "udhcpc"? or can i tuck
that away in the udhcpc "script" file that is run at DHCP events?
thanks.

rday
--

========================================================================
Robert P. J. Day
Linux Consulting, Training and Annoying Kernel Pedantry:
Have classroom, will lecture.

http://crashcourse.ca Waterloo, Ontario, CANADA
========================================================================
Alexander Griesser
2009-02-18 13:28:45 UTC
Permalink
Post by Robert P. J. Day
long story short: how to not have udhcpc add default entries to the
routing table. obviously, i can manually remove those entries later,
but i checked the doc for "udhcpc" and i don't see an obvious option
that says, "don't set a default route."
do i just do that manually after invoking "udhcpc"? or can i tuck
that away in the udhcpc "script" file that is run at DHCP events?
thanks.
I would do that in the udhcpc.sh script. Depending on your
configuration, this script might look like this:

- --------------------- 8< ------------------
[...]
case $1 in
"bound" | "renew")
ifconfig $interface $ip netmask $subnet up
if [ "$router" != "" ]; then
route add default gw $router
fi
[...]
- --------------------- 8< ------------------

As you can see, if a router option is given, it tries to set the default
route to this option.
If you can say that in your specific case, eth0 is the primary address
and eth1 is the secondary, you can modify the `route add ...` line to
something like this:

[ "$interface" = "eth0" ] && route add default gw $router

Or you can comment that out at all and set the default router manually
later on.
You could even want to check if there's already a default router present
and only if this is not the case, set the default route, that could be
done with code like this:

route -n | grep -q ^0.0.0.0 || route add default gw $router

ciao,
- --
Alexander Griesser (Netzwerkadministration)
E-Mail: alexander.griesser at lkh-vil.or.at | Web: http://www.lkh-vil.or.at
KABEG LKH Villach | Nikolaigasse 43 | 9500 Villach
Tel.: +43 4242 208 3061 | Fax.: +43 4242 208 971 2061
Robert P. J. Day
2009-02-18 13:51:53 UTC
Permalink
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Post by Robert P. J. Day
long story short: how to not have udhcpc add default entries to the
routing table. obviously, i can manually remove those entries later,
but i checked the doc for "udhcpc" and i don't see an obvious option
that says, "don't set a default route."
do i just do that manually after invoking "udhcpc"? or can i tuck
that away in the udhcpc "script" file that is run at DHCP events?
thanks.
I would do that in the udhcpc.sh script. Depending on your
- --------------------- 8< ------------------
[...]
case $1 in
"bound" | "renew")
ifconfig $interface $ip netmask $subnet up
if [ "$router" != "" ]; then
route add default gw $router
fi
[...]
- --------------------- 8< ------------------
As you can see, if a router option is given, it tries to set the
default route to this option.
potentially a dumb question but where is the "router" variable set
such that the udhcpc default script will be passed that value? as it
is, i would like eth0 to add a default route entry, but not eth1. so
how do i invoke udhcpc differently for those two interfaces? or am i
missing something painfully obvious? thanks.

rday
--

========================================================================
Robert P. J. Day
Linux Consulting, Training and Annoying Kernel Pedantry:
Have classroom, will lecture.

http://crashcourse.ca Waterloo, Ontario, CANADA
========================================================================
Alexander Griesser
2009-02-18 14:08:55 UTC
Permalink
Post by Robert P. J. Day
Post by Alexander Griesser
As you can see, if a router option is given, it tries to set the
default route to this option.
potentially a dumb question but where is the "router" variable set
such that the udhcpc default script will be passed that value?
That's udhcpc magic.
udhcpc executs the given script (-s parameter, default location can be
configured in busybox so that you can omit -s) with only one parameter
and that is the current DHCP action (bound, renew, deconfig, etc.).

So in your case, the udhcpc.sh script will be called twice, once for
eth0 and once for eth1 when both interfaces get a lease.
The variables like router, domain, etc. are placed into the shell
scripts environment by udhcpc itself so that it is easier for the
script to refer to these values.

The router variable ($router) is only set, if your DHCP lease contains
a router option, so if you're getting two IP addresses on the same
subnet on two different physical interfaces (for whatever reasons)
you need to manually mark one interface as the primary interface and
this can be done with a one-line hack in udhcpc.sh.

If you get IP addresses of two different subnets from two different
DHCP scopes you should think about removing the gateway from one
of the scope options if possible, that would get rid of this issue
automatically.
Post by Robert P. J. Day
as it is, i would like eth0 to add a default route entry, but not eth1.
OK, so go and find you udhcpc.sh script and search for the line where
it sets the default route (it probably looks similar to what I posted
before).

Now change this line from

route add default gw $router

to

[ "$interface" = "eth0" ] && route add default gw $router

and you should be good.
You could also use different scripts for the interfaces, so that the
udhcpc.sh script for eth0 sets the default router and the one for eth1
doesn't, etc.

There are several ways to achieve this goal.

ciao,
- --
Alexander Griesser (Netzwerkadministration)
E-Mail: alexander.griesser at lkh-vil.or.at | Web: http://www.lkh-vil.or.at
KABEG LKH Villach | Nikolaigasse 43 | 9500 Villach
Tel.: +43 4242 208 3061 | Fax.: +43 4242 208 971 2061
Robert P. J. Day
2009-02-18 14:27:34 UTC
Permalink
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Post by Robert P. J. Day
Post by Alexander Griesser
As you can see, if a router option is given, it tries to set the
default route to this option.
potentially a dumb question but where is the "router" variable
set such that the udhcpc default script will be passed that value?
That's udhcpc magic. udhcpc executs the given script (-s parameter,
default location can be configured in busybox so that you can omit
-s) with only one parameter and that is the current DHCP action
(bound, renew, deconfig, etc.).
yup, that part i knew. currently, it's set to the (fairly
predictable) /usr/share/udhcpc/default.script, that common script by
Tim Riker, whose relevant contents are:

...
case "$1" in
deconfig)
/sbin/ifconfig $interface 0.0.0.0
;;

renew|bound)
/sbin/ifconfig $interface $ip $BROADCAST $NETMASK

if [ -n "$router" ] ; then <---- that's the relevant line
echo "deleting routers"
while route del default gw 0.0.0.0 dev $interface ; do
:
done

metric=0
for i in $router ; do
route add default gw $i dev $interface metric $((metric++))
done
fi
So in your case, the udhcpc.sh script will be called twice, once for
eth0 and once for eth1 when both interfaces get a lease.
yup, knew that, too.
The variables like router, domain, etc. are placed into the shell
scripts environment by udhcpc itself so that it is easier for the
script to refer to these values.
ah, now we're getting close, since all of this could be clarified if
i see where the value of the "router" variable comes from since, once
i figure that out, i can arrange to have that set for only the
interface for which i want a default route set (that being eth0).
The router variable ($router) is only set, if your DHCP lease
contains a router option,
ah, that's what i'm after -- so you're saying that this is an option
that can be set on the DHCP *server* side?
so if you're getting two IP addresses on the same subnet on two
different physical interfaces (for whatever reasons) you need to
manually mark one interface as the primary interface and this can be
done with a one-line hack in udhcpc.sh.
i can see that this can be done by hacking the default script
trivially enough, but i was trying to do this without touching the
script. and i believe you've given me the info i want.
If you get IP addresses of two different subnets from two different
DHCP scopes you should think about removing the gateway from one of
the scope options if possible, that would get rid of this issue
automatically.
this is *exactly* what's happening -- two totally different subnets,
and you're saying that whether or not that "router" variable is set is
a server-side option? i can control that on only one of the subnets,
which is serving DHCP via an openwrt-based linksys router and for
which i am the admin. i can't touch the DHCP config on the other
subnet -- that's a corporate net.

obviously, a trivial solution is to change the default script, but i
just wanted this to be more of a challenge. :-) so, as long as i've
understood this correctly, now i'll just go see where on the linksys
router i can configure the DHCP service scope option so that getting
an IP address from that router doesn't end up setting the "router"
variable, is that it? thanks.

rday
--

========================================================================
Robert P. J. Day
Linux Consulting, Training and Annoying Kernel Pedantry:
Have classroom, will lecture.

http://crashcourse.ca Waterloo, Ontario, CANADA
========================================================================
Alexander Griesser
2009-02-18 14:40:51 UTC
Permalink
Post by Robert P. J. Day
yup, that part i knew. currently, it's set to the (fairly
predictable) /usr/share/udhcpc/default.script
Oh, yes, that was the path I didn't remember :) I have set it to
/bin/udhcpc.sh which is easier to remember for me. I did even write
the udhcpc.sh script on my own because the other one was a bit too
complicated for my basic needs.
Post by Robert P. J. Day
Post by Alexander Griesser
The router variable ($router) is only set, if your DHCP lease
contains a router option,
ah, that's what i'm after -- so you're saying that this is an option
that can be set on the DHCP *server* side?
Of course, that's a DHCP scope option.
On Microsoft DHCP, it's in the "scope options" folder and is called

"003 Router"

Using dhcpd on Linux systems, it's a line like:

option routers 204.254.239.1;

in the scope.
Post by Robert P. J. Day
Post by Alexander Griesser
so if you're getting two IP addresses on the same subnet on two
different physical interfaces (for whatever reasons) you need to
manually mark one interface as the primary interface and this can be
done with a one-line hack in udhcpc.sh.
i can see that this can be done by hacking the default script
trivially enough, but i was trying to do this without touching the
script. and i believe you've given me the info i want.
As I said, that only works if you do not get the IP addresses for
both interfaces out of the same scope.
OK, it works, but you will have to create reservations for the specific
MAC addresses then to remove the router option from one of them.
Post by Robert P. J. Day
this is *exactly* what's happening -- two totally different subnets,
and you're saying that whether or not that "router" variable is set is
a server-side option?
Yes.
Post by Robert P. J. Day
i can control that on only one of the subnets,
which is serving DHCP via an openwrt-based linksys router and for
which i am the admin. i can't touch the DHCP config on the other
subnet -- that's a corporate net.
Well, then remove the gateway option in the DHCP parameters on the
OpenWRT router and you should be good.
Post by Robert P. J. Day
obviously, a trivial solution is to change the default script, but i
just wanted this to be more of a challenge. :-) so, as long as i've
understood this correctly, now i'll just go see where on the linksys
router i can configure the DHCP service scope option so that getting
an IP address from that router doesn't end up setting the "router"
variable, is that it? thanks.
Yes, that would be the solution.

ciao,
- --
Alexander Griesser (Netzwerkadministration)
E-Mail: alexander.griesser at lkh-vil.or.at | Web: http://www.lkh-vil.or.at
KABEG LKH Villach | Nikolaigasse 43 | 9500 Villach
Tel.: +43 4242 208 3061 | Fax.: +43 4242 208 971 2061
Denys Vlasenko
2009-02-19 00:28:42 UTC
Permalink
Post by Robert P. J. Day
so if you're getting two IP addresses on the same subnet on two
different physical interfaces (for whatever reasons) you need to
manually mark one interface as the primary interface and this can be
done with a one-line hack in udhcpc.sh.
i can see that this can be done by hacking the default script
trivially enough, but i was trying to do this without touching the
script. and i believe you've given me the info i want.
My opinion is that you are on the wrong way to solve the problem.

The whole reason why udhcpc does not do any network config itself
but delegates it to the script is because the script can
and should be tweaked.
Post by Robert P. J. Day
If you get IP addresses of two different subnets from two different
DHCP scopes you should think about removing the gateway from one of
the scope options if possible, that would get rid of this issue
automatically.
this is *exactly* what's happening -- two totally different subnets,
and you're saying that whether or not that "router" variable is set is
a server-side option? i can control that on only one of the subnets,
But you should not. If your machine sits on two DHCP-controlled
networks at once, other machines very well may be only on one of them.

Thus both SHCP servers advertise default route suitable for such machines.

Your machine is unique, and thus your script should be more clever.

It should check availability of route from both networks.
If one is down, it's easy - use the other. If both are up,
well, have a priority or even set up more complicated
routing modes where both paths are used at once (never did it yet).
Post by Robert P. J. Day
which is serving DHCP via an openwrt-based linksys router and for
which i am the admin. i can't touch the DHCP config on the other
subnet -- that's a corporate net.
obviously, a trivial solution is to change the default script, but i
just wanted this to be more of a challenge. :-)
I wrote up my ideas regarding network config here:

http://busybox.net/~vda/no_ifup.txt

Please read, and feel free to disagree. :)
--
vda
Rob Landley
2009-02-26 20:45:23 UTC
Permalink
Post by Denys Vlasenko
http://busybox.net/~vda/no_ifup.txt
Please read, and feel free to disagree. :)
I noticed your directory has a lot of stuff in it a while ago. Possibly you
might want to create a "vda" subdirectory under docs and put these sort of
things in there so people actually notice them? (If you find old rants from
eric and me, feel free to put them under eric and rob directories if you like.
"Opinions various maintainers have bothered to write up" count as
documentation, if you ask me. Why we did X.)

For context, I note that the Linux kernel's Documentation/oops-tracing.txt
started as post Linus made to linux-kernel, which is still preserved as the
second half of that file...

Rob

Loading...