IPv6 Part 15: To sum up

While I’ve been working on this series on IPv6, my thinking has evolved. It’s clear from reading RFC 7421 that the fixed 64-bit length of the interface ID is now so baked into IPv6 that there’s no point in debating it. If sixteen bits (or rather four nibbles) isn’t enough to encompass a site’s topology, then I accept the assurances (for example in Tom Coffeen’s IPv6 Address Planning) that a global prefix that’s shorter than the standard /48 can be obtained (I still think that the size of the IPv6 address space is over-hyped).

IPv6 has two ways of automating addressing and configuration: DHCPv6 and SLAAC. In practice neither are complete solutions, and they have to be combined in various ways; the standards are still evolving. Something as straightforward as mapping an IP address to a MAC address becomes much harder with IPv6. Such a complex and messy environment is not conducive to good security.

However, the biggest problem I have with IPv6 is the assumption that it means a return to end-to-end addressing. The original purpose of Network Address Port Translation (NAPT) was to stretch the IPv4 address space, and the massively increased address space of IPv6 makes that no longer necessary. The crude one-way filter effect of NAPT needs to be replaced with a proper firewall. Nevertheless, NAPT has had other benefits too, such as:

  • Host identity hiding
  • Network identity hiding
  • Topology hiding
  • Simplification of provider change when using provider-assigned addresses
  • Simplification of multi-homing when using provider-assigned addresses

Various attempts have been made to try and replicate these benefits in IPv6: temporary addresses, “local network protection” (using host routes or Mobile IP), ULAs, NPTv6 and multi-homing via DHCPv6. In chasing the end-to-end addressing dream these have all added complexity to the endpoint device (difficult to manage on an enterprise scale); all, that is, apart from NPTv6, which is a form of NAT.

IPv6 enthusiasts often express a desire to return to the time in the early days of the Internet when end-to-end addressing was feasible. I think that the world has moved on since then: the Internet is no longer as simple or as safe, and we need to adapt our architectures accordingly. We should not assume that end-to-end addressing is always the end goal. When applying the end-to-end principle to the enterprise, it makes more sense to think of the endpoint as lying at the enterprise boundary, where complexity can be more easily handled.

IPv6 Part 3: Address auto-configuration

In the previous post I explained that network prefixes in IPv6 are nearly always a fixed 64 bits in length, with a few exceptions. Strictly speaking, it’s actually the interface ID that’s fixed at 64 bits, which means that because IPv6 addresses are 128 bits long the network prefix has to be 64 bits too. The reason for this is to meet the needs of address auto-configuration, which is a new feature of IPv6 that supports:

  • link-local address auto-configuration (so-called plug-and-play)
  • stateless address auto-configuration (SLAAC, for global addresses)

Link-local addressing is pretty fundamental to IPv6. It enables a host to communicate with other nodes on the same network without the need for manual configuration or a DHCP server. The process is as follows:

  1. In the conventional method the host generates a 64-bit identifier for the interface by taking its 48-bit MAC address and inserting the string fffe into the middle. Then it “flips” bit 7 of the address from 0 to 1, so that the MAC address:

    00:cd:fe:12:34:56

    generates the interface ID:

    2cd:feff:fe12:3456.

    This is what’s known as a Modified EUI-64 identifier (there are other methods but I will cover those in a later post).

  2. The host prefixes this identifier with the link-local network prefix fe80::/64, so that our example MAC address generates the link-local address:

    fe80::2cd:feff:fe12:3456.

  3. The host then tests this address for uniqueness on the local subnet by sending a Neighbor Solicitation message (ICMPv6 type 135) to the generated address. If it gets a Neighbor Advertisement message (ICMPv6 type 136) in reply then the process halts.
  4. If there is no response then the link-local address is assigned to the interface.

IPv6 link-local addressing

You can find more detail on this at Packetlife.

Once the link-local address is configured, the host sends a Router Solicitation message (ICMPv6 type 133) to the All Local Routers multicast address ff02::2. If there’s a local IPv6 router it will respond with a Router Advertisement message (ICMPv6 type 134). If that tells the host that it should auto-configure a global address then:

  1. The host will take the 64-bit global prefix advertised by the router and combine it with the 64-bit interface identifier previously generated to create a global address, so if the prefix is:

    2001:db8:1234:5678

    then our example interface ID generates the global address:

    2001:db8:1234:5678:2cd:feff:fe12:3456.

  2. It will test for uniqueness on the local subnet as for the link-local address
  3. If there is no response then the global address is assigned to the interface.

IPv6 SLAAC

The whole set of messages and processes, together with other ancilliary messages and processes, is known as Neighbor Discovery. In principle other methods of global addressing (manual, DHCP) could use a variable-length prefix. However the address architecture RFC (RFC 4291) stipulates a 64-bit interface ID regardless of the configuration method. RFC 5375 warns against straying from the /64 prefix:

