From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 852D6C2D0F9 for ; Wed, 13 May 2020 09:53:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6340220753 for ; Wed, 13 May 2020 09:53:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1589363583; bh=xqrh2MopQeipAcdHacog6ivfLRVDwUVB/2W23jrA/+4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=VteZU8gD/DTPf90dxKg37XbQnuTTetQM2QmXd2l068q9S1fIDDjncRbBUWQGjrg4+ oWFDRhBsfh5n2dQ2RCnGm54kxpEH6SVQmaMUOoCBpYkS4zeCaWgq2XbAPbG2Z3z6si E+/n0fHdFgCSSOU65H2Vt2td4bed3yvc51VGcETI= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387891AbgEMJxC (ORCPT ); Wed, 13 May 2020 05:53:02 -0400 Received: from mail.kernel.org ([198.145.29.99]:54586 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387860AbgEMJwz (ORCPT ); Wed, 13 May 2020 05:52:55 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 95F60206D6; Wed, 13 May 2020 09:52:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1589363575; bh=xqrh2MopQeipAcdHacog6ivfLRVDwUVB/2W23jrA/+4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Jok1ZPMZMc4D25jrfM1gzlHeZJ5+1XGKu1TxuCaT4ZtK8V1f+6OKb3SwsAHj5Po9I GWcheY6C82PvHD/x+j5mQ2lWMNNtnXTr/e1KQTEDHS9TUlylZu9K58e2dWXxthTiQs qmTOwkVMDCGQA2SihEqnDfungc6HNzKokQ3o5/do= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Bob Briscoe , Olivier Tilmans , Dave Taht , Stephen Hemminger , =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= , "David S. Miller" Subject: [PATCH 5.6 040/118] tunnel: Propagate ECT(1) when decapsulating as recommended by RFC6040 Date: Wed, 13 May 2020 11:44:19 +0200 Message-Id: <20200513094420.866941098@linuxfoundation.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200513094417.618129545@linuxfoundation.org> References: <20200513094417.618129545@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: "Toke Høiland-Jørgensen" [ Upstream commit b723748750ece7d844cdf2f52c01d37f83387208 ] RFC 6040 recommends propagating an ECT(1) mark from an outer tunnel header to the inner header if that inner header is already marked as ECT(0). When RFC 6040 decapsulation was implemented, this case of propagation was not added. This simply appears to be an oversight, so let's fix that. Fixes: eccc1bb8d4b4 ("tunnel: drop packet if ECN present with not-ECT") Reported-by: Bob Briscoe Reported-by: Olivier Tilmans Cc: Dave Taht Cc: Stephen Hemminger Signed-off-by: Toke Høiland-Jørgensen Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- include/net/inet_ecn.h | 57 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) --- a/include/net/inet_ecn.h +++ b/include/net/inet_ecn.h @@ -99,6 +99,20 @@ static inline int IP_ECN_set_ce(struct i return 1; } +static inline int IP_ECN_set_ect1(struct iphdr *iph) +{ + u32 check = (__force u32)iph->check; + + if ((iph->tos & INET_ECN_MASK) != INET_ECN_ECT_0) + return 0; + + check += (__force u16)htons(0x100); + + iph->check = (__force __sum16)(check + (check>=0xFFFF)); + iph->tos ^= INET_ECN_MASK; + return 1; +} + static inline void IP_ECN_clear(struct iphdr *iph) { iph->tos &= ~INET_ECN_MASK; @@ -134,6 +148,22 @@ static inline int IP6_ECN_set_ce(struct return 1; } +static inline int IP6_ECN_set_ect1(struct sk_buff *skb, struct ipv6hdr *iph) +{ + __be32 from, to; + + if ((ipv6_get_dsfield(iph) & INET_ECN_MASK) != INET_ECN_ECT_0) + return 0; + + from = *(__be32 *)iph; + to = from ^ htonl(INET_ECN_MASK << 20); + *(__be32 *)iph = to; + if (skb->ip_summed == CHECKSUM_COMPLETE) + skb->csum = csum_add(csum_sub(skb->csum, (__force __wsum)from), + (__force __wsum)to); + return 1; +} + static inline void ipv6_copy_dscp(unsigned int dscp, struct ipv6hdr *inner) { dscp &= ~INET_ECN_MASK; @@ -159,6 +189,25 @@ static inline int INET_ECN_set_ce(struct return 0; } +static inline int INET_ECN_set_ect1(struct sk_buff *skb) +{ + switch (skb->protocol) { + case cpu_to_be16(ETH_P_IP): + if (skb_network_header(skb) + sizeof(struct iphdr) <= + skb_tail_pointer(skb)) + return IP_ECN_set_ect1(ip_hdr(skb)); + break; + + case cpu_to_be16(ETH_P_IPV6): + if (skb_network_header(skb) + sizeof(struct ipv6hdr) <= + skb_tail_pointer(skb)) + return IP6_ECN_set_ect1(skb, ipv6_hdr(skb)); + break; + } + + return 0; +} + /* * RFC 6040 4.2 * To decapsulate the inner header at the tunnel egress, a compliant @@ -208,8 +257,12 @@ static inline int INET_ECN_decapsulate(s int rc; rc = __INET_ECN_decapsulate(outer, inner, &set_ce); - if (!rc && set_ce) - INET_ECN_set_ce(skb); + if (!rc) { + if (set_ce) + INET_ECN_set_ce(skb); + else if ((outer & INET_ECN_MASK) == INET_ECN_ECT_1) + INET_ECN_set_ect1(skb); + } return rc; }