From nobody Thu Nov 27 12:35:52 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (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 AD86A26462E for ; Fri, 7 Nov 2025 07:23:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762500197; cv=none; b=jus5dTznIqahC0aerUzXVqF4Ft8D0qovQ3a8M/ZijSb7/Ikh18O7Z5A4VyWBhQek7LkG5Y0zzWTGlm36M3pprUAJvS4gQdGc5O5I80HmdBFeqhc8dpr4fNLqa+zW7HGQYnZvm+u1/w1mDQ+3xqufqv5aVHWwe8OkAYUlZRzaPcU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762500197; c=relaxed/simple; bh=2YwtKR4mx905FfZ43qrIWW7fGqnXNDhGTdmCdBRyIzU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:content-type; b=aQzcuAoG4Y5emUUbctcOGKhawzSsZumptq8+LnkJzBkXgSF3xI1LnCjYcFJw7wJQ7zit7eeXwjkHrM5vCJ87kgiOM7i3gaYCLVBl60fUuU3+8c/mHCpR0HAaGcPnKRZJwAJNVuPIIlUtKrgMHkJo/wAnNvpGAbqiVGU7nS2X+As= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=dpD9UVHu; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="dpD9UVHu" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1762500194; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=UMwDml48iEqLKQNe+a1cHe0LETOykt21cfy1PDRoX/M=; b=dpD9UVHueYAIS4UJFX2lIA97wx5pPyU7YuKpwqY4eU753ASZ7BplY/cQ0lt6Nl5jrRMvUI aLKRD+FFeodOKP7NEiICkLhG4TbKipcd8cBYH0otN69XJlwhZ33BrTtCWR3sk6Ktn6Aj3v /Ldqsab/mnwLykkoPhN2gFscECyou/0= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-453-5XvemQEXO32FBg-pS2kdcQ-1; Fri, 07 Nov 2025 02:23:12 -0500 X-MC-Unique: 5XvemQEXO32FBg-pS2kdcQ-1 X-Mimecast-MFC-AGG-ID: 5XvemQEXO32FBg-pS2kdcQ_1762500192 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id BDD48180028A; Fri, 7 Nov 2025 07:23:11 +0000 (UTC) Received: from gerbillo.redhat.com (unknown [10.44.32.157]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 8F2761800362; Fri, 7 Nov 2025 07:23:10 +0000 (UTC) From: Paolo Abeni To: mptcp@lists.linux.dev Cc: geliang@kernel.org Subject: [PATCH v2 mptcp-net 1/2] mptcp: decouple mptcp fastclose from tcp close Date: Fri, 7 Nov 2025 08:23:03 +0100 Message-ID: <235288b5bd06f28f5df094cd27bcd33bdcbf34f3.1762500073.git.pabeni@redhat.com> In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: QUSFZ3ayKhCE0SdKn_Nw_Qf7CQi8zD1MeJYUKmmiEUY_1762500192 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8"; x-default="true" With the current fastclose implementation, the mptcp_do_fastclose() helper is in charge of two distinct actions: send the fastclose reset and cleanup the subflows. Formally decouple the two steps, ensuring that mptcp explicitly closes all the subflows after the mentioned helper. This will make the upcoming fix simpler, and allows dropping the 2nd argument from mptcp_destroy_common(). Signed-off-by: Paolo Abeni Reviewed-by: Matthieu Baerts (NGI0) --- net/mptcp/protocol.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 1506fde9a6da..0301e0b0de05 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -2884,7 +2884,11 @@ static void mptcp_worker(struct work_struct *work) __mptcp_close_subflow(sk); =20 if (mptcp_close_tout_expired(sk)) { + struct mptcp_subflow_context *subflow, *tmp; + mptcp_do_fastclose(sk); + mptcp_for_each_subflow_safe(msk, subflow, tmp) + __mptcp_close_ssk(sk, subflow->tcp_sock, subflow, 0); mptcp_close_wake_up(sk); } =20 @@ -3289,7 +3293,7 @@ static void mptcp_copy_inaddrs(struct sock *msk, cons= t struct sock *ssk) inet_sk(msk)->inet_rcv_saddr =3D inet_sk(ssk)->inet_rcv_saddr; } =20 -static void mptcp_destroy_common(struct mptcp_sock *msk, unsigned int flag= s) +static void mptcp_destroy_common(struct mptcp_sock *msk) { struct mptcp_subflow_context *subflow, *tmp; struct sock *sk =3D (struct sock *)msk; @@ -3299,7 +3303,7 @@ static void mptcp_destroy_common(struct mptcp_sock *m= sk, unsigned int flags) =20 /* join list will be eventually flushed (with rst) at sock lock release t= ime */ mptcp_for_each_subflow_safe(msk, subflow, tmp) - __mptcp_close_ssk(sk, mptcp_subflow_tcp_sock(subflow), subflow, flags); + __mptcp_close_ssk(sk, mptcp_subflow_tcp_sock(subflow), subflow, 0); =20 __skb_queue_purge(&sk->sk_receive_queue); skb_rbtree_purge(&msk->out_of_order_queue); @@ -3333,7 +3337,8 @@ static int mptcp_disconnect(struct sock *sk, int flag= s) /* msk->subflow is still intact, the following will not free the first * subflow */ - mptcp_destroy_common(msk, MPTCP_CF_FASTCLOSE); + mptcp_do_fastclose(sk); + mptcp_destroy_common(msk); =20 /* The first subflow is already in TCP_CLOSE status, the following * can't overlap with a fallback anymore @@ -3521,7 +3526,7 @@ static void mptcp_destroy(struct sock *sk) =20 /* allow the following to close even the initial subflow */ msk->free_first =3D 1; - mptcp_destroy_common(msk, 0); + mptcp_destroy_common(msk); sk_sockets_allocated_dec(sk); } =20 --=20 2.51.0 From nobody Thu Nov 27 12:35:52 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (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 0993F298CDC for ; Fri, 7 Nov 2025 07:23:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762500198; cv=none; b=CyFK7kQELG0tPE9ImiQqqYfzN7wf4Ih+0TDkNP6kc+Zg9dWQkWSXWnPD6evY4aWe3mSpnxaRuuU40s47Wr3WDHH2asFJNpbb2ooAnlc3A1racWIdHJuQ8zytkEzoZyFOJYkMUk++zWMV+CF0R5dEBIzGLRH2C1h4kYLYWu+ZOw4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762500198; c=relaxed/simple; bh=nMTl7W1IatqGq5s9O5jpxwu2Ik+UTYtEXeyz4RmtRig=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:content-type; b=X1bfdVOTXa6Ung58g1LjrRV4MgAOKsUqOWbc3L06hhYYjofT/N1ZqLbaqAalPJVu9EnqF4mB+IlOF/jMz7isVp3PV+qB+q7JG30S692+X5kyKIoLWDuCeQbLn2YJ0a3L6JF6Rui9RhEPUjoxLgE/scEct58E8dmHQ4a+adNpXRg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=fDkuJFhx; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="fDkuJFhx" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1762500195; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=JwLyeDjwW/e+rxk+/C9HVgwtOa+DCRd3X4RjNK4HTRw=; b=fDkuJFhxCdaR/oAtWHzH/C4QA+9fOVgdUKLhoV6k8RFuwNdFIuUXFECJToaG67z41gM4sc OA4z8VJIWPawvIl81/rdB0tKK6GCu/K1jCddZxALWONfUhBPTjtD3Rvx7/+mfpInmYHp8O yR30pH097hP1YHY4TjVC3U+kJ8WFse0= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-638-ZxbJGuURO1GNBnvEy48q1Q-1; Fri, 07 Nov 2025 02:23:14 -0500 X-MC-Unique: ZxbJGuURO1GNBnvEy48q1Q-1 X-Mimecast-MFC-AGG-ID: ZxbJGuURO1GNBnvEy48q1Q_1762500193 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 6E52419560A7; Fri, 7 Nov 2025 07:23:13 +0000 (UTC) Received: from gerbillo.redhat.com (unknown [10.44.32.157]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 5022B1800298; Fri, 7 Nov 2025 07:23:12 +0000 (UTC) From: Paolo Abeni To: mptcp@lists.linux.dev Cc: geliang@kernel.org Subject: [PATCH v2 mptcp-net 2/2] mptcp: fix duplicate reset on fastclose Date: Fri, 7 Nov 2025 08:23:04 +0100 Message-ID: <32586f43554a4837f39d534676c5ad957dc10dd5.1762500073.git.pabeni@redhat.com> In-Reply-To: References: Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: IpJoHkKfUkgv6UFBJ9LvFL8xZQb68ZmTm93uWH7NaTk_1762500193 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8"; x-default="true" The CI reports sporadic failures of the fastclose self-tests. The root cause is a duplicate reset, not carrying the relevant MPTCP option. In the failing scenario the bad reset is received by the peer before the fastclose one, preventing the reception of the latter. Indeed there is window of opportunity at fastclose time for the following race: mptcp_do_fastclose __mptcp_close_ssk __tcp_close() tcp_set_state() [1] tcp_send_active_reset() [2] After [1] the stack will send reset to in-flight data reaching the now closed port. Such reset may race with [2]. Address the issue explicitly sending a single reset on fastclose before explicitly moving the subflow to close status. Fixes: d21f83485518 ("mptcp: use fastclose on more edge scenarios"); Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/596 Signed-off-by: Paolo Abeni Reviewed-by: Matthieu Baerts (NGI0) --- v1 -> v2: - test subflow->send_fastclose in __mptcp_subflow_disconnect() instead of MPTCP_CF_FASTCLOSE --- net/mptcp/protocol.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 0301e0b0de05..24d4fa8227b7 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -2437,7 +2437,6 @@ bool __mptcp_retransmit_pending_data(struct sock *sk) =20 /* flags for __mptcp_close_ssk() */ #define MPTCP_CF_PUSH BIT(1) -#define MPTCP_CF_FASTCLOSE BIT(2) =20 /* be sure to send a reset only if the caller asked for it, also * clean completely the subflow status when the subflow reaches @@ -2448,7 +2447,7 @@ static void __mptcp_subflow_disconnect(struct sock *s= sk, unsigned int flags) { if (((1 << ssk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) || - (flags & MPTCP_CF_FASTCLOSE)) { + subflow->send_fastclose) { /* The MPTCP code never wait on the subflow sockets, TCP-level * disconnect should never fail */ @@ -2511,20 +2510,13 @@ static void __mptcp_close_ssk(struct sock *sk, stru= ct sock *ssk, if (dispose_it) list_del(&subflow->node); =20 - if ((flags & MPTCP_CF_FASTCLOSE) && !__mptcp_check_fallback(msk)) { - /* be sure to force the tcp_close path - * to generate the egress reset - */ - ssk->sk_lingertime =3D 0; - sock_set_flag(ssk, SOCK_LINGER); - subflow->send_fastclose =3D 1; - } + if (subflow->send_fastclose && ssk->sk_state !=3D TCP_CLOSE) + tcp_set_state(ssk, TCP_CLOSE); =20 need_push =3D (flags & MPTCP_CF_PUSH) && __mptcp_retransmit_pending_data(= sk); if (!dispose_it) { __mptcp_subflow_disconnect(ssk, subflow, flags); release_sock(ssk); - goto out; } =20 @@ -2855,9 +2847,26 @@ static void mptcp_do_fastclose(struct sock *sk) =20 mptcp_set_state(sk, TCP_CLOSE); mptcp_backlog_purge(sk); - mptcp_for_each_subflow_safe(msk, subflow, tmp) - __mptcp_close_ssk(sk, mptcp_subflow_tcp_sock(subflow), - subflow, MPTCP_CF_FASTCLOSE); + + /* Explicitly send the fastclose reset as need */ + if (__mptcp_check_fallback(msk)) + return; + + mptcp_for_each_subflow_safe(msk, subflow, tmp) { + struct sock *ssk =3D mptcp_subflow_tcp_sock(subflow); + + lock_sock(ssk); + + /* Some subflow socket states don't allow/need a reset.*/ + if ((1 << ssk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) + goto unlock; + + subflow->send_fastclose =3D 1; + tcp_send_active_reset(ssk, ssk->sk_allocation, + SK_RST_REASON_TCP_ABORT_ON_CLOSE); +unlock: + release_sock(ssk); + } } =20 static void mptcp_worker(struct work_struct *work) --=20 2.51.0