Linux – Can Linux be made to honour IPv6 Route Advertisement preferences

ipv6linuxlinux-networking

Bottom Line Up Front: I can't get a Linux box receiving RAs to use the RFC4191 "Default Router Preference" value to prefer higher-priority routes. Instead, whichever default route it learnt first is what it uses, to the detriment of all. Am I missing a config option, or a kernel upgrade, or am I just doomed for all time?

Long version:

I've got a network with a HA default gateway (VRRP/keepalived). The upstream ISP is routing a /48 to the gateway, and I then carve off /64 chunks to assign to the machines in my infrastructure (so they can assign globally-routable addresses to the containers they run). Each machine then advertises its container /64 to the rest of the network via radvd (with AdvDefaultLifetime 0 to show it doesn't have a default route). The gateway boxes also have containers running, so they have their own /64 and advertise that, but with AdvDefaultLifetime 30 because the gateways do have a default route.

I want to be able to do stateful firewalling on the gateway, so all traffic in both directions needs to go through the same member of the HA gateway pair. That's OK, I can do that — one keepalived has a higher priority, I just tell radvd on that machine to also advertise its default route at a higher priority. This way, if the "primary" machine drops off the perch, everything will route to the other machine and we're OK.

Except… Linux doesn't appear to do anything with the router preference value. I've grovelled through the kernel source, and while it carefully preserves the value in the route flags, and rt6_score_route even looks like it does something with the preference, the behaviour I've observed in production (Ubuntu 14.04 with the 3.13 kernel) is that whichever default route was learnt first is the one that gets used, regardless of which has the higher preference.

Apart from haxxing up keepalived to change radvd config files (one with AdvDefaultLifetime 30, when MASTER, and another with AdvDefaultLifetime 0 when BACKUP) and reloading radvd whenever keepalived promotes/demotes, what can I do to ensure that routes with higher preference in the RA get preferred?

Best Answer

Recent Linux kernels have the feature that you ask for. If you configure the kernel, set CONFIG_IPV6_ROUTER_PREF, see Networking support -> Networking options -> The IPv6 protocol -> Router Preference (RFC 4191) support. You may need to recompile the kernel if your distro defaults to switch this feature off.