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.
|