[ Team LiB ] Previous Section Next Section

22.9 IPv6 Path MTU Control

IPv6 gives applications several controls over path MTU discovery (Section 2.11). The defaults are appropriate for the vast majority of applications, but special-purpose programs may want to modify the path MTU discovery behavior. Four socket options are provided for this purpose.

Sending with Minimum MTU

When performing path MTU discovery, packets are normally fragmented using the MTU of the outgoing interface or the path MTU, whichever is smaller. IPv6 defines a minimum MTU of 1,280 bytes, which must be supported by all paths. Fragmenting to this minimum MTU wastes opportunities for sending larger packets (which is more efficient), but avoids the drawbacks of path MTU discovery (dropped packets and delay while the MTU is being discovered).

Two classes of applications may want to use the minimum MTU: those that use multicast (to avoid an implosion of ICMP "packet too big" messages) and those that perform brief transactions to lots of destinations (such as the DNS). Learning the MTU for a multicast session may not be important enough to pay the cost of receiving and processing millions of ICMP "packet too big" messages, and applications such as the DNS generally don't talk to the same server often enough to make it worthwhile to risk the cost of dropped packets.

The use of the minimum MTU is controlled with the IPV6_USE_MIN_MTU socket option. It has three defined values: -1, the default, uses the minimum MTU for multicast destinations but performs path MTU discovery to unicast destinations; 0 performs path MTU discovery to all destinations; and 1 uses the minimum MTU for all destinations.

IPV6_USE_MIN_MTU can also be sent as ancillary data. In the cmsghdr structure containing this ancillary data, the cmsg_level member will be IPPROTO_IPV6, the cmsg_type member will be IPV6_USE_MIN_MTU, and the first byte of data will be the first byte of the (4-byte) integer value.

Receiving Path MTU Change Indications

To receive change notifications in the path MTU, an application can enable the IPV6_RECVPATHMTU socket option. This flag enables the reception of the path MTU as ancillary data anytime it changes. recvmsg will return a zero-length datagram, but there will be ancillary data indicating the path MTU. In the cmsghdr structure containing this ancillary data, the cmsg_level member will be IPPROTO_IPV6, the cmsg_type member will be IPV6_PATHMTU, and the first byte of data will be the first byte of an ip6_mtuinfo structure. This structure contains the destination for which the path MTU has changed and the new path MTU value in bytes.


struct ip6_mtuinfo {
  struct sockaddr_in6 ip6m_addr;   /* destination address */
  uint32_t            ip6m_mtu;    /* path MTU in host byte order */
};

This structure is defined by including the <netinet/in.h> header.

Determining the Current Path MTU

If an application has not been keeping track with the IPV6_RECVPATHMTU option, it can determine the current path MTU of a connected socket with the IPV6_PATHMTU socket option. This is a get-only option, which returns an ip6_mtuinfo structure (see above) containing the current path MTU. If no path MTU has been determined, it returns the MTU of the outgoing interface. The value of the returned address is undefined.

Avoiding Fragmentation

By default, the IPv6 stack will fragment outgoing packets to the path MTU. An application such as traceroute may not want this automatic fragmentation, to discover the path MTU on its own. The IPV6_DONTFRAG socket option is used to turn off automatic fragmentation; a value of 0 (the default) permits automatic fragmentation, while a value of 1 turns off automatic fragmentation.

When automatic fragmentation is off, a send call providing a packet that requires fragmentation may return EMSGSIZE; however, the implementation is not required to provide this. The only way to determine whether a packet requires fragmentation is to use the IPV6_RECVPATHMTU option, which was already described.

IPV6_DONTFRAG can also be sent as ancillary data. In the cmsghdr structure containing this ancillary data, the cmsg_level member will be IPPROTO_IPV6, the cmsg_type member will be IPV6_DONTFRAG, and the first byte of data will be the first byte of the (4-byte) integer value.

    [ Team LiB ] Previous Section Next Section