Patch "ipv6: update skb->csum when CE mark is propagated" has been added to the 4.3-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
ipv6: update skb->csum when CE mark is propagated
to the 4.3-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
ipv6-update-skb-csum-when-ce-mark-is-propagated.patch
and it can be found in the queue-4.3 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Tue Jan 26 21:35:03 PST 2016
From: Eric Dumazet <[email protected]>
Date: Fri, 15 Jan 2016 04:56:56 -0800
Subject: ipv6: update skb->csum when CE mark is propagated
From: Eric Dumazet <[email protected]>
[ 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.
--- include/net/inet_ecn.h | 19 ++++++++++++++++--- net/ipv6/xfrm6_mode_tunnel.c | 2 +- 2 files changed, 17 insertions(+), 4 deletions(-)
include/net/inet_ecn.h +16 -3
@@ -111,11 +111,24 @@ static inline void ipv4_copy_dscp(unsignstruct ipv6hdr ; -static inline int IP6_ECN_set_ce (struct ipv6hdr *iph) +/* Note: +* IP_ECN_set_ce() has to tweak IPV4 checksum when setting CE, +* meaning both changes have no effect on skb->csum if/when CHECKSUM_COMPLETE +* In IPv6 case, no checksum compensates the change in IPv6 header, +* so we have to update skb->csum. +*/ +static inline int IP6_ECN_set_ce (struct sk_buff *skb,struct ipv6hdr *iph) { +__be32 from, to; +if (INET_ECN_is_not_ect (ipv6_get_dsfield (iph)))return 0 ; - *(__be32 *)iph |=htonl (INET_ECN_CE <<20 ); + + from = *(__be32 *)iph; + to = from |htonl (INET_ECN_CE <<20 ); + *(__be32 *)iph = to; +if (skb->ip_summed ==CHECKSUM_COMPLETE ) + skb->csum =csum_add (csum_sub (skb->csum, from), to);return 1 ; }
@@ -142,7 +155,7 @@ static inline int INET_ECN_set_ce(structcase cpu_to_be16 (ETH_P_IPV6 ):if (skb_network_header (skb) +sizeof (struct ipv6hdr ) <=skb_tail_pointer (skb)) -return IP6_ECN_set_ce (ipv6_hdr (skb)); +return IP6_ECN_set_ce (skb,ipv6_hdr (skb));break ; }
net/ipv6/xfrm6_mode_tunnel.c +1 -1
@@ -23,7 +23,7 @@ static inline void ipip6_ecn_decapsulatestruct ipv6hdr *inner_iph =ipipv6_hdr (skb);if (INET_ECN_is_ce (XFRM_MODE_SKB_CB (skb)->tos)) -IP6_ECN_set_ce (inner_iph); +IP6_ECN_set_ce (skb, inner_iph); }/* Add encapsulation header.
Patches currently in stable-queue which might be from [email protected] are
queue-4.3/tcp-fix-zero-cwnd-in-tcp_cwnd_reduction.patch queue-4.3/net-sched-fix-missing-free-per-cpu-on-qstats.patch queue-4.3/ipv6-tcp-add-rcu-locking-in-tcp_v6_send_synack.patch queue-4.3/ipv6-update-skb-csum-when-ce-mark-is-propagated.patch queue-4.3/net-possible-use-after-free-in-dst_release.patch queue-4.3/phonet-properly-unshare-skbs-in-phonet_rcv.patch queue-4.3/tcp_yeah-don-t-set-ssthresh-below-2.patch