Skip to content

Commit 3980cf1

Browse files
committed
Merge branch 'mptcp-more-misc-fixes-for-v6-8'
Matthieu Baerts says: ==================== mptcp: more misc. fixes for v6.8 This series includes 6 types of fixes: - Patch 1 fixes v4 mapped in v6 addresses support for the userspace PM, when asking to delete a subflow. It was done everywhere else, but not there. Patch 2 validates the modification, thanks to a subtest in mptcp_join.sh. These patches can be backported up to v5.19. - Patch 3 is a small fix for a recent bug-fix patch, just to avoid printing an irrelevant warning (pr_warn()) once. It can be backported up to v5.6, alongside the bug-fix that has been introduced in the v6.8-rc5. - Patches 4 to 6 are fixes for bugs found by Paolo while working on TCP_NOTSENT_LOWAT support for MPTCP. These fixes can improve the performances in some cases. Patches can be backported up to v5.6, v5.11 and v6.7 respectively. - Patch 7 makes sure 'ss -M' is available when starting MPTCP Join selftest as it is required for some subtests since v5.18. - Patch 8 fixes a possible double-free on socket dismantle. The issue always existed, but was unnoticed because it was not causing any problem so far. This fix can be backported up to v5.6. - Patch 9 is a fix for a very recent patch causing lockdep warnings in subflow diag. The patch causing the regression -- which fixes another issue present since v5.7 -- should be part of the future v6.8-rc6. Patch 10 validates the modification, thanks to a new subtest in diag.sh. ==================== Link: https://lore.kernel.org/r/20240223-upstream-net-20240223-misc-fixes-v1-0-162e87e48497@kernel.org Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 0d60d8d + b4b51d3 commit 3980cf1

File tree

8 files changed

+128
-27
lines changed

8 files changed

+128
-27
lines changed

net/mptcp/diag.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ static int subflow_get_info(struct sock *sk, struct sk_buff *skb)
2121
bool slow;
2222
int err;
2323

24+
if (inet_sk_state_load(sk) == TCP_LISTEN)
25+
return 0;
26+
2427
start = nla_nest_start_noflag(skb, INET_ULP_INFO_MPTCP);
2528
if (!start)
2629
return -EMSGSIZE;

net/mptcp/options.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -981,10 +981,10 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk,
981981
if (mp_opt->deny_join_id0)
982982
WRITE_ONCE(msk->pm.remote_deny_join_id0, true);
983983

984-
set_fully_established:
985984
if (unlikely(!READ_ONCE(msk->pm.server_side)))
986985
pr_warn_once("bogus mpc option on established client sk");
987986

987+
set_fully_established:
988988
mptcp_data_lock((struct sock *)msk);
989989
__mptcp_subflow_fully_established(msk, subflow, mp_opt);
990990
mptcp_data_unlock((struct sock *)msk);

net/mptcp/pm_userspace.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,16 @@ int mptcp_pm_nl_subflow_destroy_doit(struct sk_buff *skb, struct genl_info *info
495495
goto destroy_err;
496496
}
497497

