Upto: Table of Contents of full book "Internet of Things - a techie's viewpoint"

IPv6 on consumer home routers

This chapter was meant to be the first part of a three part series on Homenet for the Linux Journal. Very sadly, the journal closed down in August 2019 and so this was never published.


This article, and the following ones, makes many references to RFCs. These are the IETF Request For Comments, and often are the formal specifications of many internet protocols. They are usually pretty heaving reading! They are all at https://www.ietf.org/standards/rfcs/.


Home networking seems to be pretty straightforward right now. You can add almost anything in a plug-n-play mechanism, and mainly, things just work. The home network typically uses IPv4 which has been around forever, it uses DHCP and NAT transparently to manage only having one IPv4 address, you can add wireless extenders, add Zigbee networks through a gateway, and most of the time our precious geek skills aren't needed any more. What could change?

Bandwidth requirements are obviously increasing, with 4k TVs becoming common and 8k on the horizon. A 2017 report by the Australian NBN Co estimates that the typical Australian home will have 30 connected devices by 2020, while forums such as the LIFX forum have many posts on the failure of many wireless routers to cope with more than 30 devices. Of course, not all the home devices are on WiFi. Some will be on Zigbee, Z-Wave or 6LoWPAN networks, bridging through to the home IP network. Complexity is steadily increasing. In the not too distant future many of us will have multiple ISPs, with access via 5G wireless as well as landline into the home, using hubs such as the HTC 5G Hub.

With this increasing complexity, the IETF (Internet Engineering Task Force), responsible for the multitude of internet technologies such as TCP/IP, has devised an architecture which it believes is suitable for home networks of the future: Homenet. It is based on IPv6 rather than IPv4, does away with NAT, can use multiple subnets each for their own purpose, manages addresses from several ISP connections and exploits the IPv6 addressing system to full advantage.

In these articles, we look at what is involved in setting up a Homenet. While in the future this process is hoped to be transparent or at least friendly for the home user, at present much of it is geek territory. It is hoped that engineers will take this nerd-level knowledge and build user-friendly systems. The aim is for Homenet to be even easier to use than current IPv4 systems, but based on a more solid architectural base.

This series looks at Homenet, and how to get there from here. We start from the assumption of "simple" home networking using IPv4, and build up to the current state of Homenet. That can all be done using current tools and distros. We divide this into several parts:

The series is incremental: you can stop at any point and hopefully will have gained something.

IPv4 and IPv6

Most home systems are currently IPv4, apparently, but maybe not actually, on a single subnet. NAT (network address translation) is in heavy use both to overcome the shortage of IPv4 addresses (good) and to act as firewall and filtering mechanism (bad). The good side of NAT is that it allows a single IPv4 address to act for a whole subnet of hosts, with hosts able to access external global addresses via a mapping mechanism of IP packets.

NAT however suffers from a number of issues which have been well documented. It doesn't easily scale up to complex systems with double- or even triple-NAT with corresponding fragility. Services running within the network which need to be accessible from outside use techniques such as port forwarding either manually configured or using UPnP IGD (Internet Gateway Device protocol), or (unreliable) hole punching. Double NAT (NAT router within NAT network) will often break services which rely on hole punching, such as many VoIP services amd multi-player games.

With IPv6, NAT goes away. Services on different hosts have their own IPv6 address so NAT workarounds like UPnP IGD are not needed. Port forwarding is replaced by routing which simplifies security. DHCP is still there, but there is also SLAAC (stateless autoconfiguration) for better autoconfiguration of IP addresses. In all, there are good technical reasons to move to IPv6, and for the ordinary user, it is a pretty seamless transition.

Setting up the home routers

My ISP is the Australian company Lightning Broadband. By default, I only got a single IPv4 address from them, and used NAT and DHCP to deal with the hosts in my network. But all I did was ask, and they provisioned me with IPv6. Hopefully your ISP can do the same.

