Received: by 2002:a05:6a10:2726:0:0:0:0 with SMTP id ib38csp644550pxb; Tue, 5 Apr 2022 17:06:52 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxLtflkBOs/ztwD2TmMngLuoicqRUgfQ+JONrkEGudaJqwmACIN9i0wPyDL19vKMStXN7PG X-Received: by 2002:a17:90a:4417:b0:1ca:a861:3fbf with SMTP id s23-20020a17090a441700b001caa8613fbfmr7061596pjg.80.1649203611937; Tue, 05 Apr 2022 17:06:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1649203611; cv=none; d=google.com; s=arc-20160816; b=L6IxUiyz8uwfY9x8C4aenVp9YBcu/TxAJ3L7PSKXUMhoPNMUB+3660eYA8VKPi4qFv bMCuvUyIXIDbDH2ABvT9WBKLObW71DYIxRjbZxIlWW0rVZ3e0YlnvBDx542HK+SRHRC+ W0e8WC1BmTSEy/Sd/v1+7tr5PsR/21QFYKJCfnN+bjDpbkp73YkIvwgkteREFDg3Vw/Y 14DMPjOxELxCSVoBxcZJ4Fu80lTp8/uEhQ176qfkCvVR96PuuE2PtR5q9VgnYwGt6VgW 4MhF+p1w9PJCUJxB2ne3Y/tiyNvdBQDLxZJZ85ZkEFloEkCMO9wCMkrurmKp/wkQKOsl k85A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=xrNQB0ulG5ecZtXQnfY1aaljpCIudg9JHFI392y+Jfc=; b=hczIx9TMvfmitOgu0dVimYeG5BSxBwa/zvSu6E+y81FwQK9reRMvBPn8BCbCJiB2SU ugeZj9M7fTiOr9sF0SXYBZrL3/McJ3N6mraNghv4ejRVe9fAk383JJFiHcbxP3TUtq7l vgajYrzhtpuBLcg6vSjenU3LbTBIUKV13fFEOkh+ZdupnQLdzV5vkwba+1CW/RW1uBbU uDeH0U75U/uNaONj7xBT54dPAxKOwMzzhPLJxhbmnheMlgx0qH7ksfeoDLwXvODqneHy I3VA6KsyaxJCja/MypAKtK+w+zlaXvTSWABqLbXLiF1uXExMb1L2rD/NQ6VWPiyBt3/I s8mw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=JhGtfZH4; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [23.128.96.19]) by mx.google.com with ESMTPS id w9-20020a6556c9000000b00398eb2e9574si11419355pgs.298.2022.04.05.17.06.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Apr 2022 17:06:51 -0700 (PDT) Received-SPF: softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) client-ip=23.128.96.19; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=JhGtfZH4; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 0C10D17AD88; Tue, 5 Apr 2022 16:51:40 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240909AbiDEKz1 (ORCPT + 99 others); Tue, 5 Apr 2022 06:55:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57382 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242160AbiDEIhB (ORCPT ); Tue, 5 Apr 2022 04:37:01 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DE36D18E0A; Tue, 5 Apr 2022 01:32:25 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id F338061491; Tue, 5 Apr 2022 08:32:24 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 10FA0C385A1; Tue, 5 Apr 2022 08:32:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1649147544; bh=P35xTf4iwp/DUEsFUMcqfNfZ7QDo6NaErTy6nzlq8/c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JhGtfZH4bTFZkmAfWDj7ecVsg7PSgg5qjB4dIGobjRGeVQ8zKpy+/+PLYN/gCn9Vy gd9Erz/Hi9lT8YqEjBYm276J+6jPvenCyVkhCyi0L+n1WJ12PGD6dru6P9lfLG0zRv gBk6JZk5xc4GflBbm7w5BXhQ/gOnC4+sLC9FKYiA= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Lina Wang , Steffen Klassert , Sasha Levin Subject: [PATCH 5.16 0009/1017] xfrm: fix tunnel model fragmentation behavior Date: Tue, 5 Apr 2022 09:15:22 +0200 Message-Id: <20220405070354.447944502@linuxfoundation.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220405070354.155796697@linuxfoundation.org> References: <20220405070354.155796697@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RDNS_NONE,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Lina Wang [ Upstream commit 4ff2980b6bd2aa6b4ded3ce3b7c0ccfab29980af ] in tunnel mode, if outer interface(ipv4) is less, it is easily to let inner IPV6 mtu be less than 1280. If so, a Packet Too Big ICMPV6 message is received. When send again, packets are fragmentized with 1280, they are still rejected with ICMPV6(Packet Too Big) by xfrmi_xmit2(). According to RFC4213 Section3.2.2: if (IPv4 path MTU - 20) is less than 1280 if packet is larger than 1280 bytes Send ICMPv6 "packet too big" with MTU=1280 Drop packet else Encapsulate but do not set the Don't Fragment flag in the IPv4 header. The resulting IPv4 packet might be fragmented by the IPv4 layer on the encapsulator or by some router along the IPv4 path. endif else if packet is larger than (IPv4 path MTU - 20) Send ICMPv6 "packet too big" with MTU = (IPv4 path MTU - 20). Drop packet. else Encapsulate and set the Don't Fragment flag in the IPv4 header. endif endif Packets should be fragmentized with ipv4 outer interface, so change it. After it is fragemtized with ipv4, there will be double fragmenation. No.48 & No.51 are ipv6 fragment packets, No.48 is double fragmentized, then tunneled with IPv4(No.49& No.50), which obey spec. And received peer cannot decrypt it rightly. 48 2002::10 2002::11 1296(length) IPv6 fragment (off=0 more=y ident=0xa20da5bc nxt=50) 49 0x0000 (0) 2002::10 2002::11 1304 IPv6 fragment (off=0 more=y ident=0x7448042c nxt=44) 50 0x0000 (0) 2002::10 2002::11 200 ESP (SPI=0x00035000) 51 2002::10 2002::11 180 Echo (ping) request 52 0x56dc 2002::10 2002::11 248 IPv6 fragment (off=1232 more=n ident=0xa20da5bc nxt=50) xfrm6_noneed_fragment has fixed above issues. Finally, it acted like below: 1 0x6206 192.168.1.138 192.168.1.1 1316 Fragmented IP protocol (proto=Encap Security Payload 50, off=0, ID=6206) [Reassembled in #2] 2 0x6206 2002::10 2002::11 88 IPv6 fragment (off=0 more=y ident=0x1f440778 nxt=50) 3 0x0000 2002::10 2002::11 248 ICMPv6 Echo (ping) request Signed-off-by: Lina Wang Signed-off-by: Steffen Klassert Signed-off-by: Sasha Levin --- net/ipv6/xfrm6_output.c | 16 ++++++++++++++++ net/xfrm/xfrm_interface.c | 5 ++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c index d0d280077721..ad07904642ca 100644 --- a/net/ipv6/xfrm6_output.c +++ b/net/ipv6/xfrm6_output.c @@ -45,6 +45,19 @@ static int __xfrm6_output_finish(struct net *net, struct sock *sk, struct sk_buf return xfrm_output(sk, skb); } +static int xfrm6_noneed_fragment(struct sk_buff *skb) +{ + struct frag_hdr *fh; + u8 prevhdr = ipv6_hdr(skb)->nexthdr; + + if (prevhdr != NEXTHDR_FRAGMENT) + return 0; + fh = (struct frag_hdr *)(skb->data + sizeof(struct ipv6hdr)); + if (fh->nexthdr == NEXTHDR_ESP || fh->nexthdr == NEXTHDR_AUTH) + return 1; + return 0; +} + static int __xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb) { struct dst_entry *dst = skb_dst(skb); @@ -73,6 +86,9 @@ static int __xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb) xfrm6_local_rxpmtu(skb, mtu); kfree_skb(skb); return -EMSGSIZE; + } else if (toobig && xfrm6_noneed_fragment(skb)) { + skb->ignore_df = 1; + goto skip_frag; } else if (!skb->ignore_df && toobig && skb->sk) { xfrm_local_error(skb, mtu); kfree_skb(skb); diff --git a/net/xfrm/xfrm_interface.c b/net/xfrm/xfrm_interface.c index 4e3c62d1ad9e..1e8b26eecb3f 100644 --- a/net/xfrm/xfrm_interface.c +++ b/net/xfrm/xfrm_interface.c @@ -304,7 +304,10 @@ xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) if (mtu < IPV6_MIN_MTU) mtu = IPV6_MIN_MTU; - icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); + if (skb->len > 1280) + icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); + else + goto xmit; } else { if (!(ip_hdr(skb)->frag_off & htons(IP_DF))) goto xmit; -- 2.34.1