summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteffen Klassert <steffen.klassert@secunet.com>2015-10-19 04:30:05 -0400
committerSteffen Klassert <steffen.klassert@secunet.com>2015-10-19 04:30:05 -0400
commitca064bd89363a6e7e71b1c5226ff1b718957a9d4 (patch)
tree4c40ed6e576810be7c1282e875cd132c422733f9
parent4e077237cfb6ab13701d504060d3ae248b191e6e (diff)
xfrm: Fix pmtu discovery for local generated packets.
Commit 044a832a777 ("xfrm: Fix local error reporting crash with interfamily tunnels") moved the setting of skb->protocol behind the last access of the inner mode family to fix an interfamily crash. Unfortunately now skb->protocol might not be set at all, so we fail dispatch to the inner address family. As a reault, the local error handler is not called and the mtu value is not reported back to userspace. We fix this by setting skb->protocol on message size errors before we call xfrm_local_error. Fixes: 044a832a7779c ("xfrm: Fix local error reporting crash with interfamily tunnels") Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
-rw-r--r--net/ipv4/xfrm4_output.c2
-rw-r--r--net/ipv6/xfrm6_output.c1
2 files changed, 3 insertions, 0 deletions
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index 2878dbfffeb7..41a261355662 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -30,6 +30,8 @@ static int xfrm4_tunnel_check_size(struct sk_buff *skb)
30 30
31 mtu = dst_mtu(skb_dst(skb)); 31 mtu = dst_mtu(skb_dst(skb));
32 if (skb->len > mtu) { 32 if (skb->len > mtu) {
33 skb->protocol = htons(ETH_P_IP);
34
33 if (skb->sk) 35 if (skb->sk)
34 xfrm_local_error(skb, mtu); 36 xfrm_local_error(skb, mtu);
35 else 37 else
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index be033f22a3f3..e15feb7b413d 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -79,6 +79,7 @@ static int xfrm6_tunnel_check_size(struct sk_buff *skb)
79 79
80 if (!skb->ignore_df && skb->len > mtu) { 80 if (!skb->ignore_df && skb->len > mtu) {
81 skb->dev = dst->dev; 81 skb->dev = dst->dev;
82 skb->protocol = htons(ETH_P_IPV6);
82 83
83 if (xfrm6_local_dontfrag(skb)) 84 if (xfrm6_local_dontfrag(skb))
84 xfrm6_local_rxpmtu(skb, mtu); 85 xfrm6_local_rxpmtu(skb, mtu);