News Archive (1999-2012) | 2013-current at LinuxGizmos | Current Tech News Portal |    About   

IPv6 in Linux

Nov 3, 2008 — by LinuxDevices Staff — from the LinuxDevices Archive — 26 views

Foreword — This article discusses the advantages of IPv6, which in addition to a larger address space promises to increase standby time in devices, and improve performance in routers. It discusses IPv6 technology, as well as how IPv6 has been implemented in the Linux kernel.

The article was written by Rami Rosen, a Computer Science graduate of The Technion Israel Institute of Technology in Haifa, Israel. Rosen works as a Linux kernel programmer for a networking startup, and can be reached at [email protected]. Enjoy . . . !


IPv6 in Linux
by Rami Rosen

The purpose of this article is to discuss the basics of IPv6 implementation in Linux, and to draw a comparison between IPv6 and IPv4 implementations in Linux.

A brief history of IPv6

Working groups of the IETF (Internet Engineering Task Force) developed IPv4 in the early '70s. IPv4 played an important role in the growth of the Internet.

In the early '90s, the IETF started an effort to develop the next generation of the IP protocol. In its early days, it was named IPng (IP Next Generation). Later, it was named IPv6. The IPv6 protocol standards are being developed by the IPv6 working group in the IETF.

The first IPv6 specification is from 1995. Later, in 1998, it was superceded by RFC 2460. At the end of 1997, IBM's AIX 4.3 was the first commercial platform to support IPv6. Sun Solaris has had IPv6 support since Solaris 8, released in the beginning of the year 2000.

Initial support for IPv6 in Linux was started quite some time ago, in Nov. 1996, by Pedro Roque. That implementation was based on the BSD API, and was first integrated in Linux kernel 2.1.8. Most changes were done in the Network Layer (L3) in the Linux kernel.

In the following years, there were many additions. The USAGI project was a major contributor of these additions. The USAGI project was founded in 2000 in Japan. USAGI stands for “UniverSAl playGround for IPv6.” The USAGI project aimed at providing missing implementation according to the new IPv6 RFCs.

The MIPv6 Project also contributed a lot (MIPv6 is the Mobile IPv6 project, from the Helsinki University of Technology).

What IPv6 achieves

The main issue that IPv6 solves is the “shortage of addresses” problem. Instead of 232 possible address in IPv4, we have 2128 possible addresses in IPv6. This enlarges the address space significantly, probably far more than will be needed in the next few decades.

Such a large address space will eliminate NAT (network address translation) usage in many cases. This can be an advantage in many situations. For example, it makes end-to-end connectivity of VOIP and other applications simple.

Usually in IPv4, mobile devices are behind NAT. By eliminating NAT when using mobile devices in IPv6, we avoid the traffic of sending KEEP ALIVE messages, which are sent in order to keep the NAT state active. These messages are quite frequent. They are sent periodically every 40-120 seconds. NAT elimination for mobile devices in IPv6 reduces power consumption of these mobile devices, and as a consequence significantly improves their standby time. Sometimes, with mobile devices, each application may send its own keep alive messages, which only makes the problem worse.

But its extended address space is not the only advantage of IPv6, as some might think. Based on the experience gained with IPv4, many changes were made in IPv6 to improve the IP protocol. We will try to explain and focus in this article on these changes and their implementation in Linux, and we will show what is better in IPv6 in comparison to IPv4. The next sections will describe the format of IPv6 addresses, and how IPv6 is implemented in Linux, in user space, and in the kernel.

IPv6 addresses

An IPv6 address comprises eight blocks of 16 bits, which is 128 bits in total. An IPv6 address looks like this: xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx (where x is a hexadecimal digit).

Sometimes you will encounter “::” inside an IPv6 address. This is a shortcut for leading zeroes.

The localhost address in IPv6 is ::1.

In IPv4, 255.255.255.255 is the default broadcast address. The broadcast address is used in IPv4's neighboring protocol, ARP (address resolution protocol).

