summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Allcutt <edward.allcutt@openmarket.com>2014-06-30 16:16:02 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-07-28 08:00:04 -0700
commit08d9137a5e01f7c977b81feefc480da6ce9d7a4b (patch)
tree353ffec51dda51e69d7b6026a141619ce082d3e5
parent00be00119aa3e62aa234a9ccc03010b2504c1096 (diff)
ipv4: icmp: Fix pMTU handling for rare case
[ Upstream commit 68b7107b62983f2cff0948292429d5f5999df096 ] Some older router implementations still send Fragmentation Needed errors with the Next-Hop MTU field set to zero. This is explicitly described as an eventuality that hosts must deal with by the standard (RFC 1191) since older standards specified that those bits must be zero. Linux had a generic (for all of IPv4) implementation of the algorithm described in the RFC for searching a list of MTU plateaus for a good value. Commit 46517008e116 ("ipv4: Kill ip_rt_frag_needed().") removed this as part of the changes to remove the routing cache. Subsequently any Fragmentation Needed packet with a zero Next-Hop MTU has been discarded without being passed to the per-protocol handlers or notifying userspace for raw sockets. When there is a router which does not implement RFC 1191 on an MTU limited path then this results in stalled connections since large packets are discarded and the local protocols are not notified so they never attempt to lower the pMTU. One example I have seen is an OpenBSD router terminating IPSec tunnels. It's worth pointing out that this case is distinct from the BSD 4.2 bug which incorrectly calculated the Next-Hop MTU since the commit in question dismissed that as a valid concern. All of the per-protocols handlers implement the simple approach from RFC 1191 of immediately falling back to the minimum value. Although this is sub-optimal it is vastly preferable to connections hanging indefinitely. Remove the Next-Hop MTU != 0 check and allow such packets to follow the normal path. Fixes: 46517008e116 ("ipv4: Kill ip_rt_frag_needed().") Signed-off-by: Edward Allcutt <edward.allcutt@openmarket.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--net/ipv4/icmp.c2
1 files changed, 0 insertions, 2 deletions
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 76e10b47e053..ea78ef5ac352 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -697,8 +697,6 @@ static void icmp_unreach(struct sk_buff *skb)
&iph->daddr);
} else {
info = ntohs(icmph->un.frag.mtu);
- if (!info)
- goto out;
}
break;
case ICMP_SR_FAILED: