NSLU2-Linux
view · edit · print · history

This page assumes that either you want your slug to use DHCP and that either you haven't converted it from a static IP address yet or you have and it no longer works...

This should be easy but there are bugs in both the stock LinkSys? udhcpc implementation and that in older versions of unslung which can leave your slug dead. You know if this has happened - the slug will apparently never complete the boot process and even reflashing the image will not help.

My slug is broken, how do I fix it?

If your slug stopped booting after you changed the DHCP settings (and this is, you think, all you changed) try the following, in this order:

  1. Go to the DHCP server (i.e. not the slug, which is the client) and remove the piece of configuration which assigns the slug a fixed IP address - it will probably be in /etc/ethers, but, for dnsmasq, it might be in the dnsmasq configuration file. Reboot the slug. If you don't understand this, or if it doesn't work, try the next option. If that does work update this page - you have valuable information about this problem! Read the explanations below if you need more information.
  2. Reset the slug's system configuration - see the HowTo.ResetSysConf. This clears the setting which tells LinkSys?/unslung to try DHCP. Your slug should now boot, with IP address 192.168.1.77 Resetting the system configuration will clear all your slug's configuration, though not data on disk - see the warnings on the ResetSysConf page.

If the second step doesn't work this is probably not a DHCP problem - resetting the system configuration should remove any desire on the slug's part to use DHCP.

I want to use DHCP, how do I do it safely?

The problem with DHCP seems to be limited to the following combination (i.e. all the following conditions must be true):

  • The slug is running a version of udhcpc <= 0.9.6. The stock LinkSys? firmware and unslung 2.12 seem to do this. The bitbake build busybox is 0.9.9pre and the bitbake build udhcpc (standalone) is 0.9.8 - so the latest (3.x) unslung should be safe and openslug definately is. jbowler: I don't know about the CVS builds of unslung.
Have you verified that 3.x is ok with a static IP - see the next point? Say so here if you have:

jbowler: openslug busybox 0.9.9pre is fine with static IP

vitroth: 3.18 seems to be unhappy with the dhcp responses its getting from my ISC dhcp server, server logs show the DISCOVER/OFFER with no REQUEST pattern. The slug beeps for a while and eventually it falls back to 192.168.1.77

jaelwyn: Stock Linksys firmware exhibits the same symptoms vitroth is reporting -- but *without* a static IP involved on my server (ISC DHCPd? 3.0.3). However, I am sending a number of 'extra' options not generally seen on most servers. Between the udhcpc source and some packet inspection, I have some hope that I may be able to figure out what is actually causing / triggering the issue.

jaelwyn: I believe I found the problem. The checksum calculation routine prior to 0.9.8 is written in a way that makes it sensitive to whether the code is running in big-endian or little-endian mode. This is only triggered if the total UDP packet length is an *odd* number, because the problem is in the "one leftover byte" logic. On my particular server, the specified hostname is 6 characters, but the default generated by the unit is 9, and I have a 33-byte domain name option set. So my unit *only* works if it is defined with an entry in DHCPd? (so that it gets a hostname defined) -- and "slug" works, but "slug1" does not. Revision 5404 in the source repository fixed this, if anyone is curious.

  • The DHCP server offers a static IP address to the slug. This only happens if it is configured with the slugs 48bit ethernet (mac) address and a corresponding fixed IP number. It is known to happen with dnsmasq running on OpenWrt on a LinkSys? 54g router when the address is configured in /etc/ethers.
Do you know any other DHCP servers which demonstrate the problem? Say so here:

jbowler: I've observer the WRT54g? with OpenWrt and /etc/ethers causing both LinkSys? stock and unslung not to boot - the boot hangs such that the magic green LED never stops flashing :-(

judah: I've also seen it with DD-WRT on a WRT54g?, although I got it to work once...

If either of these conditions do not apply you should be able to configure the slug to use DHCP without any problem, assuming your DHCP server is configured correctly.

The safe, paranoid, approach to udhcpc

