Skip to content

Commit 2b1f48c

Browse files
committed
Merge branch 'mptcp-pm-misc-fixes-for-v7-1-rc3'
Matthieu Baerts says: ==================== mptcp: pm: misc. fixes for v7.1-rc3 Here are various fixes, mainly related to ADD_ADDRs: - Patch 1: save ADD_ADDR for rtx with ID0 when needed. A fix for v6.1. - Patch 2: remove unneeded exception for ID 0. A fix for v5.10. - Patches 3-5: fix potential data-race and leaks during ADD_ADDR rtx. A fix for v5.10. - Patch 6: resched blocked ADD_ADDR rtx after a more appropriated timeout, not after 15 seconds. A fix for v5.10. - Patch 7: skip inactive subflows when when looking at the max RTO. A fix for v6.18. - Patch 8: avoid iterating over all subflows when there is no need to. A fix for v6.18. - Patch 9: skip closed subflows when looking at sending MP_PRIO. A fix for v5.17. - Patch 10: properly catch errors when using check_output() in the selftests. A fix for v6.9. - Patch 11: skip the 'unknown' flag test when 'ip mptcp' is used. A fix for v6.10. ==================== Link: https://patch.msgid.link/20260505-net-mptcp-pm-fixes-7-1-rc3-v1-0-fca8091060a4@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents c8f7244 + 53705dd commit 2b1f48c

4 files changed

Lines changed: 73 additions & 38 deletions

File tree

net/mptcp/pm.c

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ struct mptcp_pm_add_entry {
1616
struct list_head list;
1717
struct mptcp_addr_info addr;
1818
u8 retrans_times;
19+
bool timer_done;
1920
struct timer_list add_timer;
2021
struct mptcp_sock *sock;
2122
struct rcu_head rcu;
@@ -283,6 +284,9 @@ int mptcp_pm_mp_prio_send_ack(struct mptcp_sock *msk,
283284
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
284285
struct mptcp_addr_info local, remote;
285286

287+
if (!__mptcp_subflow_active(subflow))
288+
continue;
289+
286290
mptcp_local_address((struct sock_common *)ssk, &local);
287291
if (!mptcp_addresses_equal(&local, addr, addr->port))
288292
continue;
@@ -305,18 +309,31 @@ static unsigned int mptcp_adjust_add_addr_timeout(struct mptcp_sock *msk)
305309
const struct net *net = sock_net((struct sock *)msk);
306310
unsigned int rto = mptcp_get_add_addr_timeout(net);
307311
struct mptcp_subflow_context *subflow;
308-
unsigned int max = 0;
312+
unsigned int max = 0, max_stale = 0;
313+
314+
if (!rto)
315+
return 0;
309316

310317
mptcp_for_each_subflow(msk, subflow) {
311318
struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
312319
struct inet_connection_sock *icsk = inet_csk(ssk);
313320

314-
if (icsk->icsk_rto > max)
321+
if (!__mptcp_subflow_active(subflow))
322+
continue;
323+
324+
if (unlikely(subflow->stale)) {
325+
if (icsk->icsk_rto > max_stale)
326+
max_stale = icsk->icsk_rto;
327+
} else if (icsk->icsk_rto > max) {
315328
max = icsk->icsk_rto;
329+
}
316330
}
317331

318-
if (max && max < rto)
319-
rto = max;
332+
if (max)
333+
return min(max, rto);
334+
335+
if (max_stale)
336+
return min(max_stale, rto);
320337

321338
return rto;
322339
}
@@ -327,26 +344,22 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
327344
add_timer);
328345
struct mptcp_sock *msk = entry->sock;
329346
struct sock *sk = (struct sock *)msk;
330-
unsigned int timeout;
347+
unsigned int timeout = 0;
331348

332349
pr_debug("msk=%p\n", msk);
333350

334-
if (!msk)
335-
return;
336-
337-
if (inet_sk_state_load(sk) == TCP_CLOSE)
338-
return;
339-
340-
if (!entry->addr.id)
341-
return;
351+
bh_lock_sock(sk);
352+
if (unlikely(inet_sk_state_load(sk) == TCP_CLOSE))
353+
goto out;
342354