My router is a Linksys EA6900. Under the Connectivity menu entry is a flag to turn IPv6 on. While it is a satisfactory home router, it is woefully lacking when it comes to telling me what is going on. There are no logs to tell me what is happening, and the first indication I had that IPv6 was working is that using ifconfig, IPv6 addresses suddenly started showing up on my PCs and laptops.

This part of the series is about what you can expect to see and do with IPv6 on your network with a consumer home router. Note: home routers vary widely in their IPv6 support. A rock-bottom router such as the Edimax N300 has no IPv6 support. Up a level in cost, the TP-Link Archer C60 claims to support IPv6, and does get external IPv6 addresses but requires manual configuration on the LAN side. The mid-range Linksys EA6900 is better still, but not ideal.

IPv6 addresses

"IPv6 addresses suddenly started showing up..." How was that? What did they look like? This section is a primer on IPv6 address - skip if you already know. IPv6 addresses are 128 bits, usually expressed in hexadecimal (4 bit) nibbles, 2 per byte. Each address thus uses 32 nibbles and a typical example could be 2400:3740:200:d900:39d4:560b:ef93:e50. There are shortcuts which use special rules, with the simplest case being ::1 for the loopback address for localhost. Apart from that address, IPv6 addresses are singularly unmemorable and usually require a DNS server to map names to addresses.

This will turn into one of the Homenet requirements: appropriate zeroconf DNS servers within the home.

Traditionally one used ifconfig to find out network information. This is being replaced by ip. To find the addresses assigned to the interfaces on a host, use

	  ip addr
or for a particular interface, say

	  ip addr eth0

Before delving into the addresses, please note a change of notation from using netmasks to CIDR (classless inter-domain routing, if you can figure out what that means!). IPv4 addresses were traditionally listed by the IP address itself, and the 32 bit netmask for that network. So for example, ifconfig would report

        inet  netmask ...
For IPv6, we don't want a 128 bit netmask - 32 hexadecimal digits are too cumbersome! What is used is the prefix length, standing for the number of bits used to distinguish this network from any other. Ths is known as CIDR format. So the above netmask of corresponds to a prefix length of 24: 24 binary ones followed by 8 zeroes. The IPv6 address below comes from a 64 bit prefix, or a /64 prefix:

	  inet6 2400:3740:200:d900:39d4:560b:ef93:e50  prefixlen 64
That is, a 64-bit (16 nibbles) network address of 2400:3740:200:d900 and a 64-bit (16 nibbles) node address in that network of 39d4:560b:ef93:e50.

Here is one of the little secrets of IPv6. Much is said about an address space of size 2128. In practice, 64 bits is the maximum prefix size allowed for the network address, and the remaining 64 bits are for the node addresses within that network. So there can be 264 networks, with each one containing 264 nodes. (Again, simplified from reality, but you get the idea, I hope).

A prefix might be, say, /56. This means that you have one network of a 56 bit prefix, with 28 possible subnets each with upto 264 hosts. This will be another component of Homenet: it wants to support subnets in the home, so your ISP will hopefully be giving you a /48 prefix or at worst a /56. If they only give you a /64, then you can't do any proper IPv6 subnetting and need to change your ISP.

Types of IPv6 addresses

Running ip addr on a host will often produce an output such as

     inet brd scope global eth0 ...
     inet6 2400:3740:200:d900:f49f:eb3b:2b04:64a5/64 scope global temporary dynamic ...
     inet6 2400:3740:200:d900:461e:a1ff:fe3b:7531/64 scope global dynamic ...
     inet6 fe80::461e:a1ff:fe3b:7531/64 scope link ...
Apart from the first entry of the IPv4 address, the rest are IPv6 addresses, here of 3 kinds. They are

Link local addresses

These addresses are non-routable and correspond to the IPv4 private addresses. They have the prefix fe80::/10, such as the above fe80::461e:a1ff:fe3b:7531. They are typically self-assigned (often based on the MAC address), and are unique on any network segment. They can be replicated on different segments though by other independent hosts: that is, two hosts on different networks can have the same link local address. So they cannot be used as globally unique addresses.

