]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
mptcp: clear scheduled subflows on retransmit
authorPaolo Abeni <pabeni@redhat.com>
Tue, 25 Nov 2025 16:59:11 +0000 (17:59 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 6 Dec 2025 21:25:00 +0000 (06:25 +0900)
commit 27fd02860164bfa78cec2640dfad630d832e302c upstream.

When __mptcp_retrans() kicks-in, it schedules one or more subflows for
retransmission, but such subflows could be actually left alone if there
is no more data to retransmit and/or in case of concurrent fallback.

Scheduled subflows could be processed much later in time, i.e. when new
data will be transmitted, leading to bad subflow selection.

Explicitly clear all scheduled subflows before leaving the
retransmission function.

Fixes: ee2708aedad0 ("mptcp: use get_retrans wrapper")
Cc: stable@vger.kernel.org
Reported-by: Filip Pokryvka <fpokryvk@redhat.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/20251125-net-mptcp-clear-sched-rtx-v1-1-1cea4ad2165f@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/mptcp/protocol.c

index 0087a598a383d8518a04ac3e90a62239795a521b..ded56ebb1ed2fc9cba63fcf1e17719a2838fc0ef 100644 (file)
@@ -2721,7 +2721,7 @@ static void __mptcp_retrans(struct sock *sk)
                }
 
                if (!mptcp_send_head(sk))
-                       return;
+                       goto clear_scheduled;
 
                goto reset_timer;
        }
@@ -2752,7 +2752,7 @@ static void __mptcp_retrans(struct sock *sk)
                        if (__mptcp_check_fallback(msk)) {
                                spin_unlock_bh(&msk->fallback_lock);
                                release_sock(ssk);
-                               return;
+                               goto clear_scheduled;
                        }
 
                        while (info.sent < info.limit) {
@@ -2784,6 +2784,15 @@ reset_timer:
 
        if (!mptcp_rtx_timer_pending(sk))
                mptcp_reset_rtx_timer(sk);
+
+clear_scheduled:
+       /* If no rtx data was available or in case of fallback, there
+        * could be left-over scheduled subflows; clear them all
+        * or later xmit could use bad ones
+        */
+       mptcp_for_each_subflow(msk, subflow)
+               if (READ_ONCE(subflow->scheduled))
+                       mptcp_subflow_set_scheduled(subflow, false);
 }
 
 /* schedule the timeout timer for the relevant event: either close timeout