Skip to content

Commit 14c5668

Browse files
geliangtangkuba-moo
authored andcommitted
mptcp: avoid sending RST when closing the initial subflow
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: c2b2ae3 ("mptcp: handle correctly disconnect() failures") Cc: stable@vger.kernel.org Reviewed-by: Matthieu Baerts <matttbe@kernel.org> Co-developed-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Geliang Tang <geliang.tang@suse.com> Signed-off-by: Mat Martineau <martineau@kernel.org> Link: https://lore.kernel.org/r/20231018-send-net-20231018-v1-4-17ecb002e41d@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 72377ab commit 14c5668

File tree

1 file changed

+22
-6
lines changed

1 file changed

+22
-6
lines changed

net/mptcp/protocol.c

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2348,6 +2348,26 @@ bool __mptcp_retransmit_pending_data(struct sock *sk)
23482348
#define MPTCP_CF_PUSH BIT(1)
23492349
#define MPTCP_CF_FASTCLOSE BIT(2)
23502350

2351+
/* be sure to send a reset only if the caller asked for it, also
2352+
* clean completely the subflow status when the subflow reaches
2353+
* TCP_CLOSE state
2354+
*/
2355+
static void __mptcp_subflow_disconnect(struct sock *ssk,
2356+
struct mptcp_subflow_context *subflow,
2357+
unsigned int flags)
2358+
{
2359+
if (((1 << ssk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) ||
2360+
(flags & MPTCP_CF_FASTCLOSE)) {
2361+
/* The MPTCP code never wait on the subflow sockets, TCP-level
2362+
* disconnect should never fail
2363+
*/
2364+
WARN_ON_ONCE(tcp_disconnect(ssk, 0));
2365+
mptcp_subflow_ctx_reset(subflow);
2366+
} else {
2367+
tcp_shutdown(ssk, SEND_SHUTDOWN);
2368+
}
2369+
}
2370+
23512371
/* subflow sockets can be either outgoing (connect) or incoming
23522372
* (accept).
23532373
*
@@ -2385,7 +2405,7 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
23852405
lock_sock_nested(ssk, SINGLE_DEPTH_NESTING);
23862406

23872407
if ((flags & MPTCP_CF_FASTCLOSE) && !__mptcp_check_fallback(msk)) {
2388-
/* be sure to force the tcp_disconnect() path,
2408+
/* be sure to force the tcp_close path
23892409
* to generate the egress reset
23902410
*/
23912411
ssk->sk_lingertime = 0;
@@ -2395,11 +2415,7 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
23952415

23962416
need_push = (flags & MPTCP_CF_PUSH) && __mptcp_retransmit_pending_data(sk);
23972417
if (!dispose_it) {
2398-
/* The MPTCP code never wait on the subflow sockets, TCP-level
2399-
* disconnect should never fail
2400-
*/
2401-
WARN_ON_ONCE(tcp_disconnect(ssk, 0));
2402-
mptcp_subflow_ctx_reset(subflow);
2418+
__mptcp_subflow_disconnect(ssk, subflow, flags);
24032419
release_sock(ssk);
24042420

24052421
goto out;

0 commit comments

Comments
 (0)