Skip to content

Commit ae15506

Browse files
Paolo Abenikuba-moo
authored andcommitted
mptcp: fix duplicate reset on fastclose
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: d21f834 ("mptcp: use fastclose on more edge scenarios") Cc: stable@vger.kernel.org Closes: multipath-tcp/mptcp_net-next#596 Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Geliang Tang <geliang@kernel.org> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20251118-net-mptcp-misc-fixes-6-18-rc6-v1-6-806d3781c95f@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent fff0c87 commit ae15506

File tree

1 file changed

+23
-13
lines changed

1 file changed

+23
-13
lines changed

net/mptcp/protocol.c

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2409,7 +2409,6 @@ bool __mptcp_retransmit_pending_data(struct sock *sk)
24092409

24102410
/* flags for __mptcp_close_ssk() */
24112411
#define MPTCP_CF_PUSHBIT(1)
2412-
#define MPTCP_CF_FASTCLOSEBIT(2)
24132412

24142413
/* be sure to send a reset only if the caller asked for it, also
24152414
* clean completely the subflow status when the subflow reaches
@@ -2420,7 +2419,7 @@ static void __mptcp_subflow_disconnect(struct sock *ssk,
24202419
unsigned int flags)
24212420
{
24222421
if (((1 << ssk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) ||
2423-
(flags & MPTCP_CF_FASTCLOSE)) {
2422+
subflow->send_fastclose) {
24242423
/* The MPTCP code never wait on the subflow sockets, TCP-level
24252424
* disconnect should never fail
24262425
*/
@@ -2467,14 +2466,8 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
24672466

24682467
lock_sock_nested(ssk, SINGLE_DEPTH_NESTING);
24692468

2470-
if ((flags & MPTCP_CF_FASTCLOSE) && !__mptcp_check_fallback(msk)) {
2471-
/* be sure to force the tcp_close path
2472-
* to generate the egress reset
2473-
*/
2474-
ssk->sk_lingertime = 0;
2475-
sock_set_flag(ssk, SOCK_LINGER);
2476-
subflow->send_fastclose = 1;
2477-
}
2469+
if (subflow->send_fastclose && ssk->sk_state != TCP_CLOSE)
2470+
tcp_set_state(ssk, TCP_CLOSE);
24782471

24792472
need_push = (flags & MPTCP_CF_PUSH) && __mptcp_retransmit_pending_data(sk);
24802473
if (!dispose_it) {
@@ -2779,9 +2772,26 @@ static void mptcp_do_fastclose(struct sock *sk)
27792772
struct mptcp_sock *msk = mptcp_sk(sk);
27802773

27812774
mptcp_set_state(sk, TCP_CLOSE);
2782-
mptcp_for_each_subflow_safe(msk, subflow, tmp)
2783-
__mptcp_close_ssk(sk, mptcp_subflow_tcp_sock(subflow),
2784-
subflow, MPTCP_CF_FASTCLOSE);
2775+
2776+
/* Explicitly send the fastclose reset as need */
2777+
if (__mptcp_check_fallback(msk))
2778+
return;
2779+
2780+
mptcp_for_each_subflow_safe(msk, subflow, tmp) {
2781+
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
2782+
2783+
lock_sock(ssk);
2784+
2785+
/* Some subflow socket states don't allow/need a reset.*/
2786+
if ((1 << ssk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE))
2787+
goto unlock;
2788+
2789+
subflow->send_fastclose = 1;
2790+
tcp_send_active_reset(ssk, ssk->sk_allocation,
2791+
SK_RST_REASON_TCP_ABORT_ON_CLOSE);
2792+
unlock:
2793+
release_sock(ssk);
2794+
}
27852795
}
27862796

27872797
static void mptcp_worker(struct work_struct *work)

0 commit comments

Comments
 (0)