This article serves as a quick introduction for those who know their way around IPv4 but know nothing of IPv6.
Let’s take a look at an IPv4 address:
We have 4 groups of each 8 bits, for a total of 32 bits. This gives us 232 possibilities, 4 294 967 296 to be exact. Every IP address has a network part and a host part. The subnetmask determines which part is the network part and which is the host part.
For example, 220.127.116.11 with subnetmask 255.255.0.0 means 192.0 is the network part and 43.10 the host part.
If you want to communicate with networks where the 192.0 part differs, you need a router.
Today we use the CIDR notation for our subnetmasks, for example /24. The 24 says how many bits are set to 1 in the subnetmask.
/24 = 11 11 11 11 . 11 11 11 11 . 11 11 11 11 . 00 00 00 00 = 255.255.255.0 = the first three groups are the network part.
Now, 4 billion sounds plentiful, in practice a lot less are usable:
- Per subnet we lose two addresses to the network address itself and the broadcast address. If we take the default gateway into account we lose 3 (losing as in, cannot be assigned to a host).
- Three ranges are reserved for private use (these are not routed on the internet): 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16
- Some special ranges like multicast (240.0.0.0/4) cannot be used to connect devices
- Waste by assigning big blocks to organizations who don’t need them
In short, the IPv4 addressing scheme doesn’t suffice anymore. As more and more equipment gets connected to the internet (think mobile phones, interactive services such as digital television, general increase in internet usage, etc…) the number of available addresses is sinking rapidly. Not “oh we can manage”, but Titanic scale sinking. IANA, who distributes the entire IP space to the independent RIR’s, handed out the last usable /8 blocks in February 2011. In other words: we’re out. Game over.
Postponement of the inevitable
The shortage of IP addresses was predicted long beforehand, that’s why technologies were developed to make better use of the already scarce address space. Where we used classful addressing before, we implemented CIDR, which makes classless addressing possible. Hence the name, Classless Inter-Domain Routing.
Another technique, more prominent, is the application of NAT, Network Address Translation. NAT makes it possible to have multiple nodes, each with their own private IP address, to share one public IP address. That is how most computer networks are organized these days.
One of the biggest changes of IPv6 compared to the IPv4 is obviously the length of the addresses. Where we had 32 bits before, we now have 128. These 128 bits are usually displayed as 8 groups of 16 bits.
128 bits = 2128 = 3,4 x 1038 = unspeakable = enough to give every grain of sand on earth an IP address.
So, we said they are displayed in 8 groups of each 16 bits. We write them hexadecimal. This is an example of a valid IPv6 address:
Notice the groups are separated by colons!
Fact 1: IPv6: 128 bits, divided in 8 groups of each 16 bits, displayed hexadecimal with colon as delimiter.
IPv6 has a short notation as well. We do this by replacing the 0’s in the address by 2 colons.
we can write this as
Note that you can only shorten the 0’s at one point in the address. How else would you know how many zero’s to use and where? The following example is WRONG:
2002::76cd:21::1234 -> Where do we put how much zero’s? You don’t know, so the computer definitely doesn’t know! The address we wrote down has become ambiguous. That’s something computers really don’t like.
Fact 2: IPv6 addresses can be shortened by replacing 0’s with double colons, but only if the entire address remains unambiguous.
Subnetting basically works in the same way as IPv4. With the difference there are now 128 bits for the subnetmask and they are always shown in CIDR fashion.
For example: /64: one half is the network address, the other half is the host address.
ARP doesn’t exist anymore
ARP has disappeared with IPv6. Everything has been replaced with the Neighbor Discovery Protocol, NDP. If you are running Windows you can see the discovered neighbours with
netsh interface ipv6 show neighbors
With Cisco IOS:
show ipv6 neighbors
You can filter ARP on your network, IPv6 will continue to work, as it is not dependent on ARP. The NDP protocol is the most important protocol of IPv6, it basically makes the whole system work.
Fact 3: ARP is no more, Neighbour Discovery Protocol has replaced it.
The link-local address
Every network interface, when its being initialized for IPv6, gets a “link-local” address. This address is meant for communication within the bounds of the local network. Routers do not forward packets that have link-local addresses. Link-local addresses are somewhat resemblant of the IPv4 APIPA (Automatic Private IP Addressing). This link-local address is needed for other protocols (for example, NDP).
The range reserved for link-local addresses is:
This means from fe80:: up to and including febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff.
The operating system will automatically assign the host part based on the MAC address of the adaptor*. This kind of address is NOT the same as private IP addresses in IPv4 although it can be used to communicate with other hosts within the scope of the link (ie, everything that’s reachable at layer 2).
Fact 4: Every network interface gets a link-local address.
* Note: using the MAC address is just one of the ways the operating system may generate the host part. An OS may purposely (to hide the MAC address) use another source of randomness.
Private addresses & NAT
Private addresses still exist, they are called ULA’s: Unique Local Addresses. These are not routed on the internet.
The address range reserved for ULA is:
However, IPv6 was designed so that every computer should get a “Global” IP address, which is the equivalent of an IPv4 public address. This means NAT is history. Although NAT can still be used, it is the opinion of this author we might as well go back to living in caves if you decide to do so.
Erase the idea of NAT, it simply does not apply anymore. Every node gets a globally unique IPv6 address that is directly addressable and routable without further ado.
Fact 5: Unique Local Addresses is the new private address range
Recommendation: no more private addresses, no more NAT. Every computer gets a global address.
Wait just a minute! What about these link-local addresses?
These are ONLY meant to make the Neighbour Discovery Protocol work. You do not, in any case, assign these yourself. If you assign this kind of address to an interface to debug a connectivity problem, you’re doing it wrong.
Two types of addresses: link-local and global
So by now we know of two address types:
- Link-local: every interface gets them automatically, calculated based on MAC address, within the fe80::/10 subnet.
- Global: a global address is a public, via internet accessible, IP addresses. Every computer should get one to participate in a network.
What’s the percent sign in the link-local address?
If you’ve run the ipconfig command before, you might have noticed the following:
There’s a “%” sign and a number behind your link-local address. This is the zone index. It is used to add extra routing information, in the case of link-local addresses it is used to indicate which interface we’re talking about.
Why do we need a zone index? Every interface gets a link-local address, but these are all within the same subnet, fe80::/10. By using the zone index, we can distinguish them.
With most UNIX operating systems the name of the interface is appended, for example:
Windows just uses an incrementing number. As you add more interfaces to your system, they will get a higher and higher number each time one is added. Different interfaces will have different zone indexes.
Fact 6: link-local addresses need a zone index to distinguish different network interfaces.
Hint: if you want to use link-local addresses to communicate with other nodes, you’ll need to use this zone index and know how the two are physically connected. Let’s say you have two network adapters in your computer, NIC1 & NIC2. NIC1 gets a zone index of 14 and NIC2 gets a zone index of 17. If you want to ping a device using its link-local (for example, fe80::806b:6ed0:448a:a990) address connected to NIC2, you’ll need to use
If it was connected to NIC1, you’d use
Obviously you’ll need to use this zone index in other programs as well when using link-local addresses, not just ping.
Multicast replaces broadcast
Broadcast addresses do not exist anymore. Everything is now based on multicast and anycast. There’s a multicast address for nodes with a link-local addresses:
There’s a special one for routers as well:
NDP uses multicast.
The multicast address range is ff00::/8
Fact 7: Broadcast is replaced by multicast
The subnetting system hasn’t really changed technically, subnets are created just the same as with IPv4. However, there is one important rule you should obey:
The smallest LAN subnet is a /64. Which means, one half of the address, is the network address, the other half is the host address.
Note that it’s technically still possible to create smaller subnets, but those are not compatible with Stateless Address Auto Configuration (which we’ll cover a bit later). If you want to create smaller subnets, you’ll have to use DHCPv6.
Fact 8: the smallest LAN subnet is a /64 (for SLAAC)
Aside from that we have ::/0. This range is used for ::1, which is the IPv6 loopback address. ::1 is for IPv6 what 127.0.0.1 is for IPv4.
Fact 9: ::1 is IPv6’s loopback address
In IPv6 terminology, when we assign IPv6 addresses, we talk about prefixes. Prefixes are a combination of a IPv6 prefix (an address) and a prefix length. We write them like this:
As you can see, this is the same as an IPv4 network address combined with the CIDR style notation of the subnetmask. Prefixes replaces the network addresses as we know from IPv4.
A simple formula:
48 (subnetbits that are 1) / 16 (how many bits per group) = 3. This means, the first three groups determine the network part, the others the host part.
The situation in the future will most likely be that your provider will give you a prefix and below this prefix you may create as much subnets as you want. Popular right now are /48 and /56 prefixes. As the regular LAN subnets are /64, you either have, depending on the prefix you got, room to create your own subnets:
If your provider gives you a /48, you have an entire group to play with:
2001:6f8:1418: 1234 :baf1:85ab:ef9:1 /48 /64
A /48 means you have 16 bits you can subnet with. That’s 65 536 networks.
If you only got a /56, you have one half of a group to play with. 8 bits mean 256 networks.
Fact 10: addresses are assigned based on a prefix.
Stateless Address Auto Configuration (SLAAC)
New in IPv6 is Stateless Address Auto Configuration. Stateless means there’s no mechanism that keeps state of a node (like DHCP in IPv4). You’ve already seen Stateless Auto Configuration in action with the link-local addresses. SLAAC allows a client to configure their addresses themselves, without requiring a DHCP server.
But how do you get a global address and set the default gateway, so you can reach other networks and thus the internet?
This is done by means of router advertisements. It’s part of the Neighbor Discovery Protocol. A Router Advertisement (RA) contains a prefix a node may use. When a node receives a prefix they may use from the router advertisements (a /64 prefix), the node derives the host part of the address using the MAC address of the interface.
The result is you get an address where the first part (the network part) is the prefix and the second half (the host part) is the auto configured address based on the MAC address.
Example 1: SLAAC
We know quite a bit know about IPv6. Let’s start with a simple example. One laptop will connect to a Cisco 2821 router.
- The Cisco’s IP address is 9a9b:1234::1/64 on the GigabitEthernet 0/0 interface.
- The laptop is directly connected to GigabitEthernet 0/0.
- We will send out a Route Advertisement (RA) for the 9a8b:1234::/64 prefix, allowing stateless auto configuration.
The end result is that the laptop automatically assigns itself an address with the 9a8b:1234::/64 prefix.
Let’s start by enabling IPv6 unicast routing:
Router(config)#ipv6 unicast-routing Router(config)#
Now configure the g0/0 interface:
Router(config)#interface GigabitEthernet 0/0 Router(config-if)#ipv6 address 9a8b:1234::1/64 Router(config-if)#no shutdown Router(config-if)#exit Router(config)#
Verify operation with:
Router#show ipv6 interface GigabitEthernet 0/0 GigabitEthernet0/0 is up, line protocol is up IPv6 is enabled, link-local address is FE80::217:E0FF:FE56:1F58 No Virtual link-local address(es): Global unicast address(es): 9A8B:1234::1, subnet is 9A8B:1234::/64 Joined group address(es): FF02::1 FF02::2 FF02::1:FF00:1 FF02::1:FF56:1F58 MTU is 1500 bytes ICMP error messages limited to one every 100 milliseconds ICMP redirects are enabled ICMP unreachables are sent ND DAD is enabled, number of DAD attempts: 1 ND reachable time is 30000 milliseconds (using 30000) ND advertised reachable time is 0 (unspecified) ND advertised retransmit interval is 0 (unspecified) ND router advertisements are sent every 200 seconds ND router advertisements live for 1800 seconds ND advertised default router preference is Medium Hosts use stateless autoconfig for addresses. Router#
By now the router is already sending out RA’s, but only doing so every 200 seconds. That means, in the worst case, it may take up to 200 seconds for any client to receive an RA and configure itself. We’re going to modify this interval to send an RA every 10 seconds:
Router(config)# Router(config)#interface GigabitEthernet 0/0 Router(config-if)#ipv6 nd ra interval 10 Router(config-if)#exit Router(config)#
Router#show ipv6 interface GigabitEthernet 0/0 GigabitEthernet0/0 is up, line protocol is up IPv6 is enabled, link-local address is FE80::217:E0FF:FE56:1F58 No Virtual link-local address(es): Global unicast address(es): 9A8B:1234::1, subnet is 9A8B:1234::/64 Joined group address(es): FF02::1 FF02::2 FF02::1:FF00:1 FF02::1:FF56:1F58 MTU is 1500 bytes ICMP error messages limited to one every 100 milliseconds ICMP redirects are enabled ICMP unreachables are sent ND DAD is enabled, number of DAD attempts: 1 ND reachable time is 30000 milliseconds (using 30000) ND advertised reachable time is 0 (unspecified) ND advertised retransmit interval is 0 (unspecified) ND router advertisements are sent every 10 seconds ND router advertisements live for 1800 seconds ND advertised default router preference is Medium Hosts use stateless autoconfig for addresses. Router#
Let’s turn back to our client and see if our client already has an IPv6 address:
Hooray! We can see that the laptop picked up the RA and configured itself accordingly. Our 9a8b:1234::/64 prefix is being used because Windows automatically assigned our computer an address that begins with 9a8b:1234::. Note that the default gateway has been set to the link-local address of the router and includes the zone index.
Now let’s have a closer to look at an RA:
Here we can clearly see the router advertising our prefix and any prefix lengths that are of interest. The packet was sent to a multicast address (ff02::01) and the source address is the link-local address of our router.
The RA also contains a number of timers such as router lifetime and a valid lifetime for the prefix. This means if, for example, the valid lifetime of the prefix is 60 seconds and no RA with that prefix has been received for 61 seconds, the nodes will remove any addresses it assigned to itself based on that prefix.
Managed address configuration/other stateful configuration
In an RA, we can specify two flags called managed address configuration and other stateful configuration. This influences how the client configures itself.
- Managed address: client should not use auto configuration but instead try DHCPv6. The default gateway still gets set to the node where the router advertisements are received from. This way the client’s behavior is the same as IPv4, except for the gateway bit.
- Other stateful configuration: use auto configuration, but try to get other parameters such as DNS servers via DHCPv6.
If we want our network nodes to use a managed address, or get other stateful configuration, from a DHCPv6 server, we need to explicitly say so in our route advertisements. RA’s don’t have room for DNS server information, leaving our clients dead in the water when trying to resolve hostnames. Thus, you will most likely use any of the two flags discussed.
We’ll work this out in example 2, where we use the other stateful configuration flag and a DHCPv6 server to provision our clients with DNS server addresses.
Example 2: SLAAC with other stateful configuration
Let’s resume our previous example, example 1. We already have a working IPv6 network, but now we want to expand the provision of our clients to include IPv6 DNS servers. As clients are useless without name resolving, this will be most applicable.
- DONE The Cisco’s IP address is 9a9b:1234::1/64 on the GigabitEthernet 0/0 interface.
- DONE The laptop is directly connected to GigabitEthernet 0/0.
- DONE We will send out a Route Advertisement (RA) for the 9a8b:1234::/64 prefix, allowing stateless auto configuration.
- Our RA’s have the Other Configuration flag set
- The Cisco router will act as a DHCPv6 server
- The laptop will receive 2001:4860:4860::8888 and 2001:4860:4860::8844 as DNS servers
Create the DHCPv6 scope. Creating a DHCPv6 scope is basically the same how you do it for IPv4:
Router(config)#ipv6 dhcp pool MyLocalIPv6net Router(config-dhcpv6)#dns-server 2001:4860:4860::8888 Router(config-dhcpv6)#dns-server 2001:4860:4860::8844 Router(config-dhcpv6)#link-address 9a8b:1234::/64 Router(config-dhcpv6)#exit Router(config)#
- The usage of link-address. This tells the router that this DHCP pool should respond to requests matching the address 9a8b:1234::/64, which is our local subnet we created for our clients.
- We did not specify any network addresses to be handed out, as the clients will configure themselves using SLAAC.
Next we enable the other configuration flag and allow DHCP server operation on the interface:
Router(config)#interface GigabitEthernet 0/0 Router(config-if)#ipv6 nd other-config-flag Router(config-if)#ipv6 dhcp server automatic Router(config-if)#exit Router(config)#
Router#show ipv6 dhcp pool DHCPv6 pool: MyLocalIPv6net Link-address prefix: 9A8B:1234::/64 DNS server: 2001:4860:4860::8888 DNS server: 2001:4860:4860::8844 Active clients: 0 Router#show ipv6 interface GigabitEthernet 0/0 GigabitEthernet0/0 is up, line protocol is up IPv6 is enabled, link-local address is FE80::217:E0FF:FE56:1F58 No Virtual link-local address(es): Global unicast address(es): 9A8B:1234::1, subnet is 9A8B:1234::/64 Joined group address(es): FF02::1 FF02::2 FF02::1:2 FF02::1:FF00:1 FF02::1:FF56:1F58 FF05::1:3 MTU is 1500 bytes ICMP error messages limited to one every 100 milliseconds ICMP redirects are enabled ICMP unreachables are sent ND DAD is enabled, number of DAD attempts: 1 ND reachable time is 30000 milliseconds (using 30000) ND advertised reachable time is 0 (unspecified) ND advertised retransmit interval is 0 (unspecified) ND router advertisements are sent every 10 seconds ND router advertisements live for 1800 seconds ND advertised default router preference is Medium Hosts use stateless autoconfig for addresses. Hosts use DHCP to obtain other configuration. Router#
And check our client with
Success! Windows 7 is using the DNS servers we configured in the pool.
Privacy extensions – what’s that temporary IPv6 address?
By now you might have noticed your network interface got 2 global IP addresses when using Stateless Address Auto Configuration. One is “IPv6 Address” and the other is “Temporary IPv6 Address”.
That has to do with the IPv6 privacy extensions that are enabled by default on Windows 7. Normally, Windows will always configure the same host part of the IP address when using Stateless Address Auto Configuration. This effectively allows IPv6 nodes, and in turn, people, to be tracked where they are. To solve this, Windows automatically assigns itself a temporary IPv6 address, and uses that one as source address when making a connection to another node. The default setting for Windows is to create a new temporary IPv6 address every 24 hours.
NAT gave me security – now it’s gone!
One “advantage” to NAT is that, by default, “assumably” incoming connections from the internet are impossible. However, by some clever routing tricks (which are normally blocked by providers), I can reach your private network using your router, gaining access to your internal computers.
But yes, with IPv6 this appearance of security, disappears. That’s why firewalls will become a lot more important. It’s up to a good system administrator to throw out all the garbage IPv6 traffic and strictly allow what’s necessary. The least-privilege principal is definitely a good starting point.
What about site-local addresses?
Yes, there was such a thing as site-local addresses, intended to replace the private IP ranges from IPv4. This deprecated however and site-local addresses should not be used. The range reserved for this type of address was fec0::/10.
Windows automatically gets fec0:0:0:ffff:: DNS servers?
That is part of the old site-local addresses standard which has been deprecated. But Windows still uses these when it doesn’t find any other way to configure DNS servers. How you can make your clients use specific DNS servers is explained in example 2. If Windows fails to retrieve the other configuration needed from the DHCP server (because it’s down or there’s an error in the configuration of it) or no managed configuration flag or other configuration flag is set, Windows will use the fec0 DNS servers it’s programmed to do.
If there’s no DNS server at those fec0 addresses, Windows will fail to resolve hostnames.
For completeness, these are the DNS addresses Windows will use:
What happens when a computer is connected to both an IPv4 and an IPv6 network?
That situation is called dual stack. If you connect to a hostname that has an IPv6 address (AAAA record) and the operating system has determined that the IPv6 stack is in a usable state, it will try and connect using IPv6. If you connect to a hostname that doesn’t have an IPv6 address record, it will just use IPv4. That’s why since Windows Vista you see two DNS queries when connecting to a hostname, one for AAAA records and one for A records. The general rule of thumb is: if it’s reachable via IPv6, use IPv6, otherwise fall back to IPv4.
This can create problems with wrongly configured IPv6 networks: the operating system has determined that its IPv6 stack is usable when in fact it’s not, by, for example, a wrongly configured router sending out RA’s. Result: the user will experience connectivity issues. Dead tunnels caused by IPv4 to IPv6 transition techniques is another example.