IPv6 adoption is increasing, and along with it come a new set of behaviours and defaults that system administrators and users must learn and become familiar with. I was recently caught out by Linux’s handling of IPv6 router advertisements (RAs) when forwarding is also enabled on the interface. It took me a while to figure out and searching for obvious terms (such as those in the first half of the title of this post) didn’t immediately yield useful answers, so here is my attempt to help shed some light on the subject.
By default Linux will ignore IPv6 RAs if the interface is configured to forward traffic. This is in line with RFC2462 which states that a device should be either a Host or a Router. If you’re forwarding packets you’re a router and you’re therefore expected to be sending RAs, not receiving them. This policy does make a certain amount of sense but there are obviously situations where it can be useful to accept RAs and still forward packets over the interface. The confusing part is that the Linux IPv6 stack allows the
accept_ra sysctl to be set to 1 (enabled) at the same time as the
forwarding sysctl is set to 1, yet all incoming RAs are ignored with no hint as to why. If you’re not aware that the default behaviour is to ignore RAs when forwarding is enabled it looks very much like autoconfiguration has simply broken.
The key piece of information is that makes everything as clear as mud is realising that the
accept_ra sysctl’s are not simple boolean enabled/disabled flags like many of their brethren. There are instead three possible values for each, all clearly documented in sysctl.txt, when you take the time to read it. Ironically the documentation states the type of the values as “BOOLEAN” even though they’re not… at least it helped me to feel better about my hasty assumption that the sysctl’s were boolean values.
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.
The documentation for
forwarding is similar, but much longer, so you can refer to the link above to see it.
Conclusion: If you want to autoconfigure IPv6 addresses on an interface that you’re also forwarding IPv6 traffic over, you need to set
accept_ra to 2.
No doubt there are more IPv6 quirks and defaults like this waiting to trap me in the future 🙂
 Arguably you really don’t want to be autoconfiguring addresses on your router ever, but that’s a philosophical debate that isn’t really relevant to this post.