If both the above conditions apply, or you don't feel confident, you can either not use a static address - probably the best solution on stock LinkSys? or older unslung, or you can ensure you have a later (>0.9.6) version of udhcpc and try the following. Notice that the standard unslung configuration runs the udhcpc from rc.bootbin (jbowler: I think this is right, but I haven't tried it for a while), it may be difficult to work out for sure where the control script is.

The trick to using udhcpc safely is to not stop the ethernet IP protocol functioning while udhcpc is discovering an IP address. This means you need a functional static IP address to use on the slug while udhcpc is trying to get the correct address. Of course this means that the world is no better a place if the DHCP stuff fails, but it also means it is no worse a place.

The obvious address to use is 192.168.1.77 - the default ResetSysConf value. Once you've decided on this address follow these steps:

  1. Install a suitably mature udhcpc, if you have not done so already.
  2. Find the udhcpc script. It is normally in /usr/share/udhcpc/default.script. It may be specified on the udhcpc command line, with the -s parameter.
  3. If the script says something like:
 exec run-parts -a "$1" /etc/udhcpc.d
go to /etc/udhcpc.d and find the default script in there ;-). It will probably be called 50default.
  1. Find the deconfig line in the script. It will probably say:
 /sbin/ifconfig $interface 0.0.0.0
this is not healthy. It reconfigures the interface with the IP address 0.0.0.0, this is not a good thing to do. Instead change it to use your static IP address, e.g.:
 /sbin/ifconfig $interface 192.168.1.77

After you have done this the interface will be alive, with the static IP address, until the DHCP protocol grants a lease to udhcpc. At this point udhcpc will run the script again with the bound argument and the interface will get a, possibly, new IP address. Any connections you had at that point will be broken - but if DHCP fails you will be able to fix the slug via 192.168.1.77 (or whatever IP address you used.)

When you are confident that everything is ok just change the deconfig line to:

 /sbin/ifconfig $interface up

This puts the interface into a state where udhcpc can use it without changing any existing IP address. If there isn't an existing IP address IP will not work until udhcpc fills one in - but you've tested it now so it should be ok!

The explanation, and ways to get the most out of udhcpc

If you want to know more...

DHCP uses the PF_PACKET protocol family (sometimes referred to as 'af_packet'; that's an 'address family' but this is apparently a misnomer). It needs the interface (ethernet in the slug) to be 'up' - capable of transmitting and receiving ethernet packets - but doesn't need any IP (Internet Protocol) information. That's good, because the function of DHCP is to establish the IP address to use for the interface!

The default script for udhcpc starts off by zapping the IP number of the interface - to 0.0.0.0 in the above example. This is unnecessary.

In the scenario which goes wrong udhcpc does correctly send a DHCP_DISCOVER packet out and, (jbowler: from my DHCP server logs) the DHCP server sends a DHCP_OFFER, yet apparently udhcpc either never receives this or ignores it. I (jbowler) believe it ignores it because dnsmasq (and possibly other DHCP server implementations) put extra stuff in the packet which causes udhcpc to reject it. There is a comment about this in the change log for udhcpc 0.9.7 - see Accept packets with extra garbage in http://udhcp.busybox.net/

It's highly desireable that udhcpc work even in the absence of a DHCP server, this allows a slug to come pre-configured to use DHCP if available much in the manner that modern computers just connect to the network out of the box (with no user configuration.) udhcpc makes this possible if the deconfig handling is changed to put the interface up.

To make this work in practice there also needs to be a change to the leasefail handling so that, if udhcpc fails to find a lease, the interface is brought up with a static IP value. This is an alternative to the approach above - in the above the interface is pre-configured with the static value. With this approach udhcpc is run with the -n option (to quit if it can't get a lease immediately) and leasefail hardwires the interface to a static address.

In praise of udhcpc

jbowler: I really like this program. It does one job well. By indirecting everything apart from SOCKET_DGRAM over PF_PACKET to the shell script it ensures that it can cope with any practical situation. That's very important for a slug, because the ethernet is the only connection with the outside world that a slug can rely on.

view · edit · print · history · Last edited by jaelwyn.
Based on work by jaelwyn, mrdj, vitroth, tman, and jbowler.
Originally by jbowler.
Page last modified on May 29, 2008, at 02:29 AM