498+
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
499+
if (addr_l.family == AF_INET && ipv6_addr_v4mapped(&addr_r.addr6)) {
500+
ipv6_addr_set_v4mapped(addr_l.addr.s_addr, &addr_l.addr6);
501+
addr_l.family = AF_INET6;
502+
}
503+
if (addr_r.family == AF_INET && ipv6_addr_v4mapped(&addr_l.addr6)) {
504+
ipv6_addr_set_v4mapped(addr_r.addr.s_addr, &addr_r.addr6);
505+
addr_r.family = AF_INET6;
506+
}
507+
#endif
498508
if (addr_l.family != addr_r.family) {
499509
GENL_SET_ERR_MSG(info, "address families do not match");
500510
err = -EINVAL;

net/mptcp/protocol.c

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1260,6 +1260,7 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
12601260
mpext = mptcp_get_ext(skb);
12611261
if (!mptcp_skb_can_collapse_to(data_seq, skb, mpext)) {
12621262
TCP_SKB_CB(skb)->eor = 1;
1263+
tcp_mark_push(tcp_sk(ssk), skb);
12631264
goto alloc_skb;
12641265
}
12651266

@@ -3177,8 +3178,50 @@ static struct ipv6_pinfo *mptcp_inet6_sk(const struct sock *sk)
31773178

31783179
return (struct ipv6_pinfo *)(((u8 *)sk) + offset);
31793180
}
3181+
3182+
static void mptcp_copy_ip6_options(struct sock *newsk, const struct sock *sk)
3183+
{
3184+
const struct ipv6_pinfo *np = inet6_sk(sk);
3185+
struct ipv6_txoptions *opt;
3186+
struct ipv6_pinfo *newnp;
3187+
3188+
newnp = inet6_sk(newsk);
3189+
3190+
rcu_read_lock();
3191+
opt = rcu_dereference(np->opt);
3192+
if (opt) {
3193+
opt = ipv6_dup_options(newsk, opt);
3194+
if (!opt)
3195+
net_warn_ratelimited("%s: Failed to copy ip6 options\n", __func__);
3196+
}
3197+
RCU_INIT_POINTER(newnp->opt, opt);
3198+
rcu_read_unlock();
3199+
}
31803200
#endif
31813201

3202+
static void mptcp_copy_ip_options(struct sock *newsk, const struct sock *sk)
3203+
{
3204+
struct ip_options_rcu *inet_opt, *newopt = NULL;
3205+
const struct inet_sock *inet = inet_sk(sk);
3206+
struct inet_sock *newinet;
3207+
3208+
newinet = inet_sk(newsk);
3209+
3210+
rcu_read_lock();
3211+
inet_opt = rcu_dereference(inet->inet_opt);
3212+
if (inet_opt) {
3213+
newopt = sock_kmalloc(newsk, sizeof(*inet_opt) +
3214+
inet_opt->opt.optlen, GFP_ATOMIC);
3215+
if (newopt)
3216+
memcpy(newopt, inet_opt, sizeof(*inet_opt) +
3217+
inet_opt->opt.optlen);
3218+
else
3219+
net_warn_ratelimited("%s: Failed to copy ip options\n", __func__);
3220+
}
3221+
RCU_INIT_POINTER(newinet->inet_opt, newopt);
3222+
rcu_read_unlock();
3223+
}
3224+
31823225
struct sock *mptcp_sk_clone_init(const struct sock *sk,
31833226
const struct mptcp_options_received *mp_opt,
31843227
struct sock *ssk,
@@ -3199,6 +3242,13 @@ struct sock *mptcp_sk_clone_init(const struct sock *sk,
31993242

32003243
__mptcp_init_sock(nsk);
32013244

3245+
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
3246+
if (nsk->sk_family == AF_INET6)
3247+
mptcp_copy_ip6_options(nsk, sk);
3248+
else
3249+
#endif
3250+
mptcp_copy_ip_options(nsk, sk);
3251+
32023252
msk = mptcp_sk(nsk);
32033253
msk->local_key = subflow_req->local_key;
32043254
msk->token = subflow_req->token;
@@ -3210,7 +3260,7 @@ struct sock *mptcp_sk_clone_init(const struct sock *sk,
32103260
msk->write_seq = subflow_req->idsn + 1;
32113261
msk->snd_nxt = msk->write_seq;
32123262
msk->snd_una = msk->write_seq;
3213-
msk->wnd_end = msk->snd_nxt + req->rsk_rcv_wnd;
3263+
msk->wnd_end = msk->snd_nxt + tcp_sk(ssk)->snd_wnd;
32143264
msk->setsockopt_seq = mptcp_sk(sk)->setsockopt_seq;
32153265
mptcp_init_sched(msk, mptcp_sk(sk)->sched);
32163266

net/mptcp/protocol.h

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,16 @@ static inline bool mptcp_data_fin_enabled(const struct mptcp_sock *msk)
790790
READ_ONCE(msk->write_seq) == READ_ONCE(msk->snd_nxt);
791791
}
792792

793+
static inline void mptcp_write_space(struct sock *sk)
794+
{
795+
if (sk_stream_is_writeable(sk)) {
796+
/* pairs with memory barrier in mptcp_poll */
797+
smp_mb();
798+
if (test_and_clear_bit(MPTCP_NOSPACE, &mptcp_sk(sk)->flags))
799+
sk_stream_write_space(sk);
800+
}
801+
}
802+
793803
static inline void __mptcp_sync_sndbuf(struct sock *sk)
794804
{
795805
struct mptcp_subflow_context *subflow;
@@ -808,6 +818,7 @@ static inline void __mptcp_sync_sndbuf(struct sock *sk)
808818

809819
/* the msk max wmem limit is <nr_subflows> * tcp wmem[2] */
810820
WRITE_ONCE(sk->sk_sndbuf, new_sndbuf);
821+
mptcp_write_space(sk);
811822
}
812823

813824
/* The called held both the msk socket and the subflow socket locks,
@@ -838,16 +849,6 @@ static inline void mptcp_propagate_sndbuf(struct sock *sk, struct sock *ssk)
838849
local_bh_enable();
839850
}
840851

841-
static inline void mptcp_write_space(struct sock *sk)
842-
{
843-
if (sk_stream_is_writeable(sk)) {
844-
/* pairs with memory barrier in mptcp_poll */
845-
smp_mb();
846-
if (test_and_clear_bit(MPTCP_NOSPACE, &mptcp_sk(sk)->flags))
847-
sk_stream_write_space(sk);
848-
}
849-
}
850-
851852
void mptcp_destroy_common(struct mptcp_sock *msk, unsigned int flags);
852853