This possible duplication on different network segments causes ambiguity to certain programs. For example, ping doesn't know which interface to try if there are multiple interfaces. The command

	  ping fe80::c474:4605:44af:462c
throws up the uninformative error

	  connect: Invalid argument
What it means is that the interface hasn't been specified. The command for interface wlp2s0 should be

	  ping -I wlp2s0 fe80::c474:4605:44af:462c
(you can use ping or ping6 - they are the same executable) or you can put the interface after a '%' sign in the address:

	  ping  fe80::c474:4605:44af:462c%wlp2s0

Global unique addresses

A GUA (Globally Unique Address) is just that: routable and unique on the internet. It is formed from the prefix and usually the MAC address (but see the next section). An example in the above is

	      inet6 2400:3740:200:d900:461e:a1ff:fe3b:7531/64 scope global dynamic
'global' is the keyword here.

Global temporary addresses

These addresses are also GUAs, globally unique and routable. However, they are temporary addresses created for example by a browser for a session. They are typically randomly generated from the prefix, and are relatively short lived. They hide the 'real' identity of the originating host for privacy reasons. See IPv6 temporary addresses and privacy extensions for further details. (and RFC4941). An example, in the above is

	      inet6 2400:3740:200:d900:61dc:bd3c:bfe7:c2e1/64 scope global temporary deprecated dynamic
'global temporary' are the keywords here. These addresses don't last long and are just to obfuscate the 'real' GUA from the rest of the world that doesn't need it.

In addition you will later come across

Unique local addresses

A ULA (unique local address) is in the range fc00::/7. You can choose any addresses in that range. Their purpose is to provide unique addresses within a network of possibly many subnets, and is routable across all those subnets - but not externally. They may be generated as SLAAC or DHCPv6 addresses.

The 'scope' for those subnets is deliberately not specified, but for home networks is most likely to be all those internal subnets reachable from your ISP gateway, and the gateway itself forms the 'boundary' of the network. These addresses are intended to allow access to any host throughout a household network. All nodes on the network should have a ULA, so that each node can address any other node. For example, the home file server and the home web server will have ULAs so every host on the home network can access them.

Multicast addresses

Multicast addresses are in the ff00::/8 block. I will use some later, and there will be more detail in the next section and in later parts of this series.

An interface wil typically have at least three IPv6 addresses: a link-local address (LL), a unique local address (ULA) and a globally unique address (GUA). It may have many more though, such as temporary GUAs. This is different to IPv4 where an interface usually only has one address.

How are IPv6 addresses generated?

We won't actually need this information, but it is worth asking how link local addresses and permanent global addresses are generated. Everywhere you will read that they are generated from the 48 bit MAC address: stretch the MAC address a bit, pad the middle with some extra bytes, flip some bits and there you have it - an EUI64 address (extended unique identifier, 64 bits).

Of course, it is more complex than that. This section isn't required, but may help in understanding the addresses you will see on your own system. The address assignment types include

Static assignment

You can hard-code the address. System administrators might like to do this for e.g. servers, to ensure they can remember their address. The assignment might be based on the IPv4 address, such as 2400:3740:200:d900:: corresponding to an IPv4 address of

Stateless Address Autoconfiguration (SLAAC)

A node queries the router for an address prefix. It then creates its own GUA typically by appending the EUI64 part to the prefix. The router will not typically know this address - and neither will anyone else! This could cause issues if you need to find the address of the node - see later for zeroconf DNS. See http://computer-outlines.over-blog.com/article-dynamic-ipv6-networking-part-4-slaac-118827328.html for more details. SLAAC addressing is used according to bits set in the router prefix information.

DHCPv6 stateful assignment

This is most like DHCPv4, where the router is asked to determine an IPv4 address from an ethernet address. DHCPv4 may give an IPv4 address by looking up an administrator supplied table of MAC/addresses or by generating one from a certain range.

The IPv6 variation is that instead of an ethernet or wifi MAC address, it supplies a DUID (DHCP Unique Identifier). Currently recognised formats (RFC8415) include

