IPv6 and default routes

Following on from my first tutorial, we have a box set up which has basic IPv6 connectivity. There’s a firewall in place with a simple but sufficient configuration. And we can ping6 from this box to remote IPv6 destinations.

All of this has, so far, made use only of one network interface (in my case eth0) to set things up. However looking ahead to the next step I am aware that I will want devices inside my network (i.e. my workstations, etc.) to have IPv6 connectivity through this device I am setting up. In other words, this device must, as it does today for IPv4, act as a router.

With IPv4 this is, at a basic level (so forgetting about firewalling and so on) very easy: enable IPv4 forwarding and away you go.

For IPv6? A little more complicated…


My first step was to jump in to /etc/sysctl.conf and, just as I have IPv4 forwarding enabled here, do the same for IPv6. There’s even a (likely commented out) entry already there to help you. So I change it to show:

net.ipv6.conf.all.forwarding = 1

Reboot (or if you prefer manually involve the same change via sysctl or simply dropping the value in via /proc/sys/) and it takes effect.

Why has it all stopped working?

After doing this, the first thing I noticed was that suddenly I could no longer ping6 to my test destination. I find that the default route has disappeared from the route table (ip -6 route show)

It turns out that once the device is defined to be a router (i.e. that IPv6 forwarding is enabled) it stops acting on received Router Advertisements from the ISP, arriving on my WAN link eth0.

I was pretty miffed at first, but of course on reflection this is entirely sensible behaviour – I do not actually know who is sending me a given router advertisement. I have no knowledge of how the ISP has built its IPv6 infrastructure, and while I would hope that only the ISP can send an IPv6 Router Advertisement towards me, maybe not? What if someone else manages to do it too?

That’s why an IPv6 router, even in this context, as a home gateway, needs to treat a Router Advertisement with care!

What to do?

With IPv6 forwarding enabled it is possible to allow the RA to be accepted. In sysctl.conf set:

net.ipv6.conf.all.accept_ra = 1

However this then permits the interface(s) to autoconfig so far as addressing is concerned, but still does not pick up a default route. There is also a sysctl of net.ipv6.conf.all.accept_ra_defrtr which could be useful (if you trust your RA in the first place, that is) but anyway I could not make it work as I’d expect.

So really it comes down to making sure that, once IPv6 forwarding is enabled, that a default route is manually defined. Something along the lines of:

ip -6 route add default via fe80::207:cbff:aaaa:bbbb dev eth0

seems to do the trick
Of course the difficulty here is how you obtain the address of the required gateway. My ISP had not told me what it was. I obtained it by looking at what the default route had been prior to enabling IPv6 forwarding. Of course I could also have simply run tcpdump -i eth0 ip6 and waited for a to show up.To make this permanent, a suitable line can be added to /etc/network.interfaces, so mine now looks similar to:

iface eth0 inet6 static
address 2a01:e35:8b25:aaaa::1
netmask 128
gateway fe80::207:cbff:aaaa:bbbb

[EDIT: 2 Aug 2011: “netmask 128” previously read “netmask 64” It *could* be 64, but more likely 128!!]

So with IPv6 forwarding enabled and a default route successfully restored, we can now proceed.

5 comments to IPv6 and default routes

  • digitalsushi

    Yeah but if the gateway randomly changes to another l2 address, that static assignment is invalid and you’re offline.

  • Indeed!! To digress slightly: what my “getting IPv6 working on a home server” exercise has told me in no uncertain terms is that while it’s true that the IPv6 stack has been around for years now, the integration of the elements to provide a working solution for home users is a long way from complete.

    The basic bricks are there, but a complete, smooth working solution for home users is absolutely not yet ready. I hope that my IPv6 articles are a small step in that direction.

  • Skaramush

    Hi guys,

    First of all, thanks for the great article.
    Second: setting accept_ra and accept_ra_defrtr to 1 didn’t solve the problem for me: the RA message were ignored. I checked in the Linux kernel code where the messages are handled, and they are dropped if forwarding is enabled, even if accept_ra is set. So this doesn’t solve the problem.

    The strange thing is that there has to be way to configure the default route!

    We probably miss here something…


  • Steve

    Brilliant — many thanks. This has solved my problem

  • Gabriel

    I think you could avoid configuring the default route manually by setting accept_ra to 2. See http://www.mjmwired.net/kernel/Documentation/networking/ip-sysctl.txt . It works for me.