The IPv6 post office: labelling and sorting everywhere

Francesco Prelz

INFN, sezione di Milano

and members of the HEPix IPv6 group.


  1. Protocol preference: a key IPV4 → IPv6 transition tool.
  2. The joys and dreads of RFC3484RFC6724.
  3. Where, how and when is preference established?
  4. Four very pratical catches.
  5. How to keep your eyeballs happy.

The IPv4→IPv6 transition.

Possibly the main change with IPv6.

Every network end-point is always associated to multiple active network addresses.

Address families

Address ClassIPv6 PrefixIPv4 equivalent
Local Host::1/128Local Host (
Link-Localfe80::/10Autoconfigured (169.254/16, RFC3927).
(Globally) Unique Local Addresses (RFC4193)fc00::/7Private classes (10/8, 172.16/12, 192.168/16) - no hope to be globally unique
Temporary (for privacy, RFC4941)Undistinguishable from autoconfigured unicast.Not available.
Public unicast::/0Public unicast (0/0)
Public multicastff00::/8Public multicast (224/4)

Source and destination address selection.

Should the following be learned by heart ?
«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, temporary addresses are preferred over public addresses. In mobile situations, home addresses are preferred over care-of addresses».
(RFC 6724, and the old 3484 as well).

Source and destination address: whose choice?

  • The choice of a destination address and address family is usually in the hands of application developers:
    • DNS query results from getaddrinfo() are ordered via RFC6724;
    • they SHOULD be at least iterated over!
    • with appropriate (and possibly expensive) fallback - see later.
  • The choice of a source address when initiating communication is very often left to the operating system (no explicit call to bind(2)).
  • The choice of a local listen address and address family is often left unspecified.
    It is considered out of RFC6724 scope (§ 2), but glibc uses RFC3484 (its predecessor) for this purpose!

The RFC6724 master policy table.

::1/128 50 0 Localhost
::/0 40 1 All of IPv6
::ffff:0:0/96 35 4 All of IPV4 ('mapped')
2002::/16 30 2 6to4 tunnel (transition)
2001::/32 5 5 Teredo tunnel (transition)
fc00::/7 3 13 Unique Local Addresses
::/96 1 3 'IPv4 compatible' - deprecated
fec0::/10 1 11 Site-local addresses - deprecated
3ffe::/16 1 12 6bone - dead and deallocated
Matching source/destination label overrides higher destination preference.
RFC6724: SHOULD be configurable.

/etc/gai.conf, ip -6 addrlabel and friends.

  • The path of least resistance to allowing the 'administrative policy override' of the master policy table has been to expose the table itself, in the RFC format:
    • Both for the destination choice (/etc/gai.conf on Linux)
    • and for the source choice: ip -6 addrlabel show:
      prefix ::1/128 label 0
      prefix ::/96 label 3
      prefix ::ffff: label 4
      prefix 2001::/32 label 6
      prefix 2001:10::/28 label 7
      prefix 2002::/16 label 2
      prefix fc00::/7 label 5
      prefix ::/0 label 1
  • FreeBSD offers an ip6addrctl command, derived from the KAME protocol stack, to handle both source and destination address preferences and labels (includes a nice use count).
    → but MacOS hasn't picked it up yet.
  • Windows:
    netsh int ipv6 show[/set/add/delete] pre[fixpolicy].

Catch #1: I-believed-it-would-use-IPv4.

  1. So you hear that enabling IPV4/IPv6 dual stack on core services is good, and you do that for your main mail exchanger: mail exchanger = 10 has address has IPv6 address 2001:760:4210:1::a.
  2. The MX start receiving e-mail from nodes on the same network link that have no IPv6 configuration other than an enabled stack:
    Mar 15 05:01:31 smtp1 sendmail[1244]: (...) relay=[IPv6:fe80::21d:9ff:fe10:faf9]
  3. IPv6 is normally preferred over IPv4, so when a destination host resolves to an on-link IPv6 prefix (as known via Router Advertisements), communication will happily occur via link-local scoped IPv6:
    fe80::20e:cff:fe4c:1ea5 lladdr 00:0e:0c:4c:1e:a5 REACHABLE
    2001:760:4210:1::a      lladdr 00:0e:0c:4c:1e:a5 REACHABLE

Catch #2: the 6to4 address and default route.

  1. The silent majority of users of a network link have IPv6 enabled by default.
  2. One of them decides to turn on Windows' Internet Connection Sharing (ICS) service.
  3. Unless protective measures are in place (see RFC6104), all hosts with an active IPv6 stack get a 6to4 public address and default route.
  4. Is this going to be a problem, according to the RFC6724 policy table ?
    • No, but it is a problem for the RFC3484 default policy table, which has all of IPv4 in the lowest precedence class!
  5. In that case (older OS versions), until the address and route become deprecated (e.g. by broadcasting a counter-advertisement), IPv6 is preferred to reach all services that resolve on IPv6 (all well-known services by now).
  6. As IPv6-on-IPv4 tunnels are usually filtered communication fails.
  7. One could still broadcast addresses and routes for other public prefixes...

Catch #3: the preferable local address.

  1. All is well on an IPv6 host with a public IPv6 address.
  2. Until one decides to add another public address, that happens to sort higher than the address that the host resolves to in the DNS:
    inet6 2001:760:4210:1::da:da01/64 scope global valid_lft forever
    inet6 2001:760:4210:1::d/64 scope global valid_lft forever.
  3. Suddenly, SSL hostname verifications of connections originating from the host start failing, as the traffic originates from the new address.
  4. Solution: either tweak the source prefix table:
    prefix 2001:760:4210:1::da:0/112 label 8.
  5. Or make sure all services bind their sending sockets to a specific address...

Catch #4: the dual-stack listener.

  1. On hosts with hybrid IPv6/IPv4 network stacks (e.g. Linux), services that bind to the IPv6 'unspecified' address (:: - all-zeros) will happily bind to both IPv6 and IPv4 (unless they opt out via the IPV6_V6ONLY sockopt).
  2. But usually this is obtained programmatically by requesting a passive socket on address family PF_UNSPEC.
  3. Glibc handles this request by providing a source address that is preferred for connecting to localhost according to the rules of RFC3484, which is superseded by RFC6724, that claims it doesn't apply to this case.
  4. This used to return a dual-stack listening socket, until a 2008 glibc commit fixed an issue where the IPv6 'localhost' address (::1) wasn't being assigned link-local scope, as mandated by RFC4291.
  5. Result: as the IPV4 localhost address has the same label as all of IPv4 in the RFC6724 default rules, IPv4 single-stack binding is now preferred.

Happy eyeballs ?