343-
if (mptcp_pm_should_add_signal_addr(msk)) {
344-
sk_reset_timer(sk, timer, jiffies + TCP_RTO_MAX / 8);
355+
if (sock_owned_by_user(sk)) {
356+
/* Try again later. */
357+
timeout = HZ / 20;
345358
goto out;
346359
}
347360

348361
timeout = mptcp_adjust_add_addr_timeout(msk);
349-
if (!timeout)
362+
if (!timeout || mptcp_pm_should_add_signal_addr(msk))
350363
goto out;
351364

352365
spin_lock_bh(&msk->pm.lock);
@@ -359,16 +372,23 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
359372
}
360373

361374
if (entry->retrans_times < ADD_ADDR_RETRANS_MAX)
362-
sk_reset_timer(sk, timer,
363-
jiffies + (timeout << entry->retrans_times));
375+
timeout <<= entry->retrans_times;
376+
else
377+
timeout = 0;
364378

365379
spin_unlock_bh(&msk->pm.lock);
366380

367381
if (entry->retrans_times == ADD_ADDR_RETRANS_MAX)
368382
mptcp_pm_subflow_established(msk);
369383

370384
out:
371-
__sock_put(sk);
385+
if (timeout)
386+
sk_reset_timer(sk, timer, jiffies + timeout);
387+
else
388+
/* if sock_put calls sk_free: avoid waiting for this timer */
389+
entry->timer_done = true;
390+
bh_unlock_sock(sk);
391+
sock_put(sk);
372392
}
373393

374394
struct mptcp_pm_add_entry *
@@ -431,6 +451,7 @@ bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk,
431451

432452
timer_setup(&add_entry->add_timer, mptcp_pm_add_timer, 0);
433453
reset_timer:
454+
add_entry->timer_done = false;
434455
timeout = mptcp_adjust_add_addr_timeout(msk);
435456
if (timeout)
436457
sk_reset_timer(sk, &add_entry->add_timer, jiffies + timeout);
@@ -451,7 +472,8 @@ static void mptcp_pm_free_anno_list(struct mptcp_sock *msk)
451472
spin_unlock_bh(&msk->pm.lock);
452473

453474
list_for_each_entry_safe(entry, tmp, &free_list, list) {
454-
sk_stop_timer_sync(sk, &entry->add_timer);
475+
if (!entry->timer_done)
476+
sk_stop_timer_sync(sk, &entry->add_timer);
455477
kfree_rcu(entry, rcu);
456478
}
457479
}

net/mptcp/pm_kernel.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,8 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
347347

