Skip to content

Commit 1c1f14f

Browse files
committed
Merge branch 'mptcp-fixes-for-v6-6'
Mat Martineau says: ==================== mptcp: Fixes for v6.6 Patch 1 corrects the logic for MP_JOIN tests where 0 RSTs are expected. Patch 2 ensures MPTCP packets are not incorrectly coalesced in the TCP backlog queue. Patch 3 avoids a zero-window probe and associated WARN_ON_ONCE() in an expected MPTCP reinjection scenario. Patches 4 & 5 allow an initial MPTCP subflow to be closed cleanly instead of always sending RST. Associated selftest is updated. ==================== Link: https://lore.kernel.org/r/20231018-send-net-20231018-v1-0-17ecb002e41d@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents 389db4f + 2cfaa8b commit 1c1f14f

File tree

3 files changed

+43
-15
lines changed

3 files changed

+43
-15
lines changed

net/ipv4/tcp_ipv4.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1869,6 +1869,7 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb,
18691869
#ifdef CONFIG_TLS_DEVICE
18701870
tail->decrypted != skb->decrypted ||
18711871
#endif
1872+
!mptcp_skb_can_collapse(tail, skb) ||
18721873
thtail->doff != th->doff ||
18731874
memcmp(thtail + 1, th + 1, hdrlen - sizeof(*th)))
18741875
goto no_coalesce;