In IPv6, the neighboring subsystem is based on ICMPv6, instead of ARP. Instead of a broadcast address, multicast addresses are used in IPv6 for the neighboring protocol. IPv6 does not have a broadcast address at all.

IPv6's neighboring subsystem uses four new types of ICMP codes. Neighbor Solicitation and Neighbour Advertisement are analogous to ARP request and ARP reply, respectively. Router Advertisement and Router Solicitation do not have analogs in IPv4, and will be discussed shortly.

In IPv6, all addresses starting with FF are multicast addresses. The link-local multicast address (FF02::1) represents the “all-hosts” group, and fulfills the functionality of IPv4's broadcast addresses.

The user space tools for managing IPv6 addresses are the same as those for managing IPv4 addresses. Usually, you just need to add some options to specify that we are using ipv6. For example, you can set IPv6 addresses using “ifconfig eth0 inet6…” or “ip -6 addr.” Or, you can display the routing tables by “route -A inet6” or “ip -6 route show,” and so forth.

Configuring IPv6 addresses

There are two ways to dynamically configure IPv6 addresses on hosts (as opposed to a sys admin setting up a static configuration). One is statefull configuration, for example using DHCPV6 (which resembles its counterpart DHCP in IPv4). In IPv4, we have only statefull configuration.

The second way is stateless configuration. When using stateless configuration, you do not configure anything on the client. The only thing you configure is a router, which runs a stateless configuration daemon. This daemon can be, for example, RADVD or Quagga.

Next we will discuss and illustrate the operation of the RADVD daemon. Quagga can also send Router Advertisement messages and listen to Router Solicitations, but we will not discuss it in this article since it operates very much like RADVD.

RADVD

RADVD is a daemon running on routers. It enables IPv6 address stateless configuration on hosts. RADVD stands for Router Advertisement daemon. It was developed by Pekka Savola, Lars Fenneberg, Pedro Roque, and
others, and is currently maintained by Pekka Savola (see the RADVD homepage). The RADVD daemon sends Router Advertisement messages periodically. It also listens to Router Solicitations (RS) requests, and answers with Router Advertisement (RA) reply messages.

These Router Advertisement (RA) messages include a prefix field, which plays an important role in configuration of IPv6 addresses on hosts, as we will immediately see. The prefix must be 64 bits long. When a host receives the Router Advertisement (RA) message, it configures its IP address based on this prefix and its MAC address. If Privacy Extension was set (that is, if the CONFIG_IPV6_PRIVACY kernel option was set when building the kernel, which is usually the case in most recent distros, and if the corresponding sysctl was called), there is also an element of randomness added in creation of the IPv6 address. This may help if we want to make the identity of the machine hard to find (see Privacy Extensions for Stateless Address Autoconfiguration in IPv6).

The process of creating the address is not yet finished at this point. How can we be sure that there is no other same IPv6 address on this LAN? The chances are low, but in case such a duplicate address does exist, this will cause troubles. So, at this point, the address is set to be tentative, which means it can only communicate Neighboring messages. Next, a process called DAD is started.

DAD stands for Duplicate Address Detection. It uses Neighbour Solicitation and Neighbour Advertisement messages. If DAD does not find the same IPv6 address on the LAN, the state of the address is set to be permanent, and from now on it starts to communicate with all types of packets, not just Neighboring messages as before.

In case DAD does find a duplicate address, the address we tried to set is deleted (and in the syslog you see a message like this: “eth0: duplicate address detected!”). In such a case, a sysadmin needs to configure an address manually.

There is a kernel option to support Optimistic DAD
(CONFIG_IPV6_OPTIMISTIC_DAD), and a corresponding sysctl entry. This means that the address starts communicating with all types of packets, even before DAD terminates. The DAD process itself is usually very fast (it terminates in 1-2 seconds), but sometimes, due to special requirements, mostly in embedded systems, Optimistic DAD is needed.


interface eth0
{
AdvSendAdvert on;
MaxRtrAdvInterval 30;
prefix 2002:db8:0:1::/64
{
AdvOnLink on;
AdvAutonomous on;
};
};

