ip tcp adjust-mss VS. ip mtu
So there are those two commands available, but how do they interact?
Commands work together at the same time, checking different fields. The important parameter for the ip mtu command is the length field in the IP header, while ip tcp adjust-mss command functions as a TCP intercept for TCP packets with SYN bit set. Those SYN packets carry an important option – the MSS, or Maximum Segment Size field, that specifies what is the maximum size of separate segments. The information is relative for TCP, so the size that it controls is on L4, therefore we should keep in mind the header sizes of lower layers.
On one hand, the ip mtu command seems to be enough, but the non-intelligent nature does not provide for a good flow control. The command essentially check only output packets, and if the MTU of the packet is larger than the defined value, the packet is fragmented. If the DF field is set in the packet, the packet is discarded and ICMP message is generated, informing the source that fragmentation could not be carried out. Now, depending on the intelligence of the source and it’s ability to read ICMP messages correctly, it might resend the packet with the lower MTU. But chances are, that the source is just not that smart.
The ip mtu command works only in one direction – the output. If larger packet is received on the input, it is processed normally, and no fragmentation occurs. However this differs from platform to platform and the behavior can be altered. Of course, in this case the hardware interface capabilities are vital – i.e. if the interface cannot process packets larger than 1522 Bytes, it will never be able to receive 9000-Byte jumbo frame, no matter the settings.
Checking of mtu is not that hard for the processor, but fragmenting definetely is. And it’s kind of a waste to have such a fine protocol as TCP, and have problems with it just because of MTU. Because TCP performs MSS negotiation, before an end-to-end virtual path is established, it is a good idea to inform TCP that it should not generate packets larger than a certain size. This is the reason for ip tcp adjust-mss command. It activates TCP intercept in both directions for the specific interface, and it looks only in the SYN packets for the option communicating MSS.
Because the router looks in the both input and output directions, there is a guarantee that both sides will not negotiate larger MSS than what is desirable.
Sure, intercepting TCP, changing bits in the option, recalculating checksum (yeah, options are checksummed) is more processor intensive than just checking length of a packet, but it sure is less intensive than fragmenting. And the MSS negotiation is valid for the whole TCP session, no matter how many bystes will be transferred, potentially saving hours of CPU time by not having to fragment massive data transfers.
Note: There are several permutations of MTU commands, including mtu, ip mtu, and mpls mtu. So which one is right for you? It all comes down to the goal – i.e. what are you trying to achieve.