348348
/* check first for announce */
349349
if (msk->pm.add_addr_signaled < endp_signal_max) {
350+
u8 endp_id;
351+
350352
/* due to racing events on both ends we can reach here while
351353
* previous add address is still running: if we invoke now
352354
* mptcp_pm_announce_addr(), that will fail and the
@@ -360,19 +362,20 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk)
360362
if (!select_signal_address(pernet, msk, &local))
361363
goto subflow;
362364

365+
/* Special case for ID0: set the correct ID */
366+
endp_id = local.addr.id;
367+
if (endp_id == msk->mpc_endpoint_id)
368+
local.addr.id = 0;
369+
363370
/* If the alloc fails, we are on memory pressure, not worth
364371
* continuing, and trying to create subflows.
365372
*/
366373
if (!mptcp_pm_alloc_anno_list(msk, &local.addr))
367374
return;
368375

369-
__clear_bit(local.addr.id, msk->pm.id_avail_bitmap);
376+
__clear_bit(endp_id, msk->pm.id_avail_bitmap);
370377
msk->pm.add_addr_signaled++;
371378

372-
/* Special case for ID0: set the correct ID */
373-
if (local.addr.id == msk->mpc_endpoint_id)
374-
local.addr.id = 0;
375-
376379
mptcp_pm_announce_addr(msk, &local.addr, false);
377380
mptcp_pm_addr_send_ack(msk);
378381

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

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -474,20 +474,24 @@ mptcp_lib_wait_local_port_listen() {
474474
wait_local_port_listen "${@}" "tcp"
475475
}
476476

477+
# $1: error file, $2: cmd, $3: expected msg, [$4: expected error]
477478
mptcp_lib_check_output() {
478479
local err="${1}"
479480
local cmd="${2}"
480481
local expected="${3}"
482+
local exp_error="${4:-0}"
481483
local cmd_ret=0
482484
local out
483485

484-
if ! out=$(${cmd} 2>"${err}"); then
485-
cmd_ret=${?}
486-
fi
486+
out=$(${cmd} 2>"${err}") || cmd_ret=1
487487

488-
if [ ${cmd_ret} -ne 0 ]; then
489-
mptcp_lib_pr_fail "command execution '${cmd}' stderr"
490-
cat "${err}"
488+
if [ "${cmd_ret}" != "${exp_error}" ]; then
489+
mptcp_lib_pr_fail "unexpected returned code for '${cmd}', info:"
490+
if [ "${exp_error}" = 0 ]; then
491+
cat "${err}"
492+
else
493+
echo "${out}"
494+
fi
491495
return 2
492496
elif [ "${out}" = "${expected}" ]; then
493497
return 0

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

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,12 @@ check()
122122
local cmd="$1"
123123
local expected="$2"
124124
local msg="$3"
125+
local exp_error="$4"
125126
local rc=0
126127

127128
mptcp_lib_print_title "$msg"
128-
mptcp_lib_check_output "${err}" "${cmd}" "${expected}" || rc=${?}
129+
mptcp_lib_check_output "${err}" "${cmd}" "${expected}" "${exp_error}" ||
130+
rc=${?}
129131
if [ ${rc} -eq 2 ]; then
130132
mptcp_lib_result_fail "${msg} # error ${rc}"
131133
ret=${KSFT_FAIL}
@@ -158,13 +160,13 @@ check "show_endpoints" \
158160
"3,10.0.1.3,signal backup")" "dump addrs"
159161

160162
del_endpoint 2
161-
check "get_endpoint 2" "" "simple del addr"
163+
check "get_endpoint 2" "" "simple del addr" 1
162164
check "show_endpoints" \
163165
"$(format_endpoints "1,10.0.1.1" \
164166
"3,10.0.1.3,signal backup")" "dump addrs after del"
165167

166168
add_endpoint 10.0.1.3 2>/dev/null
167-
check "get_endpoint 4" "" "duplicate addr"
169+
check "get_endpoint 4" "" "duplicate addr" 1
168170

169171
add_endpoint 10.0.1.4 flags signal
170172
check "get_endpoint 4" "$(format_endpoints "4,10.0.1.4,signal")" "id addr increment"
@@ -173,7 +175,7 @@ for i in $(seq 5 9); do
173175
add_endpoint "10.0.1.${i}" flags signal >/dev/null 2>&1
174176
done
175177
check "get_endpoint 9" "$(format_endpoints "9,10.0.1.9,signal")" "hard addr limit"
176-
check "get_endpoint 10" "" "above hard addr limit"
178+
check "get_endpoint 10" "" "above hard addr limit" 1
177179

178180
del_endpoint 9
179181
for i in $(seq 10 255); do
@@ -192,9 +194,13 @@ check "show_endpoints" \
192194
flush_endpoint
193195
check "show_endpoints" "" "flush addrs"
194196

195-
add_endpoint 10.0.1.1 flags unknown
196-
check "show_endpoints" "$(format_endpoints "1,10.0.1.1")" "ignore unknown flags"
197-
flush_endpoint
197+
# "unknown" flag is only supported by pm_nl_ctl
198+
if ! mptcp_lib_is_ip_mptcp; then
199+
add_endpoint 10.0.1.1 flags unknown
200+
check "show_endpoints" "$(format_endpoints "1,10.0.1.1")" \
201+
"ignore unknown flags"
202+
flush_endpoint
203+
fi
198204

199205
set_limits 9 1 2>/dev/null
200206
check "get_limits" "${default_limits}" "rcv addrs above hard limit"

0 commit comments

Comments
 (0)