From nobody Thu Nov 27 14:01:09 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