From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from omzsmtpe02.verizonbusiness.com ([199.249.25.209]:9918 "EHLO omzsmtpe02.verizonbusiness.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751176AbdFDIMz (ORCPT ); Sun, 4 Jun 2017 04:12:55 -0400 From: "Levin, Alexander (Sasha Levin)" Cc: Dimitris Michailidis , "David S . Miller" , "Levin, Alexander (Sasha Levin)" To: "stable@vger.kernel.org" Subject: [PATCH for v4.9 LTS 042/111] ipv6: fix flow labels when the traffic class is non-0 Date: Sun, 4 Jun 2017 08:12:13 +0000 Message-ID: <20170604081123.19462-42-alexander.levin@verizon.com> References: <20170604081123.19462-1-alexander.levin@verizon.com> In-Reply-To: <20170604081123.19462-1-alexander.levin@verizon.com> Content-Language: en-US Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Sender: stable-owner@vger.kernel.org List-ID: From: Dimitris Michailidis [ Upstream commit 90427ef5d2a4b9a24079889bf16afdcdaebc4240 ] ip6_make_flowlabel() determines the flow label for IPv6 packets. It's supposed to be passed a flow label, which it returns as is if non-0 and in some other cases, otherwise it calculates a new value. The problem is callers often pass a flowi6.flowlabel, which may also contain traffic class bits. If the traffic class is non-0 ip6_make_flowlabel() mistakes the non-0 it gets as a flow label and returns the whole thing. Thus it can return a 'flow label' longer than 20b and the low 20b of that is typically 0 resulting in packets with 0 label. Moreover, different packets of a flow may be labeled differently. For a TCP flow with ECN non-payload and payload packets get different labels as exemplified by this pair of consecutive packets: (pure ACK) Internet Protocol Version 6, Src: 2002:af5:11a3::, Dst: 2002:af5:11a2:: 0110 .... =3D Version: 6 .... 0000 0000 .... .... .... .... .... =3D Traffic Class: 0x00 (DSCP: = CS0, ECN: Not-ECT) .... 0000 00.. .... .... .... .... .... =3D Differentiated Services= Codepoint: Default (0) .... .... ..00 .... .... .... .... .... =3D Explicit Congestion Not= ification: Not ECN-Capable Transport (0) .... .... .... 0001 1100 1110 0100 1001 =3D Flow Label: 0x1ce49 Payload Length: 32 Next Header: TCP (6) (payload) Internet Protocol Version 6, Src: 2002:af5:11a3::, Dst: 2002:af5:11a2:: 0110 .... =3D Version: 6 .... 0000 0010 .... .... .... .... .... =3D Traffic Class: 0x02 (DSCP: = CS0, ECN: ECT(0)) .... 0000 00.. .... .... .... .... .... =3D Differentiated Services= Codepoint: Default (0) .... .... ..10 .... .... .... .... .... =3D Explicit Congestion Not= ification: ECN-Capable Transport codepoint '10' (2) .... .... .... 0000 0000 0000 0000 0000 =3D Flow Label: 0x00000 Payload Length: 688 Next Header: TCP (6) This patch allows ip6_make_flowlabel() to be passed more than just a flow label and has it extract the part it really wants. This was simpler than modifying the callers. With this patch packets like the above become Internet Protocol Version 6, Src: 2002:af5:11a3::, Dst: 2002:af5:11a2:: 0110 .... =3D Version: 6 .... 0000 0000 .... .... .... .... .... =3D Traffic Class: 0x00 (DSCP: = CS0, ECN: Not-ECT) .... 0000 00.. .... .... .... .... .... =3D Differentiated Services= Codepoint: Default (0) .... .... ..00 .... .... .... .... .... =3D Explicit Congestion Not= ification: Not ECN-Capable Transport (0) .... .... .... 1010 1111 1010 0101 1110 =3D Flow Label: 0xafa5e Payload Length: 32 Next Header: TCP (6) Internet Protocol Version 6, Src: 2002:af5:11a3::, Dst: 2002:af5:11a2:: 0110 .... =3D Version: 6 .... 0000 0010 .... .... .... .... .... =3D Traffic Class: 0x02 (DSCP: = CS0, ECN: ECT(0)) .... 0000 00.. .... .... .... .... .... =3D Differentiated Services= Codepoint: Default (0) .... .... ..10 .... .... .... .... .... =3D Explicit Congestion Not= ification: ECN-Capable Transport codepoint '10' (2) .... .... .... 1010 1111 1010 0101 1110 =3D Flow Label: 0xafa5e Payload Length: 688 Next Header: TCP (6) Signed-off-by: Dimitris Michailidis Acked-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- include/net/ipv6.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 7f15f95625e7..3fe4d7452bb3 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -776,6 +776,11 @@ static inline __be32 ip6_make_flowlabel(struct net *ne= t, struct sk_buff *skb, { u32 hash; =20 + /* @flowlabel may include more than a flow label, eg, the traffic class. + * Here we want only the flow label value. + */ + flowlabel &=3D IPV6_FLOWLABEL_MASK; + if (flowlabel || net->ipv6.sysctl.auto_flowlabels =3D=3D IP6_AUTO_FLOW_LABEL_OFF || (!autolabel && --=20 2.11.0