How does IPv6 source address selection work in Linux?

How does Linux choose which of possibly many IPv6 source addresses to use when connecting to another site? I am opening connections to 6to4 and non-6to4 sites from a host configured with both a 6to4 and a non-6to4 address.

My Linux box was configured with 6to4 and non-6to4 IPv6 addresses and it did indeed seem to pick the 6to4 source address when connecting to another 6to4 host, and the non-6to4 address when connecting to a non-6to4 host. This was faster because both directions of the 6to4 link were able to bypass the tunnel server. I wasn't sure if I was just getting lucky or if this was the expected behavior.

An iPad with the same IPv6 route advertisements chose to use IPv4 even when connecting to sites like ipv6.he.net, so I don't advertise the 6to4 route anymore. The local router still has its own 6to4 gateway to bypass the tunnel for outgoing 6to4.


Solution 1:

The best document on this is from Ulrich Drepper, he describes the gai.conf, the relationship with RFC 3484, the connection of glibc getaddrinfo(3) and kernel address selection.

http://www.akkadia.org/drepper/linux-rfc3484.html

BTW: iproute2 supports in later versions the gai.conf file, use ip addrlabel show command. You can find some samples in this article:

  • http://linux-hacks.blogspot.com/2008/04/default-address-selection-part-1.html
  • http://linux-hacks.blogspot.com/2008/07/default-address-selection-part-2.html

Greetings
Bernd

Solution 2:

The routing table, in addition the scope identifier is used for link-local scope addresses.

http://en.wikipedia.org/wiki/Routing_table

http://en.wikipedia.org/wiki/IPv6_address#Link-local_addresses_and_zone_indices

edit: As an interesting addendum, I found recently that the TCP stack has more strict requirements than UDP or datagrams. With UDP you can quite frequently avoid the scope identifier if the address is obvious on the host, however TCP does not allow you this freedom at all, the identifier must always be specified.