IPv6 router

As I’ve mentioned before, I switched my home ISP to A&A so that I could get IPv6 on my internet connection. That gave me 2 pieces of the puzzle (OS support and internet connection), but I still needed to sort out my network infrastructure, specifically my router. This post says what I’m trying to achieve, and it would apply to any router, regardless of the hardware/software involved. I’ll save the details of how I actually went about it for other posts, which are specific to the particular equipment.

On the client side, this should all be invisible. Someone should be able to turn up with a suitable device (e.g. an iPad or a laptop running Windows) and automatically get IPv6 internet access without having to do anything extra. They may have to type in the key for the wireless network, but that’s the same for IPv4 and IPv6. Similarly, they shouldn’t notice whether they’re accessing a particular site (e.g. Facebook) over IPv4 or IPv6; the only visible difference should be that IPv6-only sites (e.g. Loops of Zen) are now available, whereas they weren’t before. I’ve bought an iPad app to help me with my testing (IPv6 Toolkit) but that’s just a diagnostic tool and you don’t need it to actually use IPv6. In fact, as of IOS 9, it’s a requirement for all iPad apps to support IPv6.

On the router side, I want feature parity between IPv4 and IPv6 (where it makes sense). For instance, NAT (Network Address Translation) is a necessary evil in IPv4 and I’ll be glad to see the back of it, so I don’t want an IPv6 equivalent (NAT66). However, if a router says that it supports IPv6 and PPPoE then I expect it to support IPv6 over PPPoE. I also expect to be able to ping IPv6 addresses; I’d prefer to use the same command (ping) for both IPv4 and IPv6, but I don’t mind if I have to use separate commands (e.g. ping6 in Red Hat Enterprise Linux 5) as long as the functionality is built in.

I would like to have some kind of firewall built into the router (e.g. ip6tables), but that’s not essential; if necessary, I’m willing to use a separate device for that.

When I set up a router for an IPv4 xDSL (ADSL/VDSL) internet connection, I don’t have to type in the public IPv4 address: that comes from the ISP. In a similar way, I would like an IPv6 router to pick up the equivalent IPv6 address range automatically. However, if I have to type in the router’s IPv6 address manually then I can live with that; this is just a one-off job until I change my internet connection, rather than something I’d have to do on a daily basis.

Just to recap the basics of IPv6, every address is 128 bits long (as opposed to 32 bits for IPv4) and written in hexadecimal. The first 64 bits identify the network/subnet, and the next 64 bits identify the machine within that network. My ISP actually allocated me a couple of IPv6 address ranges: they reserved a /48 prefix and routed a /64 prefix to my phone line. So, the /48 prefix means that I have 16 bits left in the network address, and I can have 216 = 65,536 subnets here. The /64 prefix represents one of those possible subnets, which is simply intended as a starting point. On a simple network, that /64 prefix is all you need; if you have multiple subnets (e.g. wired vs. wireless) then you can have a separate /64 for each of them, all from the same /48.

There are 3 types of unicast IPv6 address:

  • Link-local (equivalent to APIPA in IPv4, i.e. 169.254.x.x). These all begin with fe80.
  • Unique local (equivalent to a private address in IPv4, e.g. 192.168.x.x). These all begin with fd.
  • Global unique (equivalent to a public address in IPv4). These all begin with 2 or 3.

Any computer which supports IPv6 will automatically generate a link-local address. You can use this to ping other machines on the same network, but you can’t use it outside your subnet; in particular, you can’t use it for internet access.

The address ranges from my ISP are global unique. Unlike IPv4, there’s no need to use NAT, so every machine can and should have a globally unique address. This isn’t a security risk, because you need a firewall whether you’re using IPv4 or IPv6. The key advantage is that routers can pass packets around without having to replace addresses; that means that they don’t need to understand the higher level protocols (e.g. “the sequence of 1s and 0s starting at bit 100 is an IPv4 address”).

With IPv4, the router would typically have a public IP address on the internet side and a private IP address on the LAN side.


With IPv6, the router only has a link local address on the internet side. On the LAN side, every device has a link local address and a global unique address. The router will advertise the global unique (/64) prefix to the rest of the LAN, but they will use the router’s link local address as the default gateway.


NB If you’re using an Ethernet line to the ISP (formerly known as a leased line) then you’d have a separate interlink subnet for that. However, I’m ignoring that for now, so that I can focus on xDSL lines.

When you set up the IPv6 routing table on your router, it will need a default route. You can’t use the ISP’s link-local address as your next hop address, because they probably won’t tell you what it is, and even if you did know it might change (e.g. if they replace the equipment at their end). So, you need to be able to specify an interface instead, i.e. “send any other IPv6 traffic down the DSL line for the ISP to sort out”.

Now, suppose that you switch ISP and your global address range changes. If any of your devices (e.g. servers) have static addresses, it would be a hassle to go through and update them all, and if there’s a gradual change then they won’t be able to talk to each other. This is where unique local addresses come in handy: you can set up your internal infrastructure that way (e.g. DNS records on a local server), and it won’t matter if the global unique addresses change. Link-local addresses are never registered in DNS. You can use unique local addresses across subnets (e.g. for wired and wireless machines to connect), whereas you can’t do that with link-local addresses. Also, you can use unique local addresses if you want to set up IPv6 on your own network before your ISP offers IPv6 internet access.