853854
#define MPTCP_TOKEN_MAX_RETRIES 4

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

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ flush_pids()
2020

2121
ip netns pids "${ns}" | xargs --no-run-if-empty kill -SIGUSR1 &>/dev/null
2222

23-
for _ in $(seq 10); do
23+
for _ in $(seq $((timeout_poll * 10))); do
2424
[ -z "$(ip netns pids "${ns}")" ] && break
2525
sleep 0.1
2626
done
@@ -91,6 +91,15 @@ chk_msk_nr()
9191
__chk_msk_nr "grep -c token:" "$@"
9292
}
9393

94+
chk_listener_nr()
95+
{
96+
local expected=$1
97+
local msg="$2"
98+
99+
__chk_nr "ss -inmlHMON $ns | wc -l" "$expected" "$msg - mptcp" 0
100+
__chk_nr "ss -inmlHtON $ns | wc -l" "$expected" "$msg - subflows"
101+
}
102+
94103
wait_msk_nr()
95104
{
96105
local condition="grep -c token:"
@@ -289,5 +298,24 @@ flush_pids
289298
chk_msk_inuse 0 "many->0"
290299
chk_msk_cestab 0 "many->0"
291300

301+
chk_listener_nr 0 "no listener sockets"
302+
NR_SERVERS=100
303+
for I in $(seq 1 $NR_SERVERS); do
304+
ip netns exec $ns ./mptcp_connect -p $((I + 20001)) \
305+
-t ${timeout_poll} -l 0.0.0.0 >/dev/null 2>&1 &
306+
done
307+
308+
for I in $(seq 1 $NR_SERVERS); do
309+
mptcp_lib_wait_local_port_listen $ns $((I + 20001))
310+
done
311+
312+
chk_listener_nr $NR_SERVERS "many listener sockets"
313+
314+
# graceful termination
315+
for I in $(seq 1 $NR_SERVERS); do
316+
echo a | ip netns exec $ns ./mptcp_connect -p $((I + 20001)) 127.0.0.1 >/dev/null 2>&1 &
317+
done
318+
flush_pids
319+
292320
mptcp_lib_result_print_all_tap
293321
exit $ret

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

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,11 @@ check_tools()
161161
exit $ksft_skip
162162
fi
163163

164+
if ! ss -h | grep -q MPTCP; then
165+
echo "SKIP: ss tool does not support MPTCP"
166+
exit $ksft_skip
167+
fi
168+
164169
# Use the legacy version if available to support old kernel versions
165170
if iptables-legacy -V &> /dev/null; then
166171
iptables="iptables-legacy"
@@ -3333,16 +3338,17 @@ userspace_pm_rm_sf()
33333338
{
33343339
local evts=$evts_ns1
33353340
local t=${3:-1}
3336-
local ip=4
3341+
local ip
33373342
local tk da dp sp
33383343
local cnt
33393344

33403345
[ "$1" == "$ns2" ] && evts=$evts_ns2
3341-
if mptcp_lib_is_v6 $2; then ip=6; fi
3346+
[ -n "$(mptcp_lib_evts_get_info "saddr4" "$evts" $t)" ] && ip=4
3347+
[ -n "$(mptcp_lib_evts_get_info "saddr6" "$evts" $t)" ] && ip=6
33423348
tk=$(mptcp_lib_evts_get_info token "$evts")
3343-
da=$(mptcp_lib_evts_get_info "daddr$ip" "$evts" $t)
3344-
dp=$(mptcp_lib_evts_get_info dport "$evts" $t)
3345-
sp=$(mptcp_lib_evts_get_info sport "$evts" $t)
3349+
da=$(mptcp_lib_evts_get_info "daddr$ip" "$evts" $t $2)
3350+
dp=$(mptcp_lib_evts_get_info dport "$evts" $t $2)
3351+
sp=$(mptcp_lib_evts_get_info sport "$evts" $t $2)
33463352

33473353
cnt=$(rm_sf_count ${1})
33483354
ip netns exec $1 ./pm_nl_ctl dsf lip $2 lport $sp \
@@ -3429,20 +3435,23 @@ userspace_tests()
34293435
if reset_with_events "userspace pm add & remove address" &&
34303436
continue_if mptcp_lib_has_file '/proc/sys/net/mptcp/pm_type'; then
34313437
set_userspace_pm $ns1
3432-
pm_nl_set_limits $ns2 1 1
3438+
pm_nl_set_limits $ns2 2 2
34333439
speed=5 \
34343440
run_tests $ns1 $ns2 10.0.1.1 &
34353441
local tests_pid=$!
34363442
wait_mpj $ns1
34373443
userspace_pm_add_addr $ns1 10.0.2.1 10
3438-
chk_join_nr 1 1 1
3439-
chk_add_nr 1 1
3440-
chk_mptcp_info subflows 1 subflows 1
3441-
chk_subflows_total 2 2
3442-
chk_mptcp_info add_addr_signal 1 add_addr_accepted 1
3444+
userspace_pm_add_addr $ns1 10.0.3.1 20
3445+
chk_join_nr 2 2 2
3446+
chk_add_nr 2 2
3447+
chk_mptcp_info subflows 2 subflows 2
3448+
chk_subflows_total 3 3
3449+
chk_mptcp_info add_addr_signal 2 add_addr_accepted 2
34433450
userspace_pm_rm_addr $ns1 10
34443451
userspace_pm_rm_sf $ns1 "::ffff:10.0.2.1" $SUB_ESTABLISHED
3445-
chk_rm_nr 1 1 invert
3452+
userspace_pm_rm_addr $ns1 20
3453+
userspace_pm_rm_sf $ns1 10.0.3.1 $SUB_ESTABLISHED
3454+
chk_rm_nr 2 2 invert
34463455
chk_mptcp_info subflows 0 subflows 0
34473456
chk_subflows_total 1 1
34483457
kill_events_pids

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,9 +213,9 @@ mptcp_lib_get_info_value() {
213213
grep "${2}" | sed -n 's/.*\('"${1}"':\)\([0-9a-f:.]*\).*$/\2/p;q'
214214
}
215215

216-
# $1: info name ; $2: evts_ns ; $3: event type
216+
# $1: info name ; $2: evts_ns ; [$3: event type; [$4: addr]]
217217
mptcp_lib_evts_get_info() {
218-
mptcp_lib_get_info_value "${1}" "^type:${3:-1}," < "${2}"
218+
grep "${4:-}" "${2}" | mptcp_lib_get_info_value "${1}" "^type:${3:-1},"
219219
}
220220

221221
# $1: PID

0 commit comments

Comments
 (0)