summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2016-01-15 04:56:56 -0800
committerBen Hutchings <ben@decadent.org.uk>2016-05-01 00:05:25 +0200
commit58b45f408a8821b6d9f0003c3fdfa179145c90e7 (patch)
treea95269b3623b4378559ece908e46f499cc0adee8 /net
parent37e9e7ac0e4c75dc516aa1f552ad4b2d8b72a89f (diff)
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')
-rw-r--r--net/ipv4/ip_gre.c2
-rw-r--r--net/ipv6/ip6_tunnel.c2
-rw-r--r--net/ipv6/sit.c2
-rw-r--r--net/ipv6/xfrm6_mode_tunnel.c2
4 files changed, 4 insertions, 4 deletions
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 5f28fabffd67..601254e4f28f 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -535,7 +535,7 @@ static inline void ipgre_ecn_decapsulate(const struct iphdr *iph, struct sk_buff
if (skb->protocol == htons(ETH_P_IP)) {
IP_ECN_set_ce(ip_hdr(skb));
} else if (skb->protocol == htons(ETH_P_IPV6)) {
- IP6_ECN_set_ce(ipv6_hdr(skb));
+ IP6_ECN_set_ce(skb, ipv6_hdr(skb));
}
}
}
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.