To understand the design of the InterNiche IPv6 stack, it is useful to understand the ways in which IPv6 differs from IPv4. This discussion assumes the reader is familiar with IPv4 concepts, such as the IP address, subnets, broadcast and multicast; as well as related protocols such as ARP and ICMP.
The major factor driving the creating of a new IP standard is the lack of available addresses in IPv4. IPv4's 32 bit address theoretically yield about 4 billion unique addresses. While this may be enough to assign an address to every computer currently in existence, it will fall short when every person on earth owns several Internet-capable devices. The problem is actually more pressing than that. The entire IPv4 addresses space is already assigned, with some organizations holding large numbers of unused addresses. Most of the IPv4 address space is assigned to North American corporations, making the problem especially acute in Europe and Asia.
To solve this problem, IPv6 specified an IP header with 128 bit IP addresses, as compared to the 32 addresses used in IPv4. Like IPv4, the addresses are stored as the last two fields in the IPv6 header, source followed by destination.
In IPv4 stacks it was common practice to manipulate IP addresses by treating them as 32 bit unsigned integer values. This does not work with 128 bit IPv6 addresses. Throughout the InterNiche code, IPv6 addresses are compared and copied using the macros IP6EQ()
and IP6CPY()
, respectively. These are described in Section 13.2.
IPv6 does not have the concept of IP header options, as IPv4 does. IPv6 headers also have fewer fields than the IPv4 headers. IPv6 headers have omitted the checksum, fragment and header length fields.
A new class of headers called IP "extension" headers provides a large portion of the functionality that was performed in IPv4 by the deprecated fields and option headers. IPv6 extension headers differ from IPv4 options primarily in that extension headers are technically not part of the IPv6 header (thus no IPv6 header length field is needed). Each extension header carries a 8-bit protocol type for the header which follows - e.g. 6
for TCP, 17
for UDP, etc. Each extension header has it's own assigned 8 bit type.
The new headers exist in the IPv6 packets between the IPv6 headers and the transport layer headers. Since any number of extension headers may be inserted be software layers between the transport layer and the MAC layer, the InterNiche code for IPv6 does not depend on preallocating a limited space for the IP and MAC headers at the front of data packets. This sort of preallocation worked on IPv4 since the size of the IP header was well known, and the maximum size of a MAC header could be determined at system startup time. The potential for multiple headers to be inserted along with the IP header made this problematic for IPv6, so the InterNiche code now supports a scatter/gather mechanism (see section 10.5).
IPv6 has different requirements from it's underlying network hardware than IPv4 does. Most importantly, the PMTU (Path Maximum Transmission Unit) on each network must be at least 1280 bytes. This is more than twice the size of IPv4's 580 byte requirement.
The benefits of the larger PMTU are offset by the requirement that all IP fragmentation MUST take place in the sending host, not on the IP routers. This means the sender must determine the PMTU for his connection to any peer prior to setting packet size parameters, such as TCP MSS options, or simply default to the 1280 PMTU mentioned in the previous section.
This makes routing simpler, but does so at the expense of forcing the end nodes to choose between PMTU discovery (which adds connection setup latency and overall complexity) or the default PMTU (which hurts performance).
IPv6 supports larger datagram sizes than IPv4. Assuming large IP packets will be fragmented, "normal" IPv6 packets are limited to 64K by the 16 bit offset field in the IP fragmentation header. Even larger sizes may be supported thought the use of the "Jumbogram" option in the "Hop-by-Hop" IP extension header. Through the use of the scatter/gather design, the InterNiche IPv6 code supports these datagrams. The practical upper limit of a datagram is likely to by determined by the amount of memory space allocated in the "bigfreeq
" queue of free memory buffers.
IPv6 does not use broadcast packets. Instead, a series of multicast addresses are defined for common target groups, such as the "all nodes" multicast address, or the "all routers" address. The "all nodes" multicast address is functionally equivalent to a broadcast for IPv6 hosts.
This means that the IP multicast option is required for IPv6.
Another side effect of this design is that MAC layers are also required to support multicast. An Ethernet device cannot support IPv6 by receiving Unicast and Broadcast, since it will not receive packets multicast by adjacent nodes. For more details on dealing with the multicast requirement at the MAC layer, see section 15.2.
The various "pseudo checksum" descriptions used by TCP, ICMP, and UDP over IPv4 are all replaced in IPv6 by a single standard pseudo checksum algorithm. Since the IPv6 layer lacks an IP layer header checksum, all protocols running IPv6 are required to use this checksum method. The upper layer checksum verifies the most important fields in the IP header - length, addresses, and protocol type.
The InterNiche code provides ip6_pseudosum()
, a generic implementation of this checksum algorithm that should be suitable for all transport level protocols.
The IPv6 method of constructing the pseudo header is similar to IPv4's TCP/UDP pseudo header, however the longer IPv6 IP addresses are used. The underlying 16 bit ones complement summing algorithm is unchanged.
IPv6 usually has several IPv6 addresses per network Interface, as opposed to the single address per interface commonly used by IPv4. Addresses supported by the InterNiche code for each interface are given in the table below. The net structure has a field added for each of these.
Type | Scope | Description |
---|---|---|
Link local address | Local to MAC segment | Derived from the MAC address of the interface. |
Site local | Local to computer's site | As of early 2004, the committee is still debating the exact use for this. |
Global Unicast | Global | IPv6 equivalent of an IPv4 public IP address. |
MAC-specific multicast | Local to MAC segment | A Solicited-Node multicast address derived from the interfaces MAC address |
The leading bits of the IPv6 address indicate what type of address it is. Of interest are Link-local addresses, which begin with "1111111010
" (usually 0xFE80
), and multicast addresses, which begin with "11111111
" (0xFF
).
For a complete list of all IPv6 addresses required per interface, see section 2.8 of RFC-2373. There are several multicast addresses from this section which are not listed in the table above, however they are all contained in the interface's multicast list, and thus do not need additional fields added to the net structure.
IPv6 replaces ARP with the "Neighbor Discovery" (ND) protocol for resolving MAC addresses of Link-local IP addresses. ND "solicits" are roughly equivalent to ARP requests, and ND advertisements to ARP replies. ND may also be used to generically solicit local routers.
ND is actually a collection of ICMPv6 packet types, and thus has an IPv6 Ethernet type field; unlike ARP which had it's own Ethernet type field.