net/mptcp/protocol.c

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,19 +1298,14 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
12981298
if (copy == 0) {
12991299
u64 snd_una = READ_ONCE(msk->snd_una);
13001300

1301-
if (snd_una != msk->snd_nxt) {
1301+
if (snd_una != msk->snd_nxt || tcp_write_queue_tail(ssk)) {
13021302
tcp_remove_empty_skb(ssk);
13031303
return 0;
13041304
}
13051305

13061306
zero_window_probe = true;
13071307
data_seq = snd_una - 1;
13081308
copy = 1;
1309-
1310-
/* all mptcp-level data is acked, no skbs should be present into the
1311-
* ssk write queue
1312-
*/
1313-
WARN_ON_ONCE(reuse_skb);
13141309
}
13151310

13161311
copy = min_t(size_t, copy, info->limit - info->sent);
@@ -1339,7 +1334,6 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
13391334
if (reuse_skb) {
13401335
TCP_SKB_CB(skb)->tcp_flags &= ~TCPHDR_PSH;
13411336
mpext->data_len += copy;
1342-
WARN_ON_ONCE(zero_window_probe);
13431337
goto out;
13441338
}
13451339

@@ -2354,6 +2348,26 @@ bool __mptcp_retransmit_pending_data(struct sock *sk)
23542348
#define MPTCP_CF_PUSH BIT(1)
23552349
#define MPTCP_CF_FASTCLOSE BIT(2)
23562350

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+
23572371
/* subflow sockets can be either outgoing (connect) or incoming
23582372
* (accept).
23592373
*
@@ -2391,7 +2405,7 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
23912405
lock_sock_nested(ssk, SINGLE_DEPTH_NESTING);
23922406

23932407
if ((flags & MPTCP_CF_FASTCLOSE) && !__mptcp_check_fallback(msk)) {
2394-
/* be sure to force the tcp_disconnect() path,
2408+
/* be sure to force the tcp_close path
23952409
* to generate the egress reset
23962410
*/
23972411
ssk->sk_lingertime = 0;
@@ -2401,11 +2415,7 @@ static void __mptcp_close_ssk(struct sock *sk, struct sock *ssk,
24012415

24022416
need_push = (flags & MPTCP_CF_PUSH) && __mptcp_retransmit_pending_data(sk);
24032417
if (!dispose_it) {
2404-
/* The MPTCP code never wait on the subflow sockets, TCP-level
2405-
* disconnect should never fail
2406-
*/
2407-
WARN_ON_ONCE(tcp_disconnect(ssk, 0));
2408-
mptcp_subflow_ctx_reset(subflow);
2418+
__mptcp_subflow_disconnect(ssk, subflow, flags);
24092419
release_sock(ssk);
24102420

24112421
goto out;

tools/testing/selftests/net/mptcp/mptcp_join.sh

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1432,7 +1432,9 @@ chk_rst_nr()
14321432
count=$(get_counter ${ns_tx} "MPTcpExtMPRstTx")
14331433
if [ -z "$count" ]; then
14341434
print_skip
1435-
elif [ $count -lt $rst_tx ]; then
1435+
# accept more rst than expected except if we don't expect any
1436+
elif { [ $rst_tx -ne 0 ] && [ $count -lt $rst_tx ]; } ||
1437+
{ [ $rst_tx -eq 0 ] && [ $count -ne 0 ]; }; then
14361438
fail_test "got $count MP_RST[s] TX expected $rst_tx"
14371439
else
14381440
print_ok
@@ -1442,7 +1444,9 @@ chk_rst_nr()
14421444
count=$(get_counter ${ns_rx} "MPTcpExtMPRstRx")
14431445
if [ -z "$count" ]; then
14441446
print_skip
1445-
elif [ "$count" -lt "$rst_rx" ]; then
1447+
# accept more rst than expected except if we don't expect any
1448+
elif { [ $rst_rx -ne 0 ] && [ $count -lt $rst_rx ]; } ||
1449+
{ [ $rst_rx -eq 0 ] && [ $count -ne 0 ]; }; then
14461450
fail_test "got $count MP_RST[s] RX expected $rst_rx"
14471451
else
14481452
print_ok
@@ -2305,6 +2309,7 @@ remove_tests()
23052309
chk_join_nr 1 1 1
23062310
chk_rm_tx_nr 1
23072311
chk_rm_nr 1 1
2312+
chk_rst_nr 0 0
23082313
fi
23092314

23102315
# multiple subflows, remove
@@ -2317,6 +2322,7 @@ remove_tests()
23172322
run_tests $ns1 $ns2 10.0.1.1
23182323
chk_join_nr 2 2 2
23192324
chk_rm_nr 2 2
2325+
chk_rst_nr 0 0
23202326
fi
23212327

23222328
# single address, remove
@@ -2329,6 +2335,7 @@ remove_tests()
23292335
chk_join_nr 1 1 1
23302336
chk_add_nr 1 1
23312337
chk_rm_nr 1 1 invert
2338+
chk_rst_nr 0 0
23322339
fi
23332340

23342341
# subflow and signal, remove
@@ -2342,6 +2349,7 @@ remove_tests()
23422349
chk_join_nr 2 2 2
23432350
chk_add_nr 1 1
23442351
chk_rm_nr 1 1
2352+
chk_rst_nr 0 0
23452353
fi
23462354

23472355
# subflows and signal, remove
@@ -2356,6 +2364,7 @@ remove_tests()
23562364
chk_join_nr 3 3 3
23572365
chk_add_nr 1 1
23582366
chk_rm_nr 2 2
2367+
chk_rst_nr 0 0
23592368
fi
23602369

23612370
# addresses remove
@@ -2370,6 +2379,7 @@ remove_tests()
23702379
chk_join_nr 3 3 3
23712380
chk_add_nr 3 3
23722381
chk_rm_nr 3 3 invert
2382+
chk_rst_nr 0 0
23732383
fi
23742384

23752385
# invalid addresses remove
@@ -2384,6 +2394,7 @@ remove_tests()
23842394
chk_join_nr 1 1 1
23852395
chk_add_nr 3 3
23862396
chk_rm_nr 3 1 invert
2397+
chk_rst_nr 0 0
23872398
fi
23882399

23892400
# subflows and signal, flush
@@ -2398,6 +2409,7 @@ remove_tests()
23982409
chk_join_nr 3 3 3
23992410
chk_add_nr 1 1
24002411
chk_rm_nr 1 3 invert simult
2412+
chk_rst_nr 0 0
24012413
fi
24022414

24032415
# subflows flush
@@ -2417,6 +2429,7 @@ remove_tests()
24172429
else
24182430
chk_rm_nr 3 3
24192431
fi
2432+
chk_rst_nr 0 0
24202433
fi
24212434

24222435
# addresses flush
@@ -2431,6 +2444,7 @@ remove_tests()
24312444
chk_join_nr 3 3 3
24322445
chk_add_nr 3 3
24332446
chk_rm_nr 3 3 invert simult
2447+
chk_rst_nr 0 0
24342448
fi
24352449

24362450
# invalid addresses flush
@@ -2445,6 +2459,7 @@ remove_tests()
24452459
chk_join_nr 1 1 1
24462460
chk_add_nr 3 3
24472461
chk_rm_nr 3 1 invert
2462+
chk_rst_nr 0 0
24482463
fi
24492464

24502465
# remove id 0 subflow
@@ -2456,6 +2471,7 @@ remove_tests()
24562471
run_tests $ns1 $ns2 10.0.1.1
24572472
chk_join_nr 1 1 1
24582473
chk_rm_nr 1 1
2474+
chk_rst_nr 0 0
24592475
fi
24602476

24612477
# remove id 0 address
@@ -2468,6 +2484,7 @@ remove_tests()
24682484
chk_join_nr 1 1 1
24692485
chk_add_nr 1 1
24702486
chk_rm_nr 1 1 invert
2487+
chk_rst_nr 0 0 invert
24712488
fi
24722489
}
24732490

0 commit comments

Comments
 (0)