The DUID for a Linux box can be found from the lease file - see How can I find out my system's DHCPv6 DUID?

Stateful addresses assigned by the DHCPv6 server can be used for DNS lookups directly from that server.

There are arguments for and against each of these. See, for example, SLAAC and DHCPv6 or IPv6 address assignment – stateless, stateful, DHCP… oh my . I'm not going to buy into these arguments!

There is a further hiccup in this, to do with SLAAC EUI64 addressing. Wherever you are, EUI64 will generate the same address component. If you are a mobile device, that will give you the same address component on each network you visit. Potentially this could allow your device to be tracked, reducing privacy.

This is addressed by RFC7217 with the cumbersome title "A Method for Generating Semantically Opaque Interface Identifiers with IPv6 Stateless Address Autoconfiguration (SLAAC)". What it does is to ensure that on each network it has a stable GUA, but on different networks it has a different GUA with a different node component. This has recently been adopted by the Linux NetworkManager, so on recent Linux systems you may see GUAs that are not related to the MAC address. This is a different mechanism to the temporary addresses of RFC4941, to address a different use case.

Am I IPv6 enabled?

The web site Test your IPv6 connectivity will perform a set of tests on your browser to check whether you are now on the internet using IPv6. It gives good instructions, and hopefully you will get to see an image as in Figure 1.

Testing IPv6 connectivity
Testing IPv6 connectivity
You can also install an extension/addon IPvFoo for Chromium or IPvFoo for Firefox which for any web page gives an indication as to whether it has connected via IPv4 or IPv6 (a '4' or '6' in the extensions bar)

Who is on my network?

Fnding out what hosts are on your IPv4 network is easy. Say it is a network, then this command will list them

	  nmap -sP
That is quick because nmap only has to scan 28 (256) addresses. But it won't work for IPv6 when you have to scan 264 possible addresses - a simple coffee break won't be long enough to scan 18,446,744,073,709,551,616 addresses!

Instead, the best way is to send out a multicast request that hosts should understand and respond to. Packets sent to the multicast address ff02::1 are received by all nodes on the local network segment. Depending on the message, they may respond. The ICMP6 (ping6) messages can ask for various things (as described in RFC4861) and I will look at some of those messages types (router discovery for example) in the next part of this series.

For now, one type is Neighbour Solicitation, which asks for the link layer addresses of neighbours. They respond with Neighbour Advertisements. In other words, ping to all neighbours.

Ping produces many responses, each having a sequence number, timestamp, etc. Throw the 'noise' away and collect just the link local addresses found on interface wlp2s0 by

	  ping6 -I wlp2s0 -c 10  ff02::1 | awk '{print $4}' | sort | uniq
(replace wlp2s0 by your interface). You will get output such as


Another way of discovering local nodes is to use the network discovery cache. This replaces ARP (address resolution protocol) and is based on the node advertisements on ff02::1. It can be seen by

	  ip -6 neigh
It can produce output of a set of link local and GUA addresses like

2400:3740:200:d900::1 dev wlp2s0 lladdr 38:4b:72:f0:26:c3 router STALE
fe80::c8a3:2491:1c9c:adf9 dev wlp2s0 lladdr 44:1e:a1:3b:75:31 STALE

There is also an option to nmap:

	  sudo nmap -6 --script=targets-ipv6-multicast-echo.nse
This also will take results from a cache as in

Starting Nmap 7.60 ( https://nmap.org ) at 2019-03-09 12:41 AEDT
WARNING: No targets were specified, so 0 hosts scanned.
Pre-scan script results:
| targets-ipv6-multicast-echo: 
|   IP: fe80::c8a3:2491:1c9c:adf9               MAC: 44:1e:a1:3b:75:31  IFACE: wlp2s0
|   IP: 2400:3740:200:d900::1                   MAC: 38:4b:72:f0:26:c3  IFACE: wlp2s0

Finally, I will mention v6disc.sh which combines many of these methods. In normal use it returns the GUAs of the nodes on the network:

$bash v6disc.sh
-- Searching for interface(s) 
-- Found interface(s):  wlp2s0 
-- Detecting hosts on wlp2s0 link 
-- Discovered hosts for prefix: 2400:3740:200:d900 on wlp2s0 
2400:3740:200:d900::1                    38:4b:72:f0:26:c3    
2400:3740:200:d900:a56f:9aa2:63e1:6602   d0:7e:35:6b:fd:9b    IntelCor
-- Displaying avahi discovered hosts 
2400:3740:200:d900:6079:65fd:7e90:d4bf   netbook-3.local
while v6disc.sh -L shows the link local addresses:

$bash v6disc.sh -L
-- Searching for interface(s) 
-- Found interface(s):  wlp2s0 
-- Detecting hosts on wlp2s0 link 
-- Discovered hosts for prefix: fe80: on wlp2s0 
fe80::224:21ff:fe43:4aed%wlp2s0          d0:7e:35:6b:fd:9b    IntelCor
fe80::3a4b:72ff:fef0:26c3%wlp2s0         d0:7e:35:6b:fd:9b    IntelCor
although it doesn't get the MAC address or manaufacturer correct.

vdisc.sh uses additional techniques such as malformed messages to get Windows computers to respond, using the techniques described in RFC7707.

One oddity that you might notice is that there may be missing GUAs: you may be seeing one of the privacy preserving addresses in the cache and not the permanent address.

No NAT for IPv6

I run my own web server as well as ssh and UPnP servers. The web server is exposed to the internet by NAT'ing the IPv4 address out through my router's IPv4 address. Many of us have been doing this for years, both manually and by using programs that do it for us.

NAT is gone in IPv6. Well, it's still there in one form, but you aren't supposed to be using that.

So what do we have in its place? That's easy: IPv6 global addresses. As a result of the ISP enabling IPv6 to my router and handing it an IPv6 prefix, my router is able to give prefix information to the nodes in my network, using router advertisements. The individual nodes then assign themselves one (or more) global IPv6 addresses, which gives them unique addresses in the internet. So my web server has a GUA, my ssh server has a GUA, but also my laptops, PCs, phones, tablets and everything else now have IPv6 GUA's.

Does that mean anyone can now access all of the nodes in my network? No: you have to distinguish between addressability and accessibility. The nodes are all addressable, but if your router is any good it will have set up a firewall, blocking accessibility.

The equivalent to setting up a NAT mechanism is done by opening up the firewall to an interface address on a port. On my Linksys router this is done under the Security tab, see Figure 2.

Enabling access to web server through the firewall
Enabling access to web server through the firewall

There is one significant difference in appearance of my services on the internet: under IPv4 the address of a service was the single IPv4 address of my router. Under IPv6 the address of a service is its global IPv6 address, and each separate host in my network will have a separate IPv6 address.

It also means my router has its own internal and external GUAs. When I'm running an HTTP server on a different host using NAT, I can't access the HTTP server on my router externally via IPv4, as it goes through to my NAT'ed server. Now I can using IPv6, because they have different GUAs. I'm not sure if I want to access it that way, but it definitely means I can't leave the default router login as admin/admin - DUH!

I use an external DNS provider Zoneedit for my domain jan.newmarch.name. Adding IPv6 also has implications for any external DNS lookups: a single DNS entry for the IPv4 router allows access to multiple IPv4 servers, but each IPv6 host would require its own DNS entry. That isn't a bad idea anyway, with separate DNS entries for www.jan.newmarch.name, ssh.jan.newmarch.name (this one doesn't actually exist :-) and so on. So I had to update the DNS entries to include the right IPv6 as well as IPv4 entries: router address for NAT IPv4 and web server GUA for IPv6.


This article has discussed adding IPv6 addressing to an existing home router, what the addresses look like, how to find IPv6 addresses of nodes on the network and how to make IPv6 addresses externally visible. The next part of this series will be on how to build your own router for both IPv4 and IPv6 using OpenWrt so that you get more control and visiblity over what your network is doing.