Tuesday, September 20, 2011

Dual stack host default address selection

As many organizations ponder IPv6 deployment, the most popular approach will be dual-stack deployment according to a recent survey. This approach entails activating IPv4 and IPv6 address types and assigning corresponding addresses by defined means such as manual, DHCP or auto-configuration for a given device's interface(s). All major host operating systems (OSs) support IPv4 and IPv6 and in some cases auto-configure IPv6 addresses by default.

When an application seeks to communicate with a remote host given its hostname, the application calls the getaddrinfo() sockets API call. This API call triggers one or more DNS lookups (though other forms of name resolution could be used) with the query name set to the hostname passed in the getaddrinfo() call, the query class set to Internet and the query type set to A and AAAA on successive DNS queries. So given a host with both IPv4 and IPv6 interface addresses and destination host name resolution yielding both IPv4 and IPv6 addresses, which addresses are used? Microsoft, Linux, Unix and Mac operating systems all prefer IPv6 source addresses over IPv4 by default. when an appropriate IPv6 destination address is available.

RFC 3484 defines an algorithm for source address selection in the form of a policy table which prioritizes precedence values and preferred source address prefixes for returned destination addresses. This table enables the host to select the most appropriate source address given the possible destination addresses returned with the DNS queries. The original default policy table published in RFC 3484 appeared as:


PrefixPrecedenceLabelMeaning
::1/128500localhost
::/0401Default (matching unicast) IPv6 address
2002::/163026to4
::/96203IPv4-compatible IPv6 address
::ffff:0:0/96104IPv4-mapped IPv6 address

While RFC 3484 defines independent rules for selecting source and destination addresses based on the policy table, the logic is generally the same and consists of selection in the following priority order:

  1. Prefer the same address type
  2. Prefer the same address scope (link-local, site/ULA, etc.)
  3. Prefer non-deprecated addresses (avoid both globally deprecated addresses like site-local and addresses in deprecated state)
  4. Prefer home addresses over care-of addresses (Mobile IPv6)
  5. Prefer source addresses on the selected outbound interface assigned by the designated next hop (e.g., if the outbound interface connects to multiple ISPs, each of which assigned an IP address to the interface, select the one assigned by the corresponding ISP (next-hop)
  6. Prefer matching labels (source and destination prefix mapping)
  7. Prefer public address space
  8. Prefer the address with the longest matching prefix up to the subnet prefix length (this "up to" qualifier added to enable proper DNS round robin operation where multiple round robin destinations on the same subnet resulted in always the same one being selected, that having the longest total bit-wise matching prefix

RFC 3484 is currently undergoing revision and is currently in Internet draft status to add Unique Local Addresses (ULA) as well as Teredo addresses. Though unofficial as yet, the revised policy table currently looks like:

PrefixPrecedenceLabelMeaning
::1/128600localhost
fc00::/7501ULA
::/0402Default (matching) IPv6 address
::ffff:0:0/96303IPv4-mapped IPv6 address
2002::/162046to4
2001::/32105Teredo
::/96110Avoid IPv4-compatible IPv6 address
fec0::/10111Avoid site local IPv6 address

A given host's policy table may be modified if needed in one of the following ways depending on the OS:

  • On Linux you can explicitly denote a prefix as non-preferred setting the preferred_lft parameter to 0. For example, ip -6 addr change 2001:db8:4e/128 dev eth0 preferred_lft 0 disables selection of 2001:db8::4e address as an outbound source address.
  • On Unix/Solaris you can edit the /usr/sbin/ipaddrsel.conf file which is formatted just like the policy tables above. This allows insertion or demoting of address prefixes as desired. Run the /usr/sbin/ipaddrsel command to load the new configuration.
  • On Windows XP, use the ipv6.exe command to update the policy table for a given prefix in the form of:
    ipv6 ppu prefix precedence precedence_value srclabel label_value_source [dstlable label_value_dest ].
  • On Windows 7, Server 2003 and 2008R2, you can update the policy table for a given prefix in the form of:
    netsh interface IPv6 add prefixpolicy [prefix =] prefix/length [precedence=] precedence_value [label=]label_value[[[store=] {active | persistent}]].

Of course creation of and sending of an IP packet with the best match IP source and destination addresses does not guarantee delivery as intermediate transit nodes may or may not support the chosen protocol. As with most things, having a second or third choice improves the probability of a successful connection.

No comments:

Post a Comment