summaryrefslogtreecommitdiff
path: root/net/mptcp
AgeCommit message (Collapse)Author
10 daysMerge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netPaolo Abeni
Merge in late fixes in preparation for the net-next PR. Conflicts: net/netfilter/nf_conntrack_netlink.c cd37ab22a74e0 ("netfilter: nf_conntrack_netlink: fix inverted IPv6 tuple filter") 1ae2d094b0200 ("netfilter: ctnetlink: fix inverted IPv6 address match in dump filter") Adjacent changes: drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c 8830e65ed46de ("net: use assign_bit() where applicable") 07bd391eb957 ("octeontx2-af: Fix CQ enable state tracking after AQ writes") net/core/sock.c 31c5ea8a3296 ("ipv6: Remove IPV6_ADDRFORM.") 31b564f70d88 ("net: use the full socket in sk_mc_loop()") net/mptcp/protocol.h 0cb6910130a3 ("mptcp: remove thmac from subflow ctx") 7538fa33bb2f ("mptcp: fix subflow bitfield misuse") Signed-off-by: Paolo Abeni <pabeni@redhat.com>
12 daysmptcp: options: dss: avoid printing uninit csumMatthieu Baerts (NGI0)
When parsing the DSS suboption, this pr_debug() might read and print uninitialised checksum value. That's mostly harmless, but that's also confusing. Fixing that also avoids some tools to complain about accessing uninit data. So read this csum field only if it has been set. Note: this was initially reported by Clashiko as an existing issue. The code has been analysed by a human and confirmed. This is a non-urgent fix. Fixes: 390b95a5fb84 ("mptcp: receive checksum for DSS") Reviewed-by: Mat Martineau <martineau@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20261013-net-next-mptcp-misc-feat-7-4-part2-v1-2-1181e5d2fda4@kernel.org Signed-off-by: Paolo Abeni <pabeni@redhat.com>
12 daysmptcp: options: mpc: avoid printing uninit dataMatthieu Baerts (NGI0)
When parsing the MP_CAPABLE suboption, this pr_debug() might read and print uninitialised values. That's mostly harmless, but that's also confusing. Fixing that also avoids some tools to complain about accessing uninit data. So read these fields only if they have been set. Note: this was initially reported by Clashiko as an existing issue. The code has been analysed by a human and confirmed. This is a non-urgent fix. Fixes: cc7972ea1932 ("mptcp: parse and emit MP_CAPABLE option according to v1 spec") Reviewed-by: Mat Martineau <martineau@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20261013-net-next-mptcp-misc-feat-7-4-part2-v1-1-1181e5d2fda4@kernel.org Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-10-16mptcp: fix MP_CAPABLE token migration when cloning reqskRuide Cao
TCP request migration clones pending request sockets with inet_reqsk_clone(). For MPTCP MP_CAPABLE requests this byte-copies the token_node hlist state into the clone even though the token table still names the original request, and the following warning can be seen: WARNING: net/mptcp/token.c:364 at mptcp_token_destroy_request+0x2b0/0x330, CPU#2: swapper/2/0 CPU: 2 UID: 0 PID: 0 Comm: swapper/2 Not tainted 7.2.0-rc5-00353-gc27e36054537 #10 PREEMPT(full) RIP: 0010:mptcp_token_destroy_request (net/mptcp/token.c:364 (discriminator 1)) Call Trace: <IRQ> subflow_v4_req_destructor (net/mptcp/subflow.c:694) __reqsk_free (net/ipv4/inet_connection_sock.c:906) reqsk_timer_handler (include/net/request_sock.h:137 net/ipv4/inet_connection_sock.c:1147) call_timer_fn (kernel/time/timer.c:1748) Move token request ownership from the original request to the clone under the token bucket lock. Make mptcp_token_accept() and mptcp_token_destroy_request() re-check token_node under the same lock and treat an already moved or removed request as a normal race instead of warning. This also keeps token bucket chain_len accounting balanced. If a passive MP_CAPABLE socket cannot claim the token, destroy the provisional MPTCP socket and let the subflow fall back rather than installing a socket with mismatched token ownership. Mark that path as a passive handshake fallback so MPCapableFallbackACK records the downgrade. If the speculative clone later loses the inet_ehash_insert() ownership arbitration, the original request may find that its token was already moved and fall back to plain TCP. The clone destructor then releases the token reservation and keeps chain_len balanced. This trades an exceptionally rare fallback for eliminating the warning and persistent accounting drift. Fixes: c905dee62232 ("tcp: Migrate TCP_NEW_SYN_RECV requests at retransmitting SYN+ACKs.") Cc: stable@vger.kernel.org Reported-by: Vega <vega@nebusec.ai> Reported-by: Sashiko <sashiko-bot@kernel.org> Closes: https://sashiko.dev/#/patchset/86e2514b533bf4d55d4aa2fdbf1404022e8c9430.1776149210.git.caoruide123%40gmail.com Signed-off-by: Ruide Cao <caoruide123@gmail.com> Signed-off-by: Ren Wei <weir@nebusec.ai> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20261013-net-mptcp-misc-fixes-7-3-rc8-v1-4-932c9b182fc7@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-16mptcp: hold MP_JOIN msk ref when cloning reqskRuide Cao
TCP request migration clones pending request sockets with inet_reqsk_clone(). For MPTCP MP_JOIN requests this byte-copies subflow_req->msk, but the clone does not own a reference. The original and cloned requests can consequently drop the same msk reference, leaving one request with a dangling pointer. This manifests as a KASAN slab-use-after-free in subflow_req_destructor(): BUG: KASAN: slab-use-after-free in subflow_req_destructor (net/mptcp/subflow.c:45) Write of size 4 at addr ff1100010e008d40 by task swapper/0/0 CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 7.2.0-rc5-00353-gc27e36054537 #10 PREEMPT(full) Call Trace: subflow_req_destructor (net/mptcp/subflow.c:45) subflow_v4_req_destructor (net/mptcp/subflow.c:694) __reqsk_free (net/ipv4/inet_connection_sock.c:906) reqsk_timer_handler (include/net/request_sock.h:137 net/ipv4/inet_connection_sock.c:1147) Allocated by task 10014: sk_prot_alloc (net/core/sock.c:2246) sk_clone (net/core/sock.c:2488) mptcp_sk_clone_init (include/net/sock.h:1848 net/mptcp/protocol.c:3564) subflow_syn_recv_sock (net/mptcp/subflow.c:883) tcp_check_req (net/ipv4/tcp_minisocks.c:934) Freed by task 0: slab_free_after_rcu_debug (include/linux/kasan.h:235 mm/slub.c:2677 mm/slub.c:6439) rcu_core (kernel/rcu/tree.c:2645 kernel/rcu/tree.c:2897) Last potentially related work creation: kmem_cache_free (mm/slub.c:2638 mm/slub.c:6377 mm/slub.c:6504) __sk_destruct (net/core/sock.c:2289 net/core/sock.c:2391) sk_destruct (net/core/sock.c:2419) __sk_free (net/core/sock.c:2430) sk_free (net/core/sock.c:2441) mptcp_close (include/net/sock.h:2020 net/mptcp/protocol.c:3399) inet_release (net/ipv4/af_inet.c:442) The buggy address belongs to the cache MPTCP of size 2968 The buggy address is 128 bytes inside a freed 2968-byte region A non-NULL subflow_req->msk means that the request owns one reference. The third ACK can concurrently transfer the original request reference to the child and release it, so taking an unconditional hold on the copied pointer is unsafe. MPTCP sockets use SLAB_TYPESAFE_BY_RCU and all current inet_reqsk_clone() callers run in an RCU read-side critical section. Document and lockdep-check that calling-context requirement. Read the pointer from the original request and acquire a reference only if it is still live. Use refcount_inc_not_zero_acquire() so the subsequent ownership validation cannot be reordered before the try-get, then re-read the original request to verify that it still owns the same msk. If either check fails, clear the clone pointer; otherwise its normal destructor balances the new reference. Mark the ownership-transfer store with WRITE_ONCE() to match the lockless reads. The following patch completes the clone fixup for MP_CAPABLE token ownership. Both patches carry the same Fixes tag and are required for stable backports. Fixes: c905dee62232 ("tcp: Migrate TCP_NEW_SYN_RECV requests at retransmitting SYN+ACKs.") Cc: stable@vger.kernel.org Reported-by: Kyle Zeng <kylebot@openai.com> Reported-by: David Lee <david.lee@trailofbits.com> Reported-by: Vega <vega@nebusec.ai> Closes: https://lore.kernel.org/all/20260804095051.715355-1-david.lee@trailofbits.com/ Signed-off-by: Ruide Cao <caoruide123@gmail.com> Signed-off-by: Ren Wei <weir@nebusec.ai> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20261013-net-mptcp-misc-fixes-7-3-rc8-v1-3-932c9b182fc7@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-16mptcp: fix subflow bitfield misusePaolo Abeni
The subflow status bitfield is protected by the subflow socket lock, with one notable exception: the `close_event_done` bit is actually under the msk socket lock protection. As reported by Clashiko [1], flipping the latter bit may corrupt other entries in the same bitfield. Move the `close_event_done` outside the bitfield, in a 32bit hole. Link: https://lore.kernel.org/178959153492.22033.1944011998010756543@kernel.org Fixes: d82809b6c5f2 ("mptcp: avoid duplicated SUB_CLOSED events") Cc: stable@vger.kernel.org Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20261013-net-mptcp-misc-fixes-7-3-rc8-v1-2-932c9b182fc7@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-16mptcp: reset msk state on early connect failureQuanye Yang
mptcp_connect() can fall back before the subflow SYN is sent, for example when the netns is in an MPTCP blackhole, token allocation fails, or MD5SIG is in use. If the subsequent subflow connect() fails immediately (EAFNOSUPPORT, ENETUNREACH, ...), __inet_stream_connect() returns while the socket is still SS_UNCONNECTED and never calls ->disconnect(). This was reported by Clashiko [1]. The error path only dropped the token and moved the msk back to TCP_CLOSE. MPTCP_FALLBACK_DONE, allow_subflows and request_mptcp were left as after early fallback, so a later connect() on the same fd stayed TCP-only. Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/633 [1] Fixes: 0235d075a592 ("mptcp: mark as fallback even early ones") Cc: stable@vger.kernel.org Signed-off-by: Quanye Yang <quanyeyang@proton.me> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20261013-net-mptcp-misc-fixes-7-3-rc8-v1-1-932c9b182fc7@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-05tcp: add tp->tcp_nospaceEric Dumazet
tcp_check_space() runs for every incoming ACK and for every packet we send, and reads SOCK_NOSPACE from sk->sk_socket->flags. struct socket lives in its own cache line, which the TCP fast paths do not otherwise touch, so testing sk->sk_socket->flags pulls in an extra cache line that is cold when the working set is large. Add tp->tcp_nospace, a mirror of SOCK_NOSPACE placed right after tp->chrono_type in the tcp_sock_write_tx group, in a cache line both the transmit and the ACK paths already touch (bytes_sent, data_segs_out, delivered, bytes_acked, chrono_type). It fits in an existing 3-byte hole before chrono_start, so no other field moves and sizeof(struct tcp_sock) is unchanged. The two flags are now only changed from sk_set_nospace() and sk_clear_nospace(), which maintain this invariant: SOCK_NOSPACE set => tp->tcp_nospace set sk_set_nospace() sets SOCK_NOSPACE before tp->tcp_nospace (using smp_mb__after_atomic() and smp_store_mb()), while sk_clear_nospace() clears tp->tcp_nospace before SOCK_NOSPACE (using smp_mb__before_atomic()). If a lockless sk_set_nospace() from tcp_poll() races with sk_clear_nospace() and SOCK_NOSPACE ends up set, set_bit(SOCK_NOSPACE) happened after clear_bit(SOCK_NOSPACE), so tp->tcp_nospace = 1 happens after tp->tcp_nospace = 0 as well. tcp_check_space() can thus test tp->tcp_nospace alone and leave the authoritative SOCK_NOSPACE test to __tcp_check_space(). The invariant is one directional on purpose: a stale tp->tcp_nospace only costs an extra call to __tcp_check_space(), which is what we do unconditionally today, while a stale SOCK_NOSPACE would cost a missed EPOLLOUT. Note the smp_mb() is kept. tcp_poll() sets the flag without the socket lock, and the store-buffer pattern it forms with tcp_check_space() needs a full barrier on both sides. MPTCP subflows share the struct socket of their parent, hence its SOCK_NOSPACE bit, which can not be mirrored in the subflow tcp_sock. Pin their tp->tcp_nospace in subflow_ulp_init(), so that they always reach __tcp_check_space() and keep the current behavior. Microbenchmark on an AMD EPYC 7B13, 64 threads, each thread calling tcp_check_space() in a loop over a private set of sockets. Numbers are cycles per call above a baseline loop that performs the work the callers already did (the cache lines tcp_write_xmit() and tcp_clean_rtx_queue() touched) but not tcp_check_space() itself, so they are the marginal cost of the function. Median of 11 runs. The set size controls whether struct socket is still cached: sockets/thread before after 1 +0.6 +0.7 256 (64 KB) +8.3 +3.9 4096 (1 MB) +22.4 +1.1 262144 (64 MB) +48.4 -0.8 Signed-off-by: Eric Dumazet <edumazet@kernel.org> Link: https://patch.msgid.link/20260929071743.23624-10-edumazet@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-05net: add sk_set_nospace() and sk_clear_nospace()Eric Dumazet
SOCK_NOSPACE lives in sk->sk_socket->flags and is manipulated from about thirty places in the tree, all of them open coding the sk->sk_socket dereference, some with a NULL check, some without, and some reaching the struct socket by yet another path. Add sk_set_nospace() and sk_clear_nospace() helpers and convert the core networking setters and clearers to them; the following patches convert the remaining subsystem callers so that "git grep _bit(SOCK_NOSPACE" only reports the two helpers and the remaining test_bit() sites. Callers that had no NULL check are all called from user context with a socket attached, so folding the check into the helpers only makes them more robust. No functional change intended. This is a preparation patch: a following one gives TCP a cheaper private copy of this bit, and needs a single choke point to keep it in sync. Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Signed-off-by: Eric Dumazet <edumazet@kernel.org> Link: https://patch.msgid.link/20260929071743.23624-3-edumazet@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-01mptcp: annotate lockless access to sk->sk_errQuanye Yang
sock_error() can clear sk_err with xchg() without the socket lock. On the no-data msk recv and splice paths, call sock_error() once and only stop when it returns a non-zero error. Annotate the remaining msk send and subflow error-report peeks with READ_ONCE(). Signed-off-by: Quanye Yang <quanyeyang@proton.me> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260925-mptcp-sk-err-net-v5-2-0cac04d6ea48@proton.me Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-09-29mptcp: shrink struct mptcp_options_receivedQuanye Yang
struct mptcp_options_received is allocated on the stack while parsing incoming MPTCP options. Several suboptions are mutually exclusive, as enforced by mptcp_parse_option(), so their payloads can overlap. Group fields by suboption and place the mutually exclusive payloads in an anonymous union. Keep DSS and rm_list outside the union: they can be combined with other suboptions. Move join_id into the MP_JOIN group, and overlap token, thmac and hmac inside that group. Further shrinking would require changing the parser so currently coexisting fields (DSS mapping vs ACK, rm_list, status flags) can overlap. That adds complexity for little gain, since the outer union is already dominated by the MP_JOIN / ADD_ADDR members. This reduces the structure size from 136 to 72 bytes on x86_64. Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/625 Signed-off-by: Quanye Yang <quanyeyang@proton.me> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260926-net-next-mptcp-misc-feat-7-4-v1-3-67af4ab37406@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-29mptcp: split FASTCLOSE key from rcvr_keyQuanye Yang
MP_CAPABLE and MP_FASTCLOSE both stored their key in rcvr_key. Give FASTCLOSE a dedicated fc_recv_key overlapped with rcvr_key in a union. This helps shrink struct mptcp_options_received. Signed-off-by: Quanye Yang <quanyeyang@proton.me> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260926-net-next-mptcp-misc-feat-7-4-v1-2-67af4ab37406@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-29mptcp: remove thmac from subflow ctxMatthieu Baerts (NGI0)
This entry is only used in subflow_finish_connect(). Instead, use the original value from mp_opt, and pass it to subflow_thmac_valid() to do the validation with the given truncated hmac. While at it, rename the variables in subflow_thmac_valid() to avoid confusions about the received one vs the expected one. Reviewed-by: Geliang Tang <geliang@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260926-net-next-mptcp-misc-feat-7-4-v1-1-67af4ab37406@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-17mptcp: fix bad accounting in __mptcp_subflow_push_pending()Paolo Abeni
If __subflow_push_pending() errors out we should avoid updating the copied byte counters, to avoid mismatch push call later on. Fixes: 0fa1b3783a17 ("mptcp: use get_send wrapper") Cc: stable@vger.kernel.org Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260917-net-mptcp-misc-fixes-7-3-rc4-v2-3-0cf5c72667c8@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-17mptcp: close race between scheduler and state changePaolo Abeni
The mptcp scheduler may race with subflow sockets state change: data transmission on the selected socket may fail and a later release could try to use mss_now reset to 0 for a divide operation. Address the issue by explicitly checking for the critical scenario. Fixes: c886d70286bf ("mptcp: do not queue data on closed subflows") Cc: stable@vger.kernel.org Reported-by: Shardul Bankar <shardul.b@mpiricsoftware.com> Reported-by: Xinyang Ge <xinyang@anthropic.com> Closes: https://lore.kernel.org/20260525194828.1137119-1-shardul.b@mpiricsoftware.com Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260917-net-mptcp-misc-fixes-7-3-rc4-v2-2-0cf5c72667c8@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-17mptcp: avoid unneeded actions on subflow resetPaolo Abeni
Once in a blue moon, the mptcp receive path can recursively call mptcp_data_ready() via state change under unlucky error conditions, and then try to hold the data lock again. Break the recursion loop explicitly checking for the exceptional condition. Add a new flag instead of using an existing one like 'closing', to exit early in subflow_state_change(), and explicitly flush the RX queue at reset time. This avoids unneeded processing to check for available data -- calling get_mapping_status() and more on a dying subflow -- but also in error reporting and worker scheduling. Note that we must consume the currently peeked skb before invoking mptcp_dss_corruption to avoid consuming it again after the eventual reset has freed it. Fixes: e32d262c89e2 ("mptcp: handle consistently DSS corruption") Cc: stable@vger.kernel.org Reported-by: Xinyang Ge <xinyang@anthropic.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260917-net-mptcp-misc-fixes-7-3-rc4-v2-1-0cf5c72667c8@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-16mptcp: return sk_wait_data() errors from recvmsg()Mark Amirkan
Commit 581302298524 ("mptcp: error out earlier on disconnect") made mptcp_recvmsg() stop when sk_wait_data() returns an error. The error is stored in err, but the function then jumps to a path which returns copied. When no data was copied, recvmsg() therefore returns zero and reports a false EOF. Store the result in copied, which is the value returned by the function. This also keeps the usual partial-read result when data was copied before the error. A recvmsg() blocked in one thread reproduces the issue when another thread disconnects the same MPTCP socket with connect(AF_UNSPEC). Before this change recvmsg() returns zero; afterwards it returns -EPIPE. Fixes: 581302298524 ("mptcp: error out earlier on disconnect") Cc: stable@vger.kernel.org Signed-off-by: Mark Amirkan <markdamirkan@gmail.com> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260913-b4-send-mptcp-recv-error-v1-1-4eaa3684a8b8@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-09mptcp: avoid pruning for OoW dataPaolo Abeni
Pruning is expansive and destructive, do it only when we expect to accept the skb triggering the cleanup. Fixes: e468d371180d ("mptcp: implemented OoO queue pruning") Cc: stable@vger.kernel.org Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-15-df1de70348b6@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-09mptcp: being below memory limit is a likely() conditionPaolo Abeni
The current compiler hint annotation is wrong, due to inverted logic in the previous revision of the relevant code. Fixes: e468d371180d ("mptcp: implemented OoO queue pruning") Cc: stable@vger.kernel.org Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-14-df1de70348b6@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-09mptcp: options: fix uninit-value in mptcp_write_data_finMatthieu Baerts (NGI0)
When sending a DATA_FIN without data, and because the DATA_FIN occupies 1 octet of the connection-level sequence space [1], it is then required to add a DSS mapping with specific values. If the checksum has been negotiated, it also needs to be computed, and included in the outgoing packet, and thus the initial csum data needs to be reset to 0 as well. This is no longer the case since commit cfcceb7a39fc ("tcp: shrink per-packet memset in __tcp_transmit_skb()"), because the whole ext_copy structure is no longer zeroed by default. This seems to be the only case where use_map is changed and set afterwards, so initialising the csum field only in this case, along with other fields for this specific case. Fixes: cfcceb7a39fc ("tcp: shrink per-packet memset in __tcp_transmit_skb()") Cc: stable@vger.kernel.org Link: https://datatracker.ietf.org/doc/html/rfc8684#section-3.3.3 [1] Link: https://sashiko.dev/#/patchset/20260812-net-next-mptcp-misc-feat-7-3-v1-0-1905a818f6cb%40kernel.org?part=2 Reviewed-by: Geliang Tang <geliang@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-13-df1de70348b6@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-09mptcp: remove unneeded READ_ONCE() annotationPaolo Abeni
The subflow->fully_established flag is always written under the subflow socket lock. Reading such value under the same lock does not require any ONCE annotation. Fixes: 581c8cbfa934 ("mptcp: annotate data-races around subflow->fully_established") Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-10-df1de70348b6@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-09mptcp: pm: reset retrans_time when ADD_ADDR entry is reusedMatthieu Baerts (NGI0)
When an ADD_ADDR entry is reused, the timer is re-armed, because the goal is to re-announce an ADD_ADDR, and eventually retransmit it if needed. In this case, the retransmission counter should be reset as well, so the re-announced address gets its retransmissions back instead of relying on what was left before, and possibly not being able to retransmit it. Fixes: 304ab97f4c7c ("mptcp: allow ADD_ADDR reissuance by userspace PMs") Cc: stable@vger.kernel.org Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260803-net-mptcp-misc-fixes-7-2-rc6-v2-0-b8f496d71664%40kernel.org?part=4 Reviewed-by: Mat Martineau <martineau@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-9-df1de70348b6@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-09mptcp: pm: userspace: fix address ID overflowQing Luo
When all MPTCP address IDs (1-255) are exhausted in the userspace PM, find_next_zero_bit() returns MPTCP_PM_MAX_ADDR_ID + 1 (256). This value overflows when stored in the u8 field e->addr.id, resulting in ID 0 being stored and the entry being incorrectly added to the list. ID 0 is reserved for the initial connection in MPTCP, so this overflow can cause address conflicts. Note: the in-kernel PM already has an 'endpoints == MPTCP_PM_MAX_ADDR_ID' check in mptcp_pm_nl_append_new_local_addr() that returns -ERANGE before reaching find_next_zero_bit(), preventing this overflow. So this fix only addresses the userspace PM path. Check the find_next_zero_bit() result against MPTCP_PM_MAX_ADDR_ID and return -ENOSPC if all IDs are truly exhausted. Move the ID allocation check before the memory allocation so that the error path does not need to free the allocated entry. Fixes: 4638de5aefe5 ("mptcp: handle local addrs announced by userspace PMs") Cc: stable@vger.kernel.org Signed-off-by: Qing Luo <luoqing@kylinos.cn> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-8-df1de70348b6@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-09mptcp: prevent race between disconnect() and rtxPaolo Abeni
Sashiko noted that the two event can race, leading to inconsistent status. Prevent the race using the synchronous timer stop operation. Cc: stable@vger.kernel.org Fixes: b29fcfb54cd7 ("mptcp: full disconnect implementation") Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-6-df1de70348b6@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-09mptcp: options: handle MPC data + csum reqd + no csumMatthieu Baerts (NGI0)
Before this modification, a remote peer could send an MP_CAPABLE with data, with the checksum flag set, but without adding the actual 2 bytes of checksum. As a result, uninitialised bytes could be used for the 'csum' field. That was not a critical issue, because this 'csum' field is only used to compare with the expected one, if previously negotiated in the 3WHS. Worst case, the checksum is likely wrong, a fallback is done without a reject if the negotiation was done earlier. That's OK. Yet, better to take the expected path with this case: only look at the checksum flag for MP_CAPABLEs not carrying a data-len. Such packet can be seen as a 3rd or 4th ACK. The RFC8684 mentions [1] that the 3rd packet should have the checksum flag set. When an MPC + ACK contains data, the checksum flag is redundant with the checksum field. It is not clear what should be done for the 4th ACK, nor if the flag has to be set if the checksum field is set. Therefore, it seems fine to only look at the presence of the checksum field, not to break the interaction with stacks that were not setting both. Note that linked to this checksum flag on the 3rd ACK, with the current implementation, we can have a situation where the SYN packets have no checksum flag, but the 3rd ACK has one, and this is the one that will be taken into account. First, that's clearly not directly linked to this patch, but Clashiko forced us to look at that. At the end, that seems fine to act like that: yes that's not how the negotiation should work, but being flexible without introducing side effects is also fine: fixing this would mean increasing the complexity, and that's not worth it. Fixes: 208e8f66926c ("mptcp: receive checksum for MP_CAPABLE with data") Cc: stable@vger.kernel.org Link: https://datatracker.ietf.org/doc/html/rfc8684#section-3.1-23 [1] Closes: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260803-net-mptcp-misc-fixes-7-2-rc6-v2-0-b8f496d71664%40kernel.org?part=1 Reviewed-by: Mat Martineau <martineau@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-5-df1de70348b6@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-09mptcp: pm: kernel: drop pending ADD_ADDR when removing ID0Kalpan Jani
The in-kernel MPTCP path manager can leave a stale ADD_ADDR announcement entry alive when removing the id 0 endpoint. This happens because the id 0 removal path does not tear down pending announcements, unlike the non-zero id path. When the PM later reselects id 0 after adding another signal endpoint, it finds the stale anno_list entry and hits WARN_ON_ONCE(mptcp_pm_is_kernel()) in mptcp_pm_announced_alloc(). Root cause: asymmetry between removal paths. - Non-zero id path: mptcp_nl_remove_subflow_and_signal_addr() calls mptcp_pm_remove_announced() to clean up. - Id 0 path: mptcp_nl_remove_id_zero_address() skips cleanup entirely. Fix by making the id 0 path symmetric: call mptcp_pm_announced_remove() and decrement add_addr_signaled before queuing the RM_ADDR. Subtle detail: signal endpoints are stored in anno_list with port 0, but msk_local carries the connection's local port. In other words, entries linked to ID0 paths should have port == 0. A follow-up patch will ensure that. mptcp_pm_announced_remove() uses use_port=true for comparison. So clear the port before the lookup. Fixes: 740d798e8767 ("mptcp: remove id 0 address") Cc: stable@vger.kernel.org Reported-by: syzbot+55c2a5c871441261ed14@syzkaller.appspotmail.com Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/620 Suggested-by: Tao Cui <cuitao@kylinos.cn> Signed-off-by: Kalpan Jani <kalpan.jani@mpiricsoftware.com> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-4-df1de70348b6@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-09mptcp: syncookies: remember the request backup flagMatthieu Baerts (NGI0)
Instead of using an uninitialised bit when copying the info in subflow_ulp_clone(). To fix this, no need to extend the join_entry structure: backup is coming from struct mptcp_subflow_request_sock, only one bit. Do the same here by using one bit for both. Fixes: efd340bf3d77 ("mptcp: distinguish rcv vs sent backup flag in requests") Cc: stable@vger.kernel.org Reviewed-by: Geliang Tang <geliang@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-3-df1de70348b6@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-09mptcp: subflow: no need to copy thmac during ulp_cloneMatthieu Baerts (NGI0)
'thmac' is not used after that point. Indeed, subflow_ulp_clone() is called when the request on the passive side is over, so when the truncated HMAC is no longer needed. Note that in case of SYN cookies, thmac will not be initialised. So better to remove it to avoid a warning from debug tools like KMSAN for reading uninitialised data. Fixes: f296234c98a8 ("mptcp: Add handling of incoming MP_JOIN requests") Cc: stable@vger.kernel.org Reviewed-by: Geliang Tang <geliang@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-2-df1de70348b6@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-09mptcp: do not reschedule the RTX timer for fallback socketsPaolo Abeni
On fallback socket the retrans timer is a quite convoluted no-op, but currently nothing prevents the MPTCP core to keep rescheduling it. Additionally gate RTX timer reset to the msk not being fallen back to TCP yet. To avoid adding multiple tests in fast-path, use a new flags bit for such condition. The RTX enable bit is clear at close time and set before the msk could start retransmitting, with a couple of caveats: - passive sockets inherit the bit from the listener msk; set the bit on such socket to avoid flipping it in the fast-path, even if the listener will obviously never retransmit. - while fastopening (MPTFO), mptcp_sendmsg_fastopen still ends-up calling mptcp_connect via tcp_sendmsg_fastopen -> __inet_stream_connect(ssk->sk_socket), and the first subflow's sk_socket points to the msk one. Fixes: b51f9b80c032 ("mptcp: introduce MPTCP retransmission timer") Cc: stable@vger.kernel.org Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-1-df1de70348b6@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-28tcp: use GFP_ATOMIC in tcp_send_active_reset()Eric Dumazet
tcp_send_active_reset() can be called from contexts where gfp_any() (in tcp_disconnect()) or sk->sk_allocation (in __tcp_close() and mptcp_do_fastclose()) evaluates to GFP_KERNEL, which includes __GFP_FS and __GFP_DIRECT_RECLAIM. Allocating with GFP_KERNEL while holding the socket lock (sk_lock) creates a lockdep dependency: sk_lock -> fs_reclaim This causes false-positive lockdep circular locking warnings with storage subsystems (such as nvme-tcp) that acquire socket locks in block I/O paths and invoke tcp_disconnect() or close sockets upon teardown: set->srcu -> sk_lock -> fs_reclaim -> elevator_lock -> set->srcu Active resets are small RST packet headers that should never enter direct reclaim or block while holding socket locks. Use sk_gfp_mask(sk, GFP_ATOMIC | __GFP_NOWARN) inside tcp_send_active_reset() and remove its priority argument. This preserves __GFP_MEMALLOC access for SOCK_MEMALLOC sockets, suppresses allocation failure warnings, and aligns with other control packet allocations (e.g. tcp_send_fin(), __tcp_send_ack(), tcp_xmit_probe_skb()). Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Eric Dumazet <edumazet@google.com> Acked-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260827095936.551524-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-20mptcp: fix uninitialized local_id in syncookie MP_JOIN reconstructionHarshit Varu
mptcp_token_join_cookie_init_state() restores remote_nonce, local_nonce, backup, join_id, token and msk from the saved cookie entry when rebuilding the request socket for a MP_JOIN 4th-ACK handled under SYN cookies, but it does not restore local_id, even though the SYN path saved it. subflow_ulp_clone() then reads that uninitialized field and stores it as the joined subflow's address-ID. Because the request-sock slab is SLAB_TYPESAFE_BY_RCU and not zeroed on allocation, the value is the stale byte of a previously freed request socket, which an off-path peer can influence by sending concurrent MP_JOIN SYNs. This corrupts the path manager's id-based subflow bookkeeping for the connection. Restore subflow_req->local_id from the cookie entry, as done for the other fields. Fixes: 9466a1ccebbe ("mptcp: enable JOIN requests even if cookies are in use") Cc: stable@vger.kernel.org Signed-off-by: Harshit Varu <harshitvaru666@gmail.com> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260815115205.197151-1-harshitvaru666@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-17mptcp: add per-event MIB counters for MPTCP_RST_EMPTCP resetsShardul Bankar
MPTCP_RST_EMPTCP (reset reason 1) is used as a catch-all for several distinct error conditions across subflow setup, authentication, and data-path validation. The existing MPRstTx/MPRstRx counters only track aggregate reset volume, making it difficult to diagnose which code path is triggering subflow resets in production. Add per-event MIB counters covering each MPTCP_RST_EMPTCP use site that is not already covered by an existing counter, named after the underlying event or condition rather than the reset action: MD5SigReset MD5SIG enabled on listener (incompatible) MPJoinSynAckNoMPJoin SYN/ACK missing MP_JOIN option MPJoinAckNoMPJoin server-side ACK missing MP_JOIN option (fallback path, MPJoin required) MPJoinAckNoCtx server-side ACK with no subflow context MPJoinNoIdFound MP_JOIN with a valid token but no PM local ID DssReset data mapping invalid (also fires on MAPPING_NODSS / EMIDDLEBOX path) MPJoinNotEstablished JOIN attempted on a not-fully-established msk MPJoinNoIdFound covers the second half of the no-msk MP_JOIN reset: the existing MPJoinNoTokenFound (MPTCP_MIB_JOINNOTOKEN) only counts the missing-token case in subflow_token_join_request(), while a JOIN that carries a valid token but for which the path manager returns no local id reaches the same MPTCP_RST_EMPTCP in subflow_check_req() uncounted. The aggregate MPRstTx/MPRstRx counters are unchanged. Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/511 Signed-off-by: Shardul Bankar <shardul.b@mpiricsoftware.com> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260812-net-next-mptcp-misc-feat-7-3-v1-5-1905a818f6cb@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-17mptcp: honour configured min/max RTO in retransmit pathsKalpan Jani
The MPTCP-level retransmit timers (DATA_FIN retransmissions and the fallback timeout) used the hard-coded TCP_RTO_MIN / TCP_RTO_MAX constants, ignoring the tcp_rto_min_us and tcp_rto_max_ms sysctls. Make them follow the sysctls instead: seed icsk_rto_min / icsk_rto_max on the MPTCP socket from the per-netns sysctls in __mptcp_init_sock() -- the msk does not go through tcp_init_sock(), so these fields would otherwise stay zero -- and read them directly where the constants were used: - mptcp_set_datafin_timeout(): both the backoff cap computation and the resulting timer_ival. The two sysctls are validated independently, so rto_min > rto_max is a valid configuration; keep a max_t() guard so ilog2() is never called with 0. - __mptcp_set_timeout(): the fallback when no subflow timeout is available. The icsk fields are read directly instead of using the tcp_rto_min()/tcp_rto_max() helpers: the MPTCP socket does not perform routing lookups in these paths, so the rto_min route metric checked by tcp_rto_min() can never apply here. The TCP_RTO_MIN_US / TCP_RTO_MAX_MS socket options are not supported by MPTCP setsockopt() either; this can be revisited if they get supported on MPTCP sockets. The remaining uses of TCP_RTO_MAX in net/mptcp/ctrl.c (default add_addr_timeout) and net/mptcp/subflow.c (MP_FAIL timeout) are intentionally left unchanged: they use the constant as a default duration, not as an RTO bound on a retransmit timer. Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/618 Signed-off-by: Kalpan Jani <kalpan.jani@mpiricsoftware.com> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260812-net-next-mptcp-misc-feat-7-3-v1-4-1905a818f6cb@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-17mptcp: pm: userspace: make remove_addr_entry staticMatthieu Baerts (NGI0)
Only used in pm_userspace.c. While at it, use the mptcp_userspace_pm_ prefix, like most functions in this file: that makes it clear it is specific to this userspace PM. Reviewed-by: Geliang Tang <geliang@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260812-net-next-mptcp-misc-feat-7-3-v1-3-1905a818f6cb@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-17mptcp: pm: add WARN_ON_ONCE guards on extra_subflows underflowTao Cui
extra_subflows is a u8 counter that can underflow if a decrement races with or precedes an increment. While the recently fixed userspace PM subflow creation path eliminated the primary cause, add defensive WARN_ON_ONCE guards at both decrement sites to catch any remaining edge cases rather than silently wrapping to 255. Signed-off-by: Tao Cui <cuitao@kylinos.cn> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260812-net-next-mptcp-misc-feat-7-3-v1-1-1905a818f6cb@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-11mptcp: implemented OoO queue pruningPaolo Abeni
When moving incoming skbs in the msk receive queue and the latter is above limits, prune it as needed quite alike what TCP is doing at the subflow level. The main difference relies in the stop condition: since MPTCP does not perform collapsing, it's better off dropping the bare minimum to fit the (newer) incoming packet. Signed-off-by: Paolo Abeni <pabeni@redhat.com> Tested-by: Gang Yan <yangang@kylinos.cn> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260807-net-next-mptcp-oooq-pruning-v3-7-dbc1eb853cc3@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-11mptcp: avoid code duplication in __mptcp_move_skb()Paolo Abeni
Alike TCP, MPTCP handles in-sequence packets and partially overlapping ones in a very similar way: we can use the same path to handle both, avoiding some code duplication. This will also make the next patch simpler. Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260807-net-next-mptcp-oooq-pruning-v3-6-dbc1eb853cc3@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-11mptcp: enforce hard limit on backlog flushingPaolo Abeni
Currently a wild producer could keep the backlog flushing operation spinning for an unbound time. Since the previous patch, the amount of data present in the backlog is hard-limited. Move the backlog len update at the end of the flush loop to prevent it spinning forever. Also, no need to splice back the remaining skbs list into the backlog, as such list is always empty after each backlog processing loop. Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260807-net-next-mptcp-oooq-pruning-v3-5-dbc1eb853cc3@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-11mptcp: explicitly drop over memory limitsPaolo Abeni
Currently the enforcement of the rcvbuf constraint is implemented when moving the skbs into the msk receive or OoO queue, keeping the incoming skbs in the subflow queue when over limits. Under significant memory pressure the above can cause permanent data transfer stalls, as the skb needed to make forward progress can be stuck in a subflow queue. Over memory limits, drop the incoming skb, relying on MPTCP-level retransmissions. Note that fallback socket must perform the limit before the skb reaches the subflow-level queue, as dropping an in-sequence already acked skb would break the stream. This is not a complete fix for the stall issue, as the drop strategy needs refinements that will come in the next patches. Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260807-net-next-mptcp-oooq-pruning-v3-4-dbc1eb853cc3@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-11mptcp: let the retrans scheduler do its jobPaolo Abeni
Currently the MPTCP core enforces that when MPTCP-level retrans timer fires, at most a single dfrag is retransmitted. In some corner-cases, it may be necessary to retransmit multiple dfrags, and the MPTCP socket will need to wait multiple retrans timeout to accomplish that. Remove the mentioned constraint, allowing to transmit multiple dfrags per retrans period, as long as the scheduler keeps selecting subflows for retransmissions and pending data is available in the rtx queue. The default scheduler will transmit a dfrag per available subflow. Tested-by: Gang Yan <yangang@kylinos.cn> Tested-by: Geliang Tang <geliang@kernel.org> Acked-by: Geliang Tang <geliang@kernel.org> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260807-net-next-mptcp-oooq-pruning-v3-3-dbc1eb853cc3@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-11mptcp: move the stale logic out of retrans schedulerPaolo Abeni
This allow separating the stale logic invocation and the retrans scheduler, and will simplify the next patch. It's also a cleaner design as the retrans scheduler has currently too many side effects. As a possible downside, the retrans work will now traverse the subflows list additional times; that does not matter much, as this is slowpath. While at it, pick more accurate names for the involved helpers and explicitly note that the per subflow stale data is under msk socket lock protection. The scheduler and the stale logic may observe different subflow statues, as no subflow lock is acquired. This is intentional and not harmful, worst case leading to slower retransmissions. Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260807-net-next-mptcp-oooq-pruning-v3-2-dbc1eb853cc3@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-11mptcp: move the retrans loop to a separate helperPaolo Abeni
This is a cleanup in order to make the next patch simpler. No functional change intended. Tested-by: Gang Yan <yangang@kylinos.cn> Tested-by: Geliang Tang <geliang@kernel.org> Acked-by: Geliang Tang <geliang@kernel.org> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260807-net-next-mptcp-oooq-pruning-v3-1-dbc1eb853cc3@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-06mptcp: reclaim forward-allocated memory on RX path errorsPaolo Abeni
After commit 9db5b3cec4ec ("mptcp: borrow forward memory from subflow"), errors in the receive path prior to queueing skbs into the receive queue do not trigger forward-allocated memory reclaiming. Prevent forward memory from growing unboundedly in pathological drop scenarios by explicitly reclaiming memory when skbs are dropped. Fixes: 9db5b3cec4ec ("mptcp: borrow forward memory from subflow") Cc: stable@vger.kernel.org Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260803-net-mptcp-misc-fixes-7-2-rc6-v2-8-b8f496d71664@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-06mptcp: fastopen: only mark MPTFO subflows with SYN dataWyatt Feng
Passive TCP Fast Open accepts a valid-cookie SYN even when it carries no data. In that case the child socket's receive queue is intentionally left empty. mptcp_fastopen_subflow_synack_set_params() set is_mptfo before checking for queued SYN data. That made data-less TFO SYNs hit a WARN and, if the warning was non-fatal, left stale MPTFO state behind. The stale flag could later trigger a state-confusion bug in check_fully_established(). Only mark the subflow as MPTFO after confirming that an SKB was queued. Return quietly when the receive queue is empty. Note that mptcp_subflow_context's is_mptfo field is now not just about subflows where the TFO was present, but about MPTFO subflow that consumed SYN data. Only having a valid cookie but not carrying data is not really "doing TFO". Fixes: 36b122baf6a8 ("mptcp: add subflow_v(4,6)_send_synack()") Cc: stable@vger.kernel.org Reported-by: Yuan Tan <yuantan098@gmail.com> Reported-by: Yifan Wu <yifanwucs@gmail.com> Reported-by: Juefei Pu <tomapufckgml@gmail.com> Reported-by: Zhengchuan Liang <zcliangcn@gmail.com> Reported-by: Xin Liu <bird@lzu.edu.cn> Signed-off-by: Wyatt Feng <bronzed_45_vested@icloud.com> Signed-off-by: Ren Wei <n05ec@lzu.edu.cn> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260803-net-mptcp-misc-fixes-7-2-rc6-v2-7-b8f496d71664@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-06mptcp: pm: fix memory leak from alloc-during-teardown raceShardul Bankar
mptcp_pm_destroy() empties msk->pm.anno_list and msk->pm.userspace_pm_local_addr_list under msk->pm.lock during socket teardown, dropping the lock between the two. A concurrent userspace PM genl ANNOUNCE on the same msk holds a sock reference via mptcp_token_get_sock() and, in mptcp_pm_nl_announce_doit(), calls mptcp_userspace_pm_append_new_local_addr() and mptcp_pm_announced_alloc(). Both take msk->pm.lock briefly to add to their respective lists. Because the genl handler holds a sock reference, mptcp_pm_destroy() may run on the same msk via mptcp_disconnect(), which invokes mptcp_destroy_common() without dropping the sock refcount, before the handler completes. If the lock acquisitions interleave such that mptcp_pm_destroy() empties a list first, the later alloc adds its entry to a list head that nothing else iterates for this msk, and the entry leaks. kmemleak reports both mptcp_pm_add_addr objects (from mptcp_pm_announced_alloc()) and mptcp_pm_addr_entry objects (from mptcp_userspace_pm_append_new_local_addr()) under sustained concurrent ANNOUNCE + close load against the userspace PM. Add an MPTCP_PM_DESTROYING bit in msk->pm.status, set by mptcp_pm_destroy() under pm.lock before the lists are emptied and checked under pm.lock by the alloc paths. Either the alloc takes pm.lock first, in which case its entry is on the list when mptcp_pm_destroy() frees it; or mptcp_pm_destroy() takes pm.lock first, in which case the later alloc observes the bit and refuses. Found by an MPTCP protocol-flow harness extending BRF (arXiv:2305.08782). Fixes: 9ab4807c84a4 ("mptcp: netlink: Add MPTCP_PM_CMD_ANNOUNCE") Cc: stable@vger.kernel.org Signed-off-by: Shardul Bankar <shardul.b@mpiricsoftware.com> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260803-net-mptcp-misc-fixes-7-2-rc6-v2-6-b8f496d71664@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-06mptcp: pm: fix data race in add_addr timer callbackQing Luo
The timer callback reads entry->retrans_times outside pm.lock to decide whether to call mptcp_pm_subflow_established(). Since mptcp_pm_announced_del_timer() can concurrently set retrans_times = ADD_ADDR_RETRANS_MAX under pm.lock, a race condition exists. I discovered this issue while studying the code. AI tools helped me to verify the issue can potentially happen under race conditions. Use a local 'retransmit' flag set inside pm.lock to capture whether retransmission is still possible when the lock is taken. This allows to call mptcp_pm_subflow_established() accordingly, and not depending on the situation that can be different when checked outside the pm.lock. Fixes: 348d5c1dec60 ("mptcp: move to next addr when timeout") Cc: stable@vger.kernel.org Signed-off-by: Qing Luo <luoqing@kylinos.cn> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260803-net-mptcp-misc-fixes-7-2-rc6-v2-4-b8f496d71664@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-06mptcp: remove MPC && MPJ checkMatthieu Baerts (NGI0)
After the parent commit ("mptcp: avoid combining some incoming suboptions"), the parsing step no longer allow to have both the MP_CAPABLE and MP_JOIN suboptions set together. These chunks are now unreachable, these checks can then be removed. Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260803-net-mptcp-misc-fixes-7-2-rc6-v2-3-b8f496d71664@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-06mptcp: avoid combining some incoming suboptionsMatthieu Baerts (NGI0)
Some MPTCP suboptions are mutually exclusive according to the RFC8684, but also because in different places, the code doesn't expect some combinations to be present. That's specially true for suboptions that would be present twice, but with different attributes. The new restrictions are the same as the ones applied on the output side, with mptcp_write_options. The same rules can be reused with a small fix: an MP_FASTCLOSE can be used with a DSS when the sender picks this option [1], which is not the case on Linux. Here are the rules: Which options can be used together? X: mutually exclusive O: often used together C: can be used together in some cases P: could be used together but we prefer not to (optimisations) | Opt: | MPC | MPJ | DSS | ADD | RM | PRIO | FAIL | FC | |------|------|------|------|------|------|------|------|------| | MPC |------|------|------|------|------|------|------|------| | MPJ | X |------|------|------|------|------|------|------| | DSS | X | X |------|------|------|------|------|------| | ADD | X | X | P |------|------|------|------|------| | RM | C | C | C | P |------|------|------|------| | PRIO | X | C | C | C | C |------|------|------| | FAIL | X | X | C | X | X | X |------|------| | FC | X | X | P | X | X | X | X |------| | RST | X | X | X | X | X | X | O | O | |------|------|------|------|------|------|------|------|------| The only difference is with the 'P': another stack could send and ADD_ADDR with other suboptions (DSS, RM_ADDR), and this should be allowed. A few points of attention: - In theory, an MP_CAPABLE could be used with a RM_ADDR, but there is no reason to add it with a SYN. Note that even with a 4th ACK, it doesn't seem to be useful, except when IDs are known in advance via another channel. Better not to break that. - Now, combining both an MP_CAPABLE and an MP_JOIN will no longer result to a reject of the two options, but only the second suboption is ignored. That seems OK to do that for this unexpected error. At least now all inconsistent combinations are handled the same way. This could change later in next. This also means the explicit checks for having both MPC + MPJ in subflow.c will now be unreachable. That's fine, they will be removed in a follow-up patch. - In case of conflicting combinations, the extra suboption(s) is/are ignored: having such combinations either means the remote peer is buggy, or is evil. The simplest action is then taken in this case: stop processing the current suboption. - In mp_opt->suboptions, there is also a bit reserved to the checksum, which can be used in an MP_CAPABLE and a DSS. Each time a DSS option can be used in parallel with another option, the checksum can be set, so the verification is combined into a new OPTIONS_MPTCP_DSS macro. - An MP_CAPABLE ACK can carry a Data-Level Length, and an optional Checksum: they are the same as the ones found in a DSS, because a DSS cannot be used in parallel to an MP_CAPABLE. Similarly, even if there is room, a DSS cannot be used with an MP_JOIN. Fixes: eda7acddf808 ("mptcp: Handle MPTCP TCP options") Cc: stable@vger.kernel.org Link: https://www.rfc-editor.org/rfc/rfc8684.html#section-3.5-5.1 [1] Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260803-net-mptcp-misc-fixes-7-2-rc6-v2-2-b8f496d71664@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-06mptcp: options: reset DSS fields in case of unexpected sizeMatthieu Baerts (NGI0)
A remote peer could send a malformed DSS with a wrong size, followed by another DSS or MPC + Data. In this case, the first suboption will be ignored, but leaving some fields written, which could lead to inconsistency or access uninitialized data. Explicitly reset the fields that could have been modified in case of unexpected size. Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260728-net-mptcp-misc-fixes-7-2-rc6-v1-0-f7e2d229159d%40kernel.org?part=1 Fixes: 648ef4b88673 ("mptcp: Implement MPTCP receive path") Cc: stable@vger.kernel.org Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260803-net-mptcp-misc-fixes-7-2-rc6-v2-1-b8f496d71664@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-07-23mptcp: fix BUILD_BUG_ON on legacy ARM configMatthieu Baerts (NGI0)
The 0-day bot managed to find kernel configs that cause build failures, e.g. when using the StrongARM SA1100 target (ARMv4). On such legacy ARM architecture, all structures are apparently aligned to 32 bits, causing build issue here. Indeed, on such architecture, 'flags' size is not equivalent to sizeof(u16) as expected, but to sizeof(u32). Instead, use memset(). It was not used before to ensure a simple clear operation was used by the compiler. But at the end, it shouldn't matter, and the compiler should optimise this to the same operation with or without memset() when -O above 0 is used. So let's switch to memset() to fix this issue, and reduce this complexity. Fixes: 5e939544f9d2 ("mptcp: fix uninit-value in mptcp_established_options") Cc: stable@vger.kernel.org Suggested-by: Frank Ranner <frank.ranner@intel.com> Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202605312026.Srgsz7Tp-lkp@intel.com/ Closes: https://lore.kernel.org/oe-kbuild-all/202607031100.upQfRZTM-lkp@intel.com/ Reviewed-by: Mat Martineau <martineau@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20260722-net-mptcp-misc-fixes-7-2-rc5-v1-5-6fb595bc86ef@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>