Linux, IPv6, router advertisements and forwarding

By default, a Linux host on an IPv6 network will listen for and solicit router advertisements in order to choose an IPv6 address for itself and to set up its default route. This is referred to as stateless address autoconfiguration (SLAAC).

If you don’t want a host to automatically configure an address and route then you could disable this behaviour by writing “0″ to /proc/sys/net/ipv6/conf/*/accept_ra.

Additionally, if the Linux host considers itself to be a router then it will ignore all router advertisements.

In this context, what makes the difference between router or not are the settings of the /proc/sys/net/ipv6/conf/*/forwarding files (or the net.ipv6.conf.*.forwarding sysctl). If you turn your host into a router by setting one of those to “1″, you may find that your host removes any IPv6 address and default route it learnt via SLAAC.

There is a valid argument that a router should not be autoconfiguring itself, and should have its addresses and routes configured statically. Linux has IP forwarding features for a reason though, and sometimes you want to forward packets with a Linux box while still enjoying autoconfiguration. In my case I have some hosts running virtual machines, with IPv6 prefixes routed to the virtual machines. I’d still like the hosts to learn their default route via SLAAC.

It’s taken me a long time to work out how to do this. It isn’t well-documented.

Firstly, if you have a kernel version of 2.6.37 or higher then your answer is to set accept_ra to “2″. From ip-sysctl.txt:

accept_ra – BOOLEAN

Accept Router Advertisements; autoconfigure using them.

Possible values are:

  • 0 Do not accept Router Advertisements.
  • 1 Accept Router Advertisements if forwarding is disabled.
  • 2 Overrule forwarding behaviour. Accept Router Advertisements even if forwarding is enabled.

Functional default:

  • enabled if local forwarding is disabled.
  • disabled if local forwarding is enabled.

This appears to be a type of boolean that I wasn’t previously familiar with – one that has three different values.

If you don’t have kernel version 2.6.37 though, like say, everyone running the current Debian stable (2.6.32), this will not work. Helpfully, it also doesn’t give you any sort of error when you set accept_ra to “2″. It just sets it and continues silently ignoring router advertisements.

fuuuuuuuuuuuuuuuuuuuuuu

Fortunately Bjørn Mork posted about a workaround for earlier kernels which I would likely have never discovered otherwise. You just have to disable forwarding for the interface that your router advertisements will come in on, e.g.:

# echo 0 > /proc/sys/net/ipv6/conf/eth0/forwarding

Apparently as long as /proc/sys/net/ipv6/conf/all/forwarding is still set to “1″ then forwarding will still be enabled. Obviously.

Additionally there are some extremely unintuitive interactions between “default” and “all” settings you may set in /etc/sysctl.conf and pre-existing interfaces. So there is a race condition on boot between IPv6 interfaces coming up and sysctl configuration being parsed. martin f krafft posted about this, and on Debian recommends setting desired sysctls in pre-up headers of the relevant iface stanza in /etc/network/interfaces, e.g.:

iface eth0 inet6 static
    address 2001:0db8:10c0:d0c5::1
    netmask 64
# Enable forwarding
    pre-up echo 1 > /proc/sys/net/ipv6/conf/default/forwarding
    pre-up echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
# But disable forwarding on THIS interface so we still get RAs
    pre-up echo 0 > /proc/sys/net/ipv6/conf/$IFACE/forwarding
    pre-up echo 1 > /proc/sys/net/ipv6/conf/$IFACE/accept_ra
    pre-up echo 1 > /proc/sys/net/ipv6/conf/all/accept_ra
    pre-up echo 1 > /proc/sys/net/ipv6/conf/default/accept_ra

You will now have forwarding and SLAAC.

everything went better than expected

12 Responses to “Linux, IPv6, router advertisements and forwarding”

  1. Wildcard SSL Certificate Says:

    WE have just started upgrading our test network to IPv6, it was much harder than i thought it would be, then the biggest head ache of all setting up the VLANS again :( lets just say its been a long long day

  2. kissg Says:

    Wow! This post is great. It solved my problem. Thanks.

    I just put necessary echo commands into a new script called /etc/ppp/ipv6-up.d/0dhcp-slaac.

    Gabor

  3. Jeff Loughridge Says:

    Great post. I couldn’t determine why my linux VM wouldn’t accept RAs until Google led me here. Thanks for the help.

    Jeff L.

  4. Thank Goodness for NAT66 Says:

    [...] I struggled to figure out why the debian router wouldn’t use SLAAC to configure its external interface. I knew that enabling forwarding would result in the OS ignoring Router Advertisements (RAs). I tried tweaking the IPv6 variables in the /proc filesystem. No luck. Fortunately, I stumbled upon a blog post called Linux, IPv6, Router Advertisements, and Forwarding. [...]

  5. Ravi Varma A Says:

    Very good information. It was very useful and it solved my issue.

  6. Blog o’ Doom » Native IPv6 On Comcast Says:

    [...] and 1 on the internal interface and packets will still be forwarded and you will accept RAs. See this blog for more [...]

  7. Gwen L. Says:

    Thanks for some more details than I’ve found elsewhere, especially the semantics of what this mysterious “2″ value I’ve seen prescribed for accept_ra is.

  8. Stormy Says:

    You’ve captured this perfcelty. Thanks for taking the time!

  9. Tom MCSE Says:

    Great IPv6 info.

    Thanks a lot for this wonderful tutorial about IPv6.

    Tom MCSE

  10. l_bratch Says:

    Thanks very much. My ppp0 interface on Arch defaulted to “2″ for accept_ra, so my IPv6 routes were being messed up continually.

  11. Ramkumar N Says:

    Very good and clear information.Helped me a lot…

  12. IPv6 über DHCP an KVM Gäste verteilen | Sebastian Müller Says:

    […] Wenn nicht ::1 genommen wird, muss das gateway im gast entsprechend angepasst werden. ::1 erspart diese Arbeit. Die pre-up echo’s sind ein workaround, da nur entweder accept_ra ODER forwarding funktioniert. Genaueres findet man hier. […]

Leave a Reply