diff options
author | Eric Dumazet <edumazet@google.com> | 2016-01-15 04:56:56 -0800 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2016-05-01 00:05:25 +0200 |
commit | 58b45f408a8821b6d9f0003c3fdfa179145c90e7 (patch) | |
tree | a95269b3623b4378559ece908e46f499cc0adee8 /net/ipv6 | |
parent | 37e9e7ac0e4c75dc516aa1f552ad4b2d8b72a89f (diff) | |
download | lwn-58b45f408a8821b6d9f0003c3fdfa179145c90e7.tar.gz lwn-58b45f408a8821b6d9f0003c3fdfa179145c90e7.zip |
ipv6: update skb->csum when CE mark is propagated
[ Upstream commit 34ae6a1aa0540f0f781dd265366036355fdc8930 ]
When a tunnel decapsulates the outer header, it has to comply
with RFC 6080 and eventually propagate CE mark into inner header.
It turns out IP6_ECN_set_ce() does not correctly update skb->csum
for CHECKSUM_COMPLETE packets, triggering infamous "hw csum failure"
messages and stack traces.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
[bwh: Backported to 3.2:
- Adjust context
- Add skb argument to other callers of IP6_ECN_set_ce()]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/ip6_tunnel.c | 2 | ||||
-rw-r--r-- | net/ipv6/sit.c | 2 | ||||
-rw-r--r-- | net/ipv6/xfrm6_mode_tunnel.c | 2 |
3 files changed, 3 insertions, 3 deletions
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index ae32ff78ab31..1828c27ba7aa 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -689,7 +689,7 @@ static void ip6ip6_dscp_ecn_decapsulate(const struct ip6_tnl *t, ipv6_copy_dscp(ipv6_get_dsfield(ipv6h), ipv6_hdr(skb)); if (INET_ECN_is_ce(ipv6_get_dsfield(ipv6h))) - IP6_ECN_set_ce(ipv6_hdr(skb)); + IP6_ECN_set_ce(skb, ipv6_hdr(skb)); } /* called with rcu_read_lock() */ diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 52ce1969d9b2..1dbd1d10ca9d 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -553,7 +553,7 @@ out: static inline void ipip6_ecn_decapsulate(const struct iphdr *iph, struct sk_buff *skb) { if (INET_ECN_is_ce(iph->tos)) - IP6_ECN_set_ce(ipv6_hdr(skb)); + IP6_ECN_set_ce(skb, ipv6_hdr(skb)); } static int ipip6_rcv(struct sk_buff *skb) diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c index 23ecd68a5e62..e33c9d7a4f85 100644 --- a/net/ipv6/xfrm6_mode_tunnel.c +++ b/net/ipv6/xfrm6_mode_tunnel.c @@ -24,7 +24,7 @@ static inline void ipip6_ecn_decapsulate(struct sk_buff *skb) struct ipv6hdr *inner_iph = ipipv6_hdr(skb); if (INET_ECN_is_ce(ipv6_get_dsfield(outer_iph))) - IP6_ECN_set_ce(inner_iph); + IP6_ECN_set_ce(skb, inner_iph); } /* Add encapsulation header. |