You need a /64 prefix for unique local addresses, and this won’t come from your ISP; you have to choose it yourself. The first 2 hex digits will always be “fd”, then the next 10 digits come from the global ID. That’s 12 digits in total, i.e. the first 3 groups of 4 digits, representing a /48 prefix. The 4th group is the subnet, which creates a /64 prefix. Here are a few websites which randomly generate a global ID for you (based on RFC 4193):

Each website also suggests a subnet ID for you, but you can choose anything you like; I think it makes sense to use the same subnet ID for unique local and global unique addresses. RevK offered some advice on picking IPv6 addresses: “If you have many sites you probably want to split the /48 in to parts, e.g. a /56 per site allowing 256 sites, and 256 LANs per site.”

In IPv4 networks, a lot of people use the same private address range (e.g. 192.168.0.x). This is partly because they have a device (e.g. an ADSL router) which is pre-configured to act as a DHCP server on that subnet, and partly just because it seems logical to start at 0 or 1 and then work upwards. However, this can cause problems for VPN connections: if you use the same address range at home and at work, you won’t be able to access the work computers because your PC will assume that those machines are on your local network. So, it’s a good idea to pick a random subnet and reduce the risk of collision, e.g. 192.168.147.x. I’m not sure whether the same principle applies to unique local addresses, but there’s certainly no harm in randomly generating the global ID. However, I think that the subnet ID can be sequential. Assuming that you use 00 for your first site ID, that means that you’ll probably only have a single digit to identify each LAN on that site (e.g. 0 for computers and 1 for phones).

In IPv4, you either assign static addresses (and specify DNS servers manually) or you can use a DHCP server to supply that info. You can also use DHCP for other information, e.g. specifying extra routes.

In IPv6, you can use a DHCP server to give out addresses and other configuration (e.g. a list of DNS servers). However, there’s a big catch! When the client machines get an IPv6 address from DHCPv6, they don’t update their routing table. That means that they can’t ping each other, because they don’t know that the other address is on the same network segment (even though it has the same prefix). So, you must have a router for IPv6 to work, even if you have a completely isolated network.

The router will advertise one or more /64 prefixes. It can also specify a couple of options: the M and O flags. The M (Managed) flag tells clients whether they should work out their own address using SLAAC (StateLess Address AutoConfiguration) or ask a DHCPv6 server for an address (the stateful method). The O (Other Configuration) flag tells clients whether they should ask a DHCPv6 server for extra settings, e.g. a list of DNS servers. According to RFC 6106, the router could specify extra settings itself (e.g. DNS servers). However, Windows doesn’t support that, as Christopher Palmer explained here. Among other reasons, RFC 6204 includes this requirement: “WAA-3: The IPv6 CE router MUST support DHCPv6 client behavior.”

Obviously, all your client devices will need access to a DNS server so that they can convert names into IP addresses. In the average home, you can simply use the ISP’s DNS servers for this, or use the xDSL router as a DNS server and tell it to get its info from the ISP’s servers. However, if you need to look up addresses on your local network (e.g. a Windows domain) then you need to have local DNS servers. Either way, each DNS server should be able to handle A records (for IPv4 addresses) and AAAA records (for IPv6 addresses). It doesn’t matter how you connect to the server, e.g. you can retrieve AAAA records over IPv4 and you can retrieve A records over IPv6. So, you don’t need to have DNS running over IPv6, but I strongly recommend it: start as you mean to go on. (You don’t really want to be in a situation where IPv4 internet access is down and IPv6 internet access is still working, but you can’t connect to any websites because you’re still trying to use IPv4 to resolve the addresses.) In my experience, you need a DHCPv4 server to hand out IPv4 addresses for DNS servers, and you need a DHCPv6 server to hand out IPv6 addresses for DNS servers; I don’t know whether that’s intrinsic to the protocols, or just the way that people have implemented them because it makes intuitive sense.

So, in practical terms, you need to have a router advertising the network prefix(es) and a DHCPv6 server giving out other configuration options. (The DHCPv6 server could be your router or a separate device.) It’s then up to you whether you want your DHCPv6 server to give out addresses or not; personally, I prefer to use SLAAC and give static addresses to servers etc. where necessary. So, my method is to set the O flag and drop the M flag on the router.
NB These flags apply to the whole network: either all the machines ask the DHCP servers for addresses or none of them do. In IPv4, I often use DHCP reservations for servers, but that won’t work in IPv6 if you drop the M flag.

Speaking of the network prefix, the global unique prefix comes from the ISP. As I said above, it would be nice for the router to pick this up automatically via the PPPoE link and then advertise it to the rest of the network. All the other machines would then use that prefix to get a global unique address. This is called prefix delegation, or DHCPv6-PD, i.e. the ISP has to run a DHCPv6 server to give out the prefix. Personally, I agree with RevK (PPP IPV6CP vs DHCPv6): it would be better to use IPv6CP in this context (PPPoE/DSL). However, unless the IETF accept the (hypothetical) RFC and companies like Cisco actually implement it, we’re all stuck with DHCPv6 for now.

Anyway, that all covers what I want to do. Actually implementing it is another story…

Leave a Reply

Your email address will not be published. Required fields are marked *