Present Location: News >> Blog >> Linux IPv6 Autoconfiguration

Blog

> Linux IPv6 Autoconfiguration
Posted by prox, from Charlotte, on August 29, 2009 at 19:38 local (server) time

I keep running into this annoying problem, and have finally found a decent workaround.  Here's a little background:

Linux's IPv6 autoconf system runs when an interface is brought up & is marked as RUNNING.  On wired (Ethernet) this usually means there is some sort of link on the interface.  An IPv6 link-local address is assigned to the interface based on the EUI-64 for the interface, which in turn is based off the MAC address.  The Linux kernel sends a couple of ICMPv6 router solicitation messages to ff02::2 (the link-local multicast address for all routers), waits for the reciept of a router advertisement message, then acts on the information provided.  Usually the router advertisement message contains an IPv6 prefix (/64, in almost all cases), a lifetime, and some miscellaneous options.  Linux takes the EUI-64 for the interface, appends it to the prefix it just received, and binds it to the interface.  A default route (::/0) is also generated, having a gateway of the link-local address of the router that sent the advertisement message.

This works just fine most of the time.  However, with some wireless networks and instances where the interface is brought up the first time when on the wrong (or nonexistant) network, problems can occur.

The biggest issue seems to be Linux's inability to re-send router solicitation messages when an interface is bounced, at regular intervals, or even on demand.  Try this scenario:

Ok, that turned out to be a silly scenario, but you get the picture.  We all too often see the message:

eth0: no IPv6 routers present

…when we plug into something that doesn't /yet/ have connectivity to the rest of the network, but will soon.

A better example, and the one that I get burned by all the time, revolves around wpa_supplicant and wireless interfaces.  When I bring up the interface on my laptop, Debian runs wpa_supplicant for me.  The link is immediately brought up and flagged as RUNNING, but wpa_supplicant hasn't finished authenticating, and sometimes takes 20-30 seconds, depending on the network.  Unfortunately, the kernel gives up on the router solicitation messages before real connectivity is available.

To make matters worse, bouncing the interface doesn't always cause the kernel to resend the router solicitation messages.  I have to rmmod the module, then insmod and start all over again.

Enter the ndisc6 tools package.  ndisc6 is a collection of IPv6 diagnostic tools for Linux and *BSD, and includes rdisc6(8), a userland application that implements the router discovery process, and can tell the kernel to update its autoconfiguration state.  It's available as part of the ndisc6 package (duh) on Debian/Ubuntu.  Running it like this will refresh/assign the autoconfigured addresses and recreate the default route:

% sudo rdisc6 eth0
Soliciting ff02::2 (ff02::2) on eth0...

Hop limit                 :           64 (      0x40)
Stateful address conf.    :           No
Stateful other conf.      :           No
Router preference         :       medium
Router lifetime           :         1800 (0x00000708) seconds
Reachable time            :  unspecified (0x00000000)
Retransmit time           :  unspecified (0x00000000)
 Prefix                   : 2001:db8:8ad6:5::/64
  Valid time              :        86400 (0x00015180) seconds
  Pref. time              :        14400 (0x00003840) seconds
 Source link-layer address: 00:03:23:5F:4D:D9
 from fe80::203:23ff:fe5f:4dd9

Yep, just like that.  It's really not a fix for the problem, but it's a good workaround, since it doesn't involve bouncing interfaces or reloading modules.

The BSDs have rtsold, that supposedly runs as a daemon and manages scheduling of the router discovery process in userland.  Perhaps Linux needs this, so router discovery can be triggered after certain events (wpa_supplicant succeeding).

Comment by Jeremy Duncan [Website] on August 30, 2009 at 01:25 local (server) time

or you could use DHCPv6.  The server side is well implemented w/ Fedora and Ubuntu "dhcp6s" and the clients are done well - "dhcp6c" and "dibbler-client"

Comment by TJ [Website] on August 30, 2009 at 12:21 local (server) time

I like that potential work-around ... but even w/o that, your stack should still listen for prefixes in RAs ("SLAAC"), and RAs should be sent every ~180s.  Change the advertisement interval to ~20-30s and your delay is even less.

If the stack quits listening that is _wrong_.


@Jeremy - might have the same problem there, if it quits sending the solicits after initial failure to detect ... ?


/TJ

Comment by Mark Kamichoff [Website] on September 10, 2009 at 16:23 local (server) time

Yeah, something is up with the stack.  In the past, I've tried bounding radvd on the upstream router, which triggers the sending of at least one RA right when it starts up, but that didn't work either.  I did do tcpdumps on the router & on the client until I was blue in the face - some of the RAs were being dropped on the way to the client, and the only thing in between is a Cisco AIR-AP1232AG-A-K9.

I've definitely been meaning on trying DHCPv6 with a hybrid-style configuration (w/the managed flag set on RAs).  I'd like to get all my platforms using it at the same time, although I'm thinking IRIX is a lost cause.

Comment by Ryan Rawdon [Website] on November 11, 2009 at 15:50 local (server) time

A better example for the rtsol issue (than the uplink port contrived example, though it gets the point across) would be when there is STP enabled on user-facing ports.  The 30 or 60 second period for STP to progress through its various states is long enough to eat a lot of things, including DHCPDISCOVER messages (or does it try rtsol for longer than that before giving up?)


> Add Comment

New comments are currently disabled for this entry.