From nobody Thu Sep 18 13:59:07 2025 Delivered-To: wpasupplicant.patchew@gmail.com Received: by 2002:a02:a689:0:0:0:0:0 with SMTP id j9csp1929027jam; Fri, 24 Sep 2021 14:12:52 -0700 (PDT) X-Google-Smtp-Source: ABdhPJygIifx3iUaeuyhASb/chOfsaIUwzkar0/DnUaQwpXaj/+EWcbrkYiuqWz8Zu12DTC7F+QQ X-Received: by 2002:a17:90a:1c6:: with SMTP id 6mr4639016pjd.194.1632517972599; Fri, 24 Sep 2021 14:12:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1632517972; cv=none; d=google.com; s=arc-20160816; b=yMN7/yeS8FdoObjSMErJN63K16GtU42WA/jM04wOi8dcYJDXIE9OFmF6yq5vUqahjx KGhHZR0aCF8+xk9f6WZQ/sa8G7owH5b0ibjknu1rdu7nUD8pac+oT9v/2gg+xs2MkWSv Q7b5xqCG/L+NUq1DdOHUYzs/JFQPUaam9GOUm6kXdq6AFjiyBOXOM8M2MTQZlT1CbIdZ wRPqHBzFM+Oq09dnYBRhqIfU8qR1jRgZCX/lMmDf8l9xQjGBoGlRf8cVhMwyNpuXZ3I3 wfm3gNwaQ3KfgHRZZDuXEvA7OCb2O9CGozrPisgD8lFPdkOY2guPsuZqPDQ3N4502DhV TtMA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from; bh=kWj7jXq6zeuIABCqKf42kZ9zu+Mqh7ss34PAnvsYTKI=; b=B+xNGlYMqRbYL3hpJuNvczWMpFY8BfzVtL54IDJJ7A9mnw8+Kg+uHBzZhfINJPTV6K Iv7rq/858qJvOKCuJQ/GpgtuT+XFHUNI8QSBDpmzRR0fDU3lHbJAjj++65+LPyOGGwvV tQK/OujW9LTHhSJTCFiAeWH/VaUpnVfkwibt4DAJGmfisB2NBo/E/L5fuOaLqChuCDrh KHLTT1SPhaZS9yXFPJUstCf346c4P5MRpz/TctG3/avz3waXBeo5rbhlcI1buCpEGxCl l5K02ZYdC4njGRRdAXA5QWzLwHY6ZpF3g6SemvA/2icmM3836Q2FOlCqtqI1xG5Bed+E A7uA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of mptcp+bounces-2053-wpasupplicant.patchew=gmail.com@lists.linux.dev designates 147.75.69.165 as permitted sender) smtp.mailfrom="mptcp+bounces-2053-wpasupplicant.patchew=gmail.com@lists.linux.dev"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from sjc.edge.kernel.org (sjc.edge.kernel.org. [147.75.69.165]) by mx.google.com with ESMTPS id y2si16094743pjg.116.2021.09.24.14.12.52 for (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 24 Sep 2021 14:12:52 -0700 (PDT) Received-SPF: pass (google.com: domain of mptcp+bounces-2053-wpasupplicant.patchew=gmail.com@lists.linux.dev designates 147.75.69.165 as permitted sender) client-ip=147.75.69.165; Authentication-Results: mx.google.com; spf=pass (google.com: domain of mptcp+bounces-2053-wpasupplicant.patchew=gmail.com@lists.linux.dev designates 147.75.69.165 as permitted sender) smtp.mailfrom="mptcp+bounces-2053-wpasupplicant.patchew=gmail.com@lists.linux.dev"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sjc.edge.kernel.org (Postfix) with ESMTPS id 285D53E1062 for ; Fri, 24 Sep 2021 21:12:52 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id F25793FD5; Fri, 24 Sep 2021 21:12:49 +0000 (UTC) X-Original-To: mptcp@lists.linux.dev Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 994473FC8 for ; Fri, 24 Sep 2021 21:12:48 +0000 (UTC) X-IronPort-AV: E=McAfee;i="6200,9189,10117"; a="246639632" X-IronPort-AV: E=Sophos;i="5.85,321,1624345200"; d="scan'208";a="246639632" Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Sep 2021 14:12:44 -0700 X-IronPort-AV: E=Sophos;i="5.85,321,1624345200"; d="scan'208";a="704320278" Received: from mjmartin-desk2.amr.corp.intel.com (HELO mjmartin-desk2.intel.com) ([10.209.52.210]) by fmsmga006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Sep 2021 14:12:44 -0700 From: Mat Martineau To: netdev@vger.kernel.org Cc: Florian Westphal , davem@davemloft.net, kuba@kernel.org, matthieu.baerts@tessares.net, mptcp@lists.linux.dev, pabeni@redhat.com, Mat Martineau Subject: [PATCH net-next 1/5] mptcp: do not shrink snd_nxt when recovering Date: Fri, 24 Sep 2021 14:12:34 -0700 Message-Id: <20210924211238.162509-2-mathew.j.martineau@linux.intel.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20210924211238.162509-1-mathew.j.martineau@linux.intel.com> References: <20210924211238.162509-1-mathew.j.martineau@linux.intel.com> Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Florian Westphal When recovering after a link failure, snd_nxt should not be set to a lower value. Else, update of snd_nxt is broken because: msk->snd_nxt +=3D ret; (where ret is number of bytes sent) assumes that snd_nxt always moves forward. After reduction, its possible that snd_nxt update gets out of sync: dfrag we just sent might have had a data sequence number even past recovery_snd_nxt. This change factors the common msk state update to a helper and updates snd_nxt based on the current dfrag data sequence number. The conditional is required for the recovery phase where we may re-transmit old dfrags that are before current snd_nxt. After this change, snd_nxt only moves forward and covers all in-sequence data that was transmitted. recovery_snd_nxt is retained to detect when recovery has completed. Fixes: 1e1d9d6f119c5 ("mptcp: handle pending data on closed subflow") Signed-off-by: Florian Westphal Signed-off-by: Mat Martineau --- net/mptcp/options.c | 8 +++----- net/mptcp/protocol.c | 43 +++++++++++++++++++++++++++++++------------ 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/net/mptcp/options.c b/net/mptcp/options.c index c41273cefc51..1ec6529c4326 100644 --- a/net/mptcp/options.c +++ b/net/mptcp/options.c @@ -1019,11 +1019,9 @@ static void ack_update_msk(struct mptcp_sock *msk, old_snd_una =3D msk->snd_una; new_snd_una =3D mptcp_expand_seq(old_snd_una, mp_opt->data_ack, mp_opt->a= ck64); =20 - /* ACK for data not even sent yet and even above recovery bound? Ignore.*/ - if (unlikely(after64(new_snd_una, snd_nxt))) { - if (!msk->recovery || after64(new_snd_una, msk->recovery_snd_nxt)) - new_snd_una =3D old_snd_una; - } + /* ACK for data not even sent yet? Ignore.*/ + if (unlikely(after64(new_snd_una, snd_nxt))) + new_snd_una =3D old_snd_una; =20 new_wnd_end =3D new_snd_una + tcp_sk(ssk)->snd_wnd; =20 diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 7e5f76092b64..3d1757b8ef69 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -1525,6 +1525,32 @@ static void mptcp_push_release(struct sock *sk, stru= ct sock *ssk, release_sock(ssk); } =20 +static void mptcp_update_post_push(struct mptcp_sock *msk, + struct mptcp_data_frag *dfrag, + u32 sent) +{ + u64 snd_nxt_new =3D dfrag->data_seq; + + dfrag->already_sent +=3D sent; + + msk->snd_burst -=3D sent; + msk->tx_pending_data -=3D sent; + + snd_nxt_new +=3D dfrag->already_sent; + + /* snd_nxt_new can be smaller than snd_nxt in case mptcp + * is recovering after a failover. In that event, this re-sends + * old segments. + * + * Thus compute snd_nxt_new candidate based on + * the dfrag->data_seq that was sent and the data + * that has been handed to the subflow for transmission + * and skip update in case it was old dfrag. + */ + if (likely(after64(snd_nxt_new, msk->snd_nxt))) + msk->snd_nxt =3D snd_nxt_new; +} + void __mptcp_push_pending(struct sock *sk, unsigned int flags) { struct sock *prev_ssk =3D NULL, *ssk =3D NULL; @@ -1568,12 +1594,10 @@ void __mptcp_push_pending(struct sock *sk, unsigned= int flags) } =20 info.sent +=3D ret; - dfrag->already_sent +=3D ret; - msk->snd_nxt +=3D ret; - msk->snd_burst -=3D ret; - msk->tx_pending_data -=3D ret; copied +=3D ret; len -=3D ret; + + mptcp_update_post_push(msk, dfrag, ret); } WRITE_ONCE(msk->first_pending, mptcp_send_next(sk)); } @@ -1626,13 +1650,11 @@ static void __mptcp_subflow_push_pending(struct soc= k *sk, struct sock *ssk) goto out; =20 info.sent +=3D ret; - dfrag->already_sent +=3D ret; - msk->snd_nxt +=3D ret; - msk->snd_burst -=3D ret; - msk->tx_pending_data -=3D ret; copied +=3D ret; len -=3D ret; first =3D false; + + mptcp_update_post_push(msk, dfrag, ret); } WRITE_ONCE(msk->first_pending, mptcp_send_next(sk)); } @@ -2230,15 +2252,12 @@ bool __mptcp_retransmit_pending_data(struct sock *s= k) return false; } =20 - /* will accept ack for reijected data before re-sending them */ - if (!msk->recovery || after64(msk->snd_nxt, msk->recovery_snd_nxt)) - msk->recovery_snd_nxt =3D msk->snd_nxt; + msk->recovery_snd_nxt =3D msk->snd_nxt; msk->recovery =3D true; mptcp_data_unlock(sk); =20 msk->first_pending =3D rtx_head; msk->tx_pending_data +=3D msk->snd_nxt - rtx_head->data_seq; - msk->snd_nxt =3D rtx_head->data_seq; msk->snd_burst =3D 0; =20 /* be sure to clear the "sent status" on all re-injected fragments */ --=20 2.33.0