From patchwork Wed Oct 18 18:23:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mat Martineau X-Patchwork-Id: 13427718 X-Patchwork-Delegate: kuba@kernel.org Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 7F6A44177B; Wed, 18 Oct 2023 18:24:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Jk+4E41E" Received: by smtp.kernel.org (Postfix) with ESMTPSA id CEE29C433BB; Wed, 18 Oct 2023 18:24:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1697653444; bh=t3JO7pRjalAV5hLmRWEH40gfq1UpKK71NZeBrKPyjZw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Jk+4E41EHF7J+cpx8/j+4/hb+6adn6mFoDsvppVDqd+mvYF60l5Yo2yTDq14gJHN8 KZ4X67tmi+F4ruFvCK0Om7s6Teil0Imo61S0oXO5wLzGMH5FpaiBB8iDJwfdosy7x1 F6kw+UljXajFbdina45Hks3zVkLeBek8HxqijwUR7rrbpNorbeUqBKt95WrZTldFkj lMrdbHpgnizg5keYWt7fTyRO+v5QUeeP8nGah+BzPwL6W5lZIU/n/wCaNA/EOLoJwC Y0RVkd79MZoOjFJsqr35Lx+HwXgGym0KbgoqnhV+xsyYT6DZRl5D+nX4B4/nqUXsA7 QTfeJDSD+DrYQ== From: Mat Martineau Date: Wed, 18 Oct 2023 11:23:55 -0700 Subject: [PATCH net 4/5] mptcp: avoid sending RST when closing the initial subflow Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20231018-send-net-20231018-v1-4-17ecb002e41d@kernel.org> References: <20231018-send-net-20231018-v1-0-17ecb002e41d@kernel.org> In-Reply-To: <20231018-send-net-20231018-v1-0-17ecb002e41d@kernel.org> To: Matthieu Baerts , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , David Ahern , Davide Caratti , Christoph Paasch , Florian Westphal Cc: netdev@vger.kernel.org, mptcp@lists.linux.dev, Mat Martineau , Geliang Tang , stable@vger.kernel.org X-Mailer: b4 0.12.3 X-Patchwork-Delegate: kuba@kernel.org From: Geliang Tang When closing the first subflow, the MPTCP protocol unconditionally calls tcp_disconnect(), which in turn generates a reset if the subflow is established. That is unexpected and different from what MPTCP does with MPJ subflows, where resets are generated only on FASTCLOSE and other edge scenarios. We can't reuse for the first subflow the same code in place for MPJ subflows, as MPTCP clean them up completely via a tcp_close() call, while must keep the first subflow socket alive for later re-usage, due to implementation constraints. This patch adds a new helper __mptcp_subflow_disconnect() that encapsulates, a logic similar to tcp_close, issuing a reset only when the MPTCP_CF_FASTCLOSE flag is set, and performing a clean shutdown otherwise. Fixes: c2b2ae3925b6 ("mptcp: handle correctly disconnect() failures") Cc: stable@vger.kernel.org Reviewed-by: Matthieu Baerts Co-developed-by: Paolo Abeni Signed-off-by: Paolo Abeni Signed-off-by: Geliang Tang Signed-off-by: Mat Martineau --- net/mptcp/protocol.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 4e30e5ba3795..886ab689a8ae 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -2348,6 +2348,26 @@ bool __mptcp_retransmit_pending_data(struct sock *sk) #define MPTCP_CF_PUSH BIT(1) #define MPTCP_CF_FASTCLOSE BIT(2) +/* be sure to send a reset only if the caller asked for it, also + * clean completely the subflow status when the subflow reaches + * TCP_CLOSE state + */ +static void __mptcp_subflow_disconnect(struct sock *ssk, + struct mptcp_subflow_context *subflow, + unsigned int flags) +{ + if (((1 << ssk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) || + (flags & MPTCP_CF_FASTCLOSE)) { + /* The MPTCP code never wait on the subflow sockets, TCP-level + * disconnect should never fail + */ + WARN_ON_ONCE(tcp_disconnect(ssk, 0)); + mptcp_subflow_ctx_reset(subflow); + } else { + tcp_shutdown(ssk, SEND_SHUTDOWN); + } +} + /* subflow sockets can be either outgoing (connect) or incoming * (accept). * @@ -2385,7 +2405,7 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk, lock_sock_nested(ssk, SINGLE_DEPTH_NESTING); if ((flags & MPTCP_CF_FASTCLOSE) && !__mptcp_check_fallback(msk)) { - /* be sure to force the tcp_disconnect() path, + /* be sure to force the tcp_close path * to generate the egress reset */ ssk->sk_lingertime = 0; @@ -2395,11 +2415,7 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk, need_push = (flags & MPTCP_CF_PUSH) && __mptcp_retransmit_pending_data(sk); if (!dispose_it) { - /* The MPTCP code never wait on the subflow sockets, TCP-level - * disconnect should never fail - */ - WARN_ON_ONCE(tcp_disconnect(ssk, 0)); - mptcp_subflow_ctx_reset(subflow); + __mptcp_subflow_disconnect(ssk, subflow, flags); release_sock(ssk); goto out;