Listing 1: radvd.conf

In listing 1, we see a basic RADVD configuration file (/etc/radvd.conf). When starting the RADVD daemon, it will send periodic Router Advertisement messages with this prefix. Hosts will configure their IPv6 addresses based on this prefix (2002:db8:0:1), and based on their MAC address. Also, usually an element of randomness will be added (unless the CONFIG_IPV6_PRIVACY kernel option was not set for the kernel).

There are two options in radvd.conf that control the lifetime of the prefix. These are AdvPreferredLifetime and AdvValidLifetime. AdvPreferredLifetime specifies the length of time in seconds that the address — which was generated from the prefix via stateless address autoconfiguration — remains in a preferred state. When preferred time is over, this address will stop communicating (will not answer ping6, etc). AdvValidLifetime specifies the length of time in seconds that the address — which was generated from this prefix — remains valid. When this time is over, the address is removed.

One of the most interesting and powerful features implemented in IPv6 is renumbering. Renumbering means replacing the current address on hosts (which is built based upon the current prefix) with a new address, based upon a new prefix, on all hosts. This may be needed, for example, when changing a provider.

RADVD can be used for renumbering IPv6 hosts easily. For achieving this goal, all you have to do is add a new prefix in radvd.conf, add AdvPreferredLifetime and AdvValidLifetime to the current prefix, and restart the RADVD daemon. First, all the hosts will gain a new address, generated from the new prefix, via stateless address configuration. Then, after the time you set elapsed, addresses that were generated with the current prefix will be removed.

You can cause the hosts to add the RADVD router as a default router by specifying a value other than 0 for the AdvDefaultLifetime field in radvd.conf. This is the lifetime associated with the default router in seconds. The maximum lifetime period can be 18.2 hours. A value of 0 indicates that the router is not to be configured as a default router on hosts. Stopping the RADVD daemon will send a Neighbour Advertisement with Router Lifetime as 0. This will cause all hosts that receive this message to delete the RADVD default router from their routing tables.

IPv6 header

The IPv6 header is much simpler than the IPv4 header. It was designed to minimize processing at intermediate routers. Knowing the IPv6 header is essential for understanding IPv6.

In IPv4, the IP header is of varying length. It can be between 20 bytes to 60 bytes. The bytes past the 20 minimum length are used for IP options.

In IPv6, the IP header has a fixed length of 40 bytes. For this reason, there is no such field specifying the IP header length (as in IPv4).

In IPv6, there is no IP options mechanism, as in IPv4. The IP options processing mechanism in IPv4 has a performance cost. Instead, IPV6 has a much more efficient mechanism of chaining extension headers. Here is a diagram of IPv6 header:


Figure 1 – IPv6 header

The designers of IPv6 decided that there will be no checksum field in the IPv6 header, as in IPv4. Avoiding checksum computing in IPv6 improves performance. Checksum is done in layers 2 and 4, and having it also in layer 3 (the network layer) is not needed. In this respect, IPv6 is implemented better than IPv4.

Consider that in IPv4, on each router that forwards a packet, the TTL (time-to-live) field of the IPv4 header is decremented by 1. This causes a re-computation of the checksum of the IPv4 header, since the checksum depends also on TTL (among other IPv4 header fields). In IPv6, there is, of course, no need for this recomputation when the TTL is decreased, since there is no checksum field at all in the IPv6 header.

The flow label field is for QoS management, but currently it is not in use. The hop limit field is by default 64. This is the parallel of the TTL field in the IPv4 header.

The IPv6 header is flexible, and extending it is simple. The Extension Headers are placed between IPv6 header and the transport header (TCP/UDP). The extension header can be one of these types:

  • Hop-by-hop options (IPPROTO_HOPOPTS)
  • Routing packet (IPPROTO_ROUTING)
  • Fragment packet (IPPROTO_FRAGMENT)
  • ICMPV6 options (IPPROTO_ICMPV6)
  • No next header (IPPROTO_NONE)
  • Destination options (IPPROTO_DSTOPTS)
  • Mobility options (IPPROTO_MH)
  • Other Protocols (TCP,UDP,…)

If a host tries to parse an extension header that it does not recognize, then an ICMP error will be sent, notifying about a parameter problem (type: ICMPV6_PARAMPROB, code: ICMPV6_UNK_NEXTHDR), and the packet will be dropped.

When we have a Hop by hop extension header, each node along the path of the packet will parse the extension header. For all other extension headers, a host will parse the extension headers of a packet only if the destination address in the IPv6 header is its address. Without going into the deep technical details, the extension headers mechanism in IPv6 takes less overhead and is more efficient than IPv4 option processing.

IPsec

IPsec is mandatory in IPv6 and is optional in IPv4. Most current modern operating systems implement IPsec both in IPv4 and in IPv6. In Linux 2.6.* kernels, IPsec is implemented both in IPv4 and in IPv6, though IPv6 implementation is more advanced.

DNS

A new DNS Resource Record was created to support IPv6. It is the “AAAA” record, and it enables a domain name to be associated with an IPv6 address. The DNS query and resolve methods were adjusted to support IPv6.

In February 2008, IANA added DNS records for the IPv6 addresses of six of the thirteen root name servers, to enable Internet hosts to communicate by IPv6.

The MLD (Multicast Listener Discovery) protocol

Multicast is used to send packets to a group of machines at the same time. Multicast is implemented in IPv4 by the IGMP protocol (Internet Group Management Protocol). In IPv6, Multicast is implemented using MLDv1 and MLDv2 (Multicast Listener Discovery) protocols. The MLDv1 protocol is based on IGMPv2, and MLDv2 is based on IGMPv3. MLDv1 and MLDv2 use ICMPv6 messages. Nodes that want to receive multicast packets that are sent to a specified group are called listeners, and they are said to “join” the group.

Multicast routing support in IPv6 was recently added to the kernel by Yoshifuji Hideaki, who is a co-maintainer of IPv6 in the Linux Kernel. This work is based on patches from Mickael Hoerdt, LSIIT Laboratory, Strasbourg, France. Multicast routing has a kernel part and a user space part, which is called PIM. IPv6 multicast routing is a wide subject, and we will not delve into its complexities in this article. We will just note that all IPv4 multicast routing features exist also in IPv6 multicast routing, and some are implemented slightly better.

Conclusion

It seems that IPv6 in Linux has reached an advanced and stable state. Moving to IPv6 will be a long process, but as a whole, Linux seems to be ready for it. We saw in this article some of the advantages of IPv6 over IPv4, such as:

  • A larger address space, which will solve:
    • IPv4 Address Exhaustion
    • NAT elimination
  • Ease of stateless configuration of IP addresses without anything to configure on hosts
  • A simple renumbering method
  • A simpler IP header (compared to IPv4 header)
  • In IPv6, fragmentation is not done by routers (as in IPv4), but only on hosts, which use PMTU discovery

There are some minor disadvantages for using IPv6 in Linux, that were not discussed in this article. For example, LVS (Linux Virtual Server) is currently not implemented in Linux IPv6 (though work on it started recently). Porting applications to IPv6 is relatively simple. But on the whole, it seems that migration to IPv6 is inevitable and has indeed significant advantages over IPv4. The migration from IPv4 to IPv6 is a long journey; along the way, we will probably encounter many networks, which consist of both IPv4-only machines, side by side with IPv6-only machines and dual-stack machines (machines using both IPv4 and IPv6 protocols); there are many tunneling techniques which will help us in such networks; however, though there will be some difficulties along the way, migration to IPv6 is needed and will improve networking significantly, in the long run. Stay tuned!


About the author — Rami Rosen is a Computer Science graduate of Technion, the Israel Institute of Technology, located in Haifa. He works as a Linux kernel programmer for a networking startup, and he can be reached at [email protected]


 
This article was originally published on LinuxDevices.com and has been donated to the open source community by QuinStreet Inc. Please visit LinuxToday.com for up-to-date news and articles about Linux and open source.



Comments are closed.