If you have ever tried to use jumbo packets, or trace a weird slowness on the network – one of the things that frequently comes up is packet fragmentation. This is basically where a source machine is sending bigger packets than can be consumed along its pathway to a destination machine. This means the packets will need to be split up. This causes a host of performance issues.
So how do you diagnose this? Well Ping is your friend. It allows you to flag packets to not be fragmented and specify a minimum and maximum packet size. The example below sends a 1460 byte do not fragment packet from the host to example.com:
$ ping -M do -s 1460 example.com
PING example.com (93.184.216.34) 1460(1488) bytes of data.
1468 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=1 ttl=45 time=223 ms
1468 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=2 ttl=45 time=223 ms 1468 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=3 ttl=45 time=223 ms
Taking the example above and running on a Macbook/OSX:
$ ping -D -s 1460 example.com
PING example.com (93.184.216.34): 1460 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
Request timeout for icmp_seq 2
Request timeout for icmp_seq 3
Request timeout for icmp_seq 4
The maximum packet size over the internet is 1500 bytes. So 1490 should be fine, right?
$ ping -M do -s 1490 example.com
PING example.com (93.184.216.34) 1490(1518) bytes of data.
ping: local error: Message too long, mtu=1500 ping: local error: Message too long, mtu=1500
The same test on Macbook/OSX:
$ ping -D -s 1490 example.com
PING example.com (93.184.216.34): 1460 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
Request timeout for icmp_seq 2
Request timeout for icmp_seq 3
Request timeout for icmp_seq 4
As you can see, this breaks beneath the expected 1500 byte packet size. Running “ping -M do -s 1490 example.com” says that the ICMP data size is 1490 bytes and fragmentation is not allowed. But remember the size of ICMP data, ICMP size (i.e., header + data) will be 1498 bytes. Next you need to add the IP header and so the new frame size becomes 1518 bytes. The frame size can’t exceed MTU size of the interface and you can see this in the error message (MTU for the interface is 1500 bytes). Without fragmentation, this message can’t be sent. Since fragmentation is not allowed, ping fails saying message is too long.
Ok, so what if I do this?
$ ping -M want -s 1490 example.com
PING example.com (93.184.216.34) 1490(1518) bytes of data.
1498 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=1 ttl=45 time=223 ms
1498 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=2 ttl=45 time=223 ms
1498 bytes from 93.184.216.34 (93.184.216.34): icmp_seq=3 ttl=45 time=223 ms
Ok, why did this work? Well -M want will allow local fragmentation.