Using a subnet prefix length other than a /64 will break many features of IPv6, including Neighbor Discovery (ND), Secure Neighbor Discovery (SEND) [RFC3971], privacy extensions [RFC4941], parts of Mobile IPv6 [RFC4866], Protocol Independent Multicast – Sparse Mode (PIM-SM) with Embedded-RP [RFC3956], and Site Multihoming by IPv6 Intermediation (SHIM6) [SHIM6], among others.

In fact it’s specifically the SLAAC component of Neighbor Discovery that would be broken by a global network prefix other than /64, because of the way that the interface ID is generated.

In the next post, I’ll delve more into the background of SLAAC.

Yes it’s a lot of bits but…

Let’s take a look at the structure of an IPv6 Global Unicast address (GUA), a globally-routeable address:

IPv6 addresses, like IPv4 addresses, are Big Endian, that is, the most significant bits come first. That’s similar to decimal numbers, where thousands come before hundreds and so on. The most significant bits (the “high-order” bits) at the beginning of a GUA form the global routeing prefix. This is used by Internet Service Providers (ISPs) to route traffic through the global Internet.

The standard IPv6 global routeing prefix assigned to a single-site enterprise is a /48. RFC 3177 specified /48 as the standard prefix for all sites, even home users, but subsequently RFC 6177 recommended longer prefixes for small enterprises and home users. With IPv4 an enterprise may only be assigned a /24, if that. That means that ISPs have (very) roughly 16 million times the address space to work with (248 versus 224); in fact 48 bits provides about 280 trillion prefixes, or roughly 38,000 prefixes for every human on the planet.

It’s the structure at the local end of an IPv6 address that’s surprising for someone like me who has worked with IPv4 all through their career. The network prefix (what in IPv4 is called the subnet mask) is a fixed /64 in length, as opposed to the variable-length subnet masking (VLSM) of IPv4. That means that the interface ID (broadly the IPv6 equivalent of the host ID) is also 64 bits long. In other words there’s enough address space on each subnet for 264 hosts, i.e. 18446744073709551616, or enough M&Ms to fill the Great Lakes.

Now that’s a huge number. With current networking technology it’s difficult to imagine it being practical to have more than, say, 10000 hosts on a single subnet. That only requires 14 bits, so the other (most significant) 50 bits are effectively redundant, in other words 18446744073709535232 addresses or 99.99999999999991%. In practice there is likely to be parallel running of IPv4 and IPv6 on the same subnets for some time, and IPv4 subnets are typically much smaller, say, 256 hosts, so the redundancy will be greater still.

The consequence of this fixed /64 network prefix is that the subnet ID, which is the local part of the network prefix, is typically only sixteen bits. For IPv4, most enterprises use private RFC 1918 addressing combined with Network Address Translation. They often utilise the 10/8 private prefix subnetted down to a /24 for individual subnets, which also provides a 16-bit subnet addressing space. So in practice IPv6 doesn’t provide any additional subnet address space for many enterprises compared to IPv4.

Sixteen bits is still a large number, equivalent to 65536 addresses, and it would be very generous if enterprises used those sixteen bits as a completely flat address space. However they usually structure the local subnet space hierarchically, in order to aggregate routes efficiently and minimise internal routeing tables (just as the global routeing address space is structured). IPv6 does have the advantage for network administrators that addresses are represented in hex rather than IPv4’s decimal; each hex character represents four bits (a “nibble”) as opposed to the 8-bit components of an IPv4 address (an “octet”). This means that the subnet space can be divided conveniently into 4-bit chunks in a way that’s easy to read, and so less prone to error. It is generally recommended (by Coffeen 2014 for example) to follow this practice when designing your IPv6 subnetting structure.

Nevertheless creating a hierarchical structure in this way means that there will be inevitably some inefficiency in the use of the address space. For example, take a site that has 20 buildings with 20 subnets per building. Each nibble can encompass only 16 objects, so you would need to assign two nibbles to the site level of the hierarchy and two to the building level of the hierarchy, thus using up the available subnet space, with quite a lot of redundancy. This is almost a worse-case scenario, but it shows how the address space for local subnetting is not that generous, and looks positively stingy compared to the address space for interfaces.

In summary, IPv6 uses a roughly 48-bit address space for global routeing, That’s a huge amount of prefixes, and to be fair it does deliver the original goal of IPv6, which was to increase the global address space. However, the way that the local part of IPv6 addresses is structured means that there is no useable expansion of address space at the local end. That stuff about galaxies and light-years is (mostly) hype.

In the next post I’ll take a look at why IPv6 addresses are structured in this way.