IPv6 in Linux

Core Technology

Article from Issue 196/2017

IPv6 is the future of the Internet, and it promises many goodies. Discover what your Linux box can do about it today.

IPv4, today's Internet workhorse protocol, offers more than 4 billion IP addresses. This may seem like a lot, but in a world of 7 billion people and every single toaster seemingly wanting an Internet connection, it's actually not. In fact, IANA, the Internet's numbering authority, allocated the last block of IPv4 addresses about six years ago. That doesn't mean there are no spare IPv4 addresses left on the planet – regional operators still have some reserves – but the supply already has been exhausted.

IPv6 comes to the rescue. With 128-bit addresses – that is, about a quadrillion IPs per every human body cell in the world, we'll hopefully be on the safe side for some time. However, IPv6 offers much more than extra bits in the address; it fixes a 35-year irritant of IPv4 operation by allowing the network to function without network address translation (NAT) or DHCP. Moreover, it enjoys being a first-class citizen in your Linux box.

Back to Basics

In general, IPv6 addresses are shown as eight 2-byte, colon-delimited hexadecimal numbers (e.g., fe80:0000:0000:0000:eef4:bbff:fe29:873d). So many numbers are awkward, so a few simplifications are possible. First, you can omit leading zeros: 0001 is the same as 1, and 0000 is the same as 0. Second, you can drop running sequences of all zeros, which are quite common in IPv6 addresses. You can do this only once per address for the longest sequence, though. A double colon shows where zeros were: consider fe80::eef4:bbff:fe29:873d or even ::1, which is just a loop-back address, serving the same purposes as in IPv4. This means a single IPv6 address may have several equally valid representations. If you think IPv6 addresses are more difficult to parse than IPv4, that's true. Luckily, libraries such as glibc handle this for you.

Recall that you also use a colon to separate hostnames and ports, as in To make this work for IPv6 addresses, enclose them in square brackets; for example, try entering https://[2001:4f8:1:10:0:1991:8:25]:80 in your browser. Note this applies to raw addresses only. If a DNS name resolves to IPv6 address via AAAA (aka a "quad-A" record) [1], you don't need any brackets.

As in IPv4, IPv6 addresses are split into two parts. Higher order bits are known as a routing prefix, and there are some well-defined prefixes, as I'll explain shortly. The lower part, which is almost always 64 bits long, specifies the host or interface ID. Bits in between may encode a subnet or serve other purposes, depending on the address type.

A regional regulator could allocate a /32 prefix (e.g., 2a02:06b8::/32) to your provider. The provider then extends it to identify their customers. If it uses 16 bits, the provider can have more than 65,000 distinct clients. "Provider" bits may carry some information; for example, a most significant bit of 1 could indicate the customer is an organization, not a private individual. Or the provider could use the most significant byte to encode a city in which the customer is located. Although this bit affords many opportunities, ultimately the provider allocates a /48 prefix and hands it off to you.

This makes a difference. In the IPv4 world, you (a household or a small company) get a single IP address or two, and that's it. IPv6 strongly encourages allocating prefixes smaller than /64. Address space is "cheap" in IPv6 now, and this affects network design. With a /48 prefix from your provider, you have another 16 bits left in the network portion. You could use a higher order byte to number rooms in your house (assuming you don't have more than 256 of them) and a lower order byte to represent a device. For example, :fc02 could be that IoT thing in the attic. In IPv4, all hosts in your house are usually on the same ("gray") subnet, unless you have a really big house. In IPv6, a fridge is often on a subnet of its own.


Another difference is that you typically have several IPv6 addresses on your box, which I'll examine one at a time.

The first is the link-local address. It's present even if your ISP doesn't know anything about IPv6, as long as your Linux kernel supports the technology (most kernels today do). Link-local addresses begin with the fe80::/10 prefix, and the host part is calculated from the MAC address of the respective network adapter. Running

ip -6 address show

on your Linux box should reveal your link-local address. The -6 switch tells the ip command to show IPv6 addresses only. Listing 1 shows an IPv6 configuration on a box with no global IPv6 connectivity.

Listing 1

A typical IPv6 configuration


Link-local addresses are valid only within the link (i.e., hosts plugged to the same Ethernet switch) and are never routed. In Listing 1, you see the real link-local address of my laptop, but you can't ping it by that address (sorry). They are still useful for cases like Neighborhood Discovery, which is link-local by its nature, or auto-configuration: Obviously, you can't use a global routable IPv6 address while you are trying to obtain one. Link-local addresses also are good for ad hoc networking.

Other "local" IPv6 addresses include a unique local IPv6 unicast address (ULA), or local IPv6 for short, is a private IPv4 address equivalent. The prefix is fd00::/8, which is followed by a random-generated global ID (Figure 1). Unique local addresses are provider-independent and shouldn't be routed over the Internet. A single prefix makes them easy to filter on border routers. You are free to use ULAs the way you want, on their own or together with global routable IPv6 addresses, which belong to the 2000::/3 prefix; that is, they always begin with 2. (See the "Troubleshooting IPv6" box.)

Troubleshooting IPv6

If you ever troubleshoot network problems, ping and traceroute (or tracepath) are your good friends. You can expect them to help you with IPv6 bugs as well, but wait!

$ ping 2001:4f8:1:10:0:1991:8:25
ping: unknown host 2001:4f8:1:10:0:1991:8:25

This return is bad news, really. How could it be that ping doesn't recognize a global IPv6 address?

In many Linux distributions, ping is an IPv4-only tool. The same holds for trace-whatever. What you want here is ping6 and its friends. As the suffix suggests, they're IPv6-enabled. Ping your link-local address to check this:

$ ping fe80::fef8:aeff:feeb:866f
connect: Invalid argument

What's wrong now? Here, ping6 isn't smart enough to deduce which link (or network interface) you are referring to, so you need to add an interface number (as reported by ip link show) as a suffix:

$ ping fe80::fef8:aeff:feeb:866f%3

Now everything should work as expected.

If your distro ships newer iputils packages, the above may not apply to you anymore. Congrats! Yet, you might want to invoke ping -6, just to be sure.

Figure 1: Websites like this help you generate a properly randomized, /48-bit-long ULA prefix.

DHCP, Begone!

An IPv6-enabled box gets one (link-local) address "for free," but what should it do with the rest? IPv6 was designed to benefit from auto-configuration mechanisms. With the Stateless Autoconfiguration (SLAAC) technique, you get a fully operable IPv6 network with no configuration except on routers.

A secret ingredient is ICMP6. You know and love ICMP because it makes ping and traceroute work, but IPv6 assigns ICMP some extra duties. First, ICMP6 matches IPv6 addresses to Ethernet MAC addresses within the local network. This is known as Neighborhood Discovery, and a separate protocol (ARP) was in charge of it in IPv4. By the way, you can examine and change the local neighbors table both for IPv4 and IPv6 with the ip neigh command.

Then, there are router advertisements (RAs). When you were connecting an IPv4 box to the network, you had to supply the default gateway, or it wouldn't be able to communicate with hosts outside the local network. IPv6-enabled routers periodically advertise themselves to connected hosts, and these hosts may also solicit advertisements when needed. When you plug in the cable, your box generates a link-local address and uses it to learn where neighborhood routers are; then, it generates a global routable IPv6 address from the router-supplied prefix, and that's it. You are now connected to all the globe, no NAT required.

The Linux kernel doesn't handle router advertisements on its own, though. The good news is dnsmasq [2] speaks IPv6 and can do router advertisements for you. It also acts as a DHCP server and caching DNS server for your network. A few configuration samples related to RA and DHCPv6 are commented in Listing 2, and you can find more in the dnsmasq.conf.example reference configuration file [3].

Listing 2

dnsmasq configuration snippets


Given SLAAC, you might wonder about the role of manual configuration and DHCP in the IPv6 world. Yes, it's certainly possible to assign an IPv6 address with the good old ip command:

$ sudo ip addr add fd5c:5053:5e0e::1/64 dev eth0

As for DHCP, it also exists for IPv6 under the name DHCPv6. Thanks to SLAAC, it's not mandatory anymore, even on corporate networks; yet, it's still deployed for several reasons. First, you might want to convey the name server, the hostname, and other configuration bits beyond raw addresses. Second, you might want a specific IPv6 address assignment procedure, so you always know who is who. The first is often called "stateless" DHCP, whereas the second is called "stateful" DHCP.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Introduction

    The move from IPv4 to IPv6 must be gradual rather than abrupt. After just two minutes of configuration work, Charly leans back and watches his first IPv6 packets pass through a Miredo tunnel.

  • IPv6

    Is the world ready for the next generation Internet Protocol? We take a look at Linux with IPv6.

  • High Availability VPN

    IPSec prevents many of the clever tricks high-availability products employ. We’ll show you a solution that provides transparent backup for IPSec connections.

  • OpenVPN

    Wireless networks are practical but dangerous at the same time.WEP encryption is unlikely to stop an attacker. But help is at hand in the form of add-on security measures such as an encrypted OpenVPN tunnel.

  • Security Lessons

    Moving data to and from Linux systems under the radar.

comments powered by Disqus

Direct Download

Read full article as PDF:

Price $2.95