Thursday, August 3, 2017

How the IPv6 link-local address is determined

The IPv6 (ip6) link-local address is of significance to the link on which the ip6 network address exists. In other words, in an ethernet world, the link-local address only has meaning within a VLAN and is not routeable. In principle, the address could be routed, but it is forbidden under rfc3513.
Routers must not forward any packets with link-local source or destination addresses to other links.
In this post I'm only going to discuss the link-local unicast address, prefixed by FE80::/10. When I need clarity on link-local addresses I end up on Wikipedia and then at rfc3513. Hopefully you can get a high-level grasp via this post and for deeper detail consult those resources.

What's The Point?

Link local addresses are integral to the ip6 Neighbor Discovery Protocol (NDP) that allows local services and routers to be detected with zero input from the user.

The local machine can build up a table of services and routers on each link. On a linux machine you can quickly view what's out there:
$ ip -6 neighbor show
fe80::250:56ff:fe86:1234 dev eth1 lladdr 00:50:56:86:12:34 STALE
fc01:e5:1102::111:21 dev vlan12  FAILED
But getting into NDP and what this table tells you is not something I have time to do here.

Why Is There A Link-Local Address On My Interface?

Operating systems that have an ip6 stack enabled will assign themselves a link local address. They will ordinarily do that even when DHCPv6 exists on the network. The mechanism itself is known as stateless address autoconfiguration (SLAAC).

When determining an address to use, a linux system appears to conform to rfc2464 although rfc4862 appears to ease the precise definition.
The OUI of the Ethernet address (the first three octets) becomes the
company_id of the EUI-64 (the first three octets).  The fourth and
fifth octets of the EUI are set to the fixed value FFFE hexadecimal.
The last three octets of the Ethernet address become the last three
octets of the EUI-64. -- rfc2464 p. 3
The "Universal/Local" (U/L) bit of the original MAC address is also flipped.

For example:
vnet0     Link encap:Ethernet  HWaddr fe:54:00:d7:40:40
          inet6 addr: fe80::fc54:ff:fed7:4040/64 Scope:Link
The MAC address is fe:54:00:d7:40:40. First ff:fe is inserted in the 4th and 5th octets to become fe:54:ff:fe:40:40 and then the locally-administered bit is flipped (0xe minus 2 equals 0xc). The result is fc:54:ff:fe:40:40 and the full address with the link-local network prepended is
fe80::fc54:ff:fed7:4040/64.


Two things to clarify:
  1. If the locally-administered bit is set, then it is unset and vice versa.
  2. In ip6 addresses :: (double colon) is shorthand for zeros. The full address is actually fe80:000:000:000:fc54:ff:fed7:4040/64.
Windows is a lot different, according to this Microsoft technet post, which references this microsoft technet post, the address is assigned randomly since Vista. It's not referenced in the technet post, but rfc4941 describes two randomised identifier processes.

Was CVE-2016-1409 A Link-Local Bungle?

I have a suspicion (read "guessing"), that CVE-2016-1409 was a mixture of two failures in violation of the RFCs. Namely that:
  1. Cisco and other vendors would route Neighbor Advertisements across hops.
  2. In-path routers did not decrement hop-limit when (1) happens or the final recipient was accepting NA messages when hop-limit did not equal 255.