Bug 55861 - PMTU discovery no longer works in Linux 3.6+ with routers that do not send next hop MTU information
Summary: PMTU discovery no longer works in Linux 3.6+ with routers that do not send ne...
Status: NEW
Alias: None
Product: Networking
Classification: Unclassified
Component: IPV4 (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: Stephen Hemminger
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-03-27 15:25 UTC by Max Bowsher
Modified: 2014-08-06 23:07 UTC (History)
3 users (show)

See Also:
Kernel Version: 3.6 onwards
Subsystem:
Regression: Yes
Bisected commit-id:


Attachments

Description Max Bowsher 2013-03-27 15:25:13 UTC
After upgrading recently, I found that path MTU discovery no longer worked correctly for accessing some devices on the other side of an IPsec tunnel.

Bisection revealed the problems started with 3.6 and are still present in 3.9-rc4 (latest available at time of reporting).

Some investigation into code changes leads me to the belief that Linux lost support for handling ICMP destination unreachable fragmentation needed packets for which the next hop MTU field is zero. This is an expected condition when dealing with older routers, as RFC792 originally defined ICMP destination unreachable fragmentation needed without a next hop MTU field, and it was later added in bytes previously allocated as unused.

The particular router in my case generating such packets is a machine running OpenBSD 4.6.

A commit that appears to be of particular interest in this bug is https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=46517008e1168dc926cf2c47d529efc07eca85c0
Comment 1 Max Bowsher 2013-03-27 16:52:46 UTC
The proper handling of these ICMP packets is more clearly explained in RFC1191, in which section 3 contains the statement:

   Hosts MUST be able to deal with Datagram Too Big messages that do not
   include the next-hop MTU, since it is not feasible to upgrade all the
   routers in the Internet in any finite time.
Comment 2 Edward Allcutt 2013-03-27 18:11:59 UTC
The specific problem seems to be in net/ipv4/icmp.c:icmp_unreach()

                case ICMP_FRAG_NEEDED:
                                info = ntohs(icmph->un.frag.mtu);
                                if (!info)
                                        goto out;

where the goto skips the later icmp_socket_deliver() that would invoke the upper protocol stack, which seems after a brief look to handle this case fine.
Comment 3 Edward Allcutt 2014-08-06 23:07:37 UTC
Fixed upstream in 3.16 (commit is 68b7107).

Note You need to log in before you can comment on or make changes to this bug.