IPv6 source address routing with multiple uplinks (SixXS)

by cmur2 on 2013-07-13 in Linux

Why or maybe when do you want to use source address based routing on Linux with IPv6? In my use case I have two IPv6 capable uplinks attached to a server, the native IPv6 provided by my hosting provider (exactly one address :/) and a SixXS static tunnel.

Initially there was only the native IPv6 connection (on interface venet0), and that was the default gateway for every IPv6 packet, too. To be able to use more addresses I requested a SixXS static tunnel which gave me a second interface, named sixxs. The default gateway remained venet0 since there were services running on it.

After setting up the SixXS tunnel, it pinged flawlessly in the SixXS admin panel but did not respond to any pings from outside the assigned subnet. That’s because the Linux Kernel by default judges the route to take only from the destination address of a packet, and since the echo replies should not go to the SixXS subnet (even if the echo requests came over sixxs) they were emitted through venet0 and dropped by my hosting provider afterwards.

A first hint on the solution I found here: policy based routing with IPv6. I knew the concept beforehand for IPv4 but didn’t cross the bridge that policy based routing should be usable for IPv6 as well (with some subtle differences).

The core idea is to create a new routing table for every uplink (only sixxs here) except the default uplink (venet0). All created routing tables then get a new default gateway for their respective uplink provider and a rule, when to use which routing table (and therefore which uplink).

Create a (named) routing table by adding a line like 200 sixxs into /etc/iproute2/rt_tables (make sure you have iproute2 installed) where sixxs is the name and 200 the routing table’s number which should be unused. See here for more routing table basics.

echo "200 sixxs" >> /etc/iproute2/rt_tables

Next create a rule that uses the packet source address to determine if we should use the sixxs routing table (and uplink):

ip -6 rule add from 2001:db8:1:1::/64 table sixxs

I use the 2001:db8:1:1::/64 prefix here instead my real SixXS prefix - 2001:db8:1:1::1 would be the PoP IPv6 address, 2001:db8:1:1::2 my IPv6 address.

Finally add the respective default gateway (the PoP IPv6 address) to the sixxs routing table via the sixxs interface:

ip -6 route add default via 2001:db8:1:1::1 dev sixxs table sixxs

Optionally delete the old route from the main routing table since it won’t come into use anymore:

ip -6 route del 2001:db8:1:1::/64

While the above description is suited for simply fixing the routing to use a packets source address for choosing the right uplink, policy routing in general can be used for many other fancy things when dealing with more than one uplink…

The post »IPv6 source address routing with multiple uplinks (SixXS)«
is licensed under Creative Commons BY-NC-SA 3.0.