In every meeting I attend I try to add IPv6 as a topic. It doesn’t always succeed, but when it does, it opens up for interesting discussions. One thing I realize is that changing the mind set of people like me, that has spent years with good old IPv4, takes time. Learning old dogs new tricks and all that. Let’s look at IPv6 addresses again to try to sort up some confusion and discuss new tricks.
The need for NAT – or not?
One thing that keeps popping up is the need for NAT and private addresses. Let’s look at this as two separate issues. Why is private addresses a good thing? Well, if you change service provider you do not have to renumber the network people tell me. My response is that you can still do that. If you want permanent addresses there are Unique Local Addresses, ULA, you can use for the same purpose – to address local resources. Now, this does not replace the global address on the same interface. When setting up communication, the application chooses one sender address and one destination address that works optimally. When communicating with a local printer, use the ULA. When surfing to a web site somewhere on the Internet, use the global address.
Over to part two, the need for NAT. Do you still need it? I guess not. At least not for this reason.
Selecting IPv6 addresses for communication
The task of selecting the right IPv4 address for communication has been an issue for me in many applications when I have a server with multiple addresses attached to different interfaces and networks. In IPv4, how to handle this situation was not really documented. In IPv6 this quickly became important. A desktop host may have a link local address (FE80::), a global address assigned with DHCP/RA and a temporary address for privacy reasons. The site may provide an Unique Local Address prefix too. In addition, the interface has a few multicast addresses to listen to. For a server we usually use permanent addresses, but may still have a few of these to select form in addition to the link local address.
Every IPv6 application needs to be ready for having to select an IPv6 address to send to, and one to send from. If both hosts are dual stack, we will have to test and select address family to (see Happy Eyeballs). The procedure for IPv6 address selection is documented in RFC 3484 – Default Address Selection for IP version 6.
“The IPv6 addressing architecture allows multiple unicast addresses to be assigned to interfaces. These addresses may have different reachability scopes (link-local, site-local, or global). These addresses may also be “preferred” or “deprecated”. Privacy considerations have introduced the concepts of “public addresses” and “temporary addresses” . The mobility architecture introduces “home addresses” and “care-of addresses”. In addition, multi- homing situations will result in more addresses per node. For example, a node may have multiple interfaces, some of them tunnels or virtual interfaces, or a site may have multiple ISP attachments with a global prefix per ISP. The end result is that IPv6 implementations will very often be faced with multiple possible source and destination addresses when initiating communication. It is desirable to have default algorithms, common across all implementations, for selecting source and destination addresses so that developers and administrators can reason about and predict the behavior of their systems.”
A shared task between the application and the O/S
The RFC describes how the address selection is implemented. The application use an API like getaddrinfo() to get a list of IP addresses that matches a host name. The operating system is responsible for sorting this list according to RFC 3484 (with some additions for ULAs, that did not exist at the time). The application then starts with the top of the list and tries to connect and proceeds down the list until it reaches the other party. For dual stack hosts connecting to dual stack servers, this rule is modified by RFC 6555 – Happy Eyeballs - that say that the app should try IPv6 and IPv4 connections at simultaneously. RFC 6555 also suggests that systems could change the RFC 3484 configuration for ordering based on the results of the connection attempts. The rule set is explained this way:
“The algorithms use several criteria in making their decisions. The combined effect is to prefer destination/source address pairs for which the two addresses are of equal scope or type, prefer smaller scopes over larger scopes for the destination address, prefer non- deprecated source addresses, avoid the use of transitional addresses when native addresses are available, and all else being equal prefer address pairs having the longest possible common prefix. For source address selection, public addresses  are preferred over temporary addresses. In mobile situations , home addresses are preferred over care-of addresses. If an address is simultaneously a home address and a care-of address (indicating the mobile node is “at home” for that address), then the home/care-of address is preferred over addresses that are solely a home address or solely a care-of address.”
RFC 3484 implementations in Linux and FreeBSD
The RFC says that there is a default rule set for address selection, but the network or system manager should be able to change this. In Linux, GLIBC uses a configuration file called /etc/gai.conf and in FreeBSD there is a tool called ip6addrctl to manage this list. That makes it possible to add ULA addresses in the address selection rule set even though they did not exist at the time RFC 3484 was published.
Issues with RFC 3484
Microsoft has implemented RFC 3484 in Windows. They have noticed that this affects IPv4 as well, especially the support for Round Robin DNS load balancing since they implemented RFC 3484 address selection for both IPv4 and IPv6. I could not find a way to change the rule set for address selection in Windows.
There are a few known issues with RFC 3484, like the missing ULA address space. Work has started in updating the document, with an RFC and a draft published by the IETF listing the problems that are found, mentioning the issue with Round Robin DNS.
As a developer, read all of these documents
If you are a developer working with network-related code, my advice to you is to read all of the documents I have linked to in this text. Get an understanding how this affects your code as you port it to IPv6. Make sure you include ULAs in your design. And test, test, test. I’ve had applications use site-local addresses when trying to contact a server with a global address. Don’t let that happen to your application. Combine these rules with Happy Eyeballs and you will still have a successful application as the net moves to IPv6.