From: Paolo Abeni pabeni@redhat.com
[ Upstream commit 5e15395f6d9ec07395866c5511f4b4ac566c0c9b ]
mptcp_cleanup_rbuf() needs to know the last most recent, mptcp-level rcv_wnd sent, and such information is tracked into the msk->old_wspace field, updated at ack transmission time by mptcp_write_options().
Fallback socket do not add any mptcp options, such helper is never invoked, and msk->old_wspace value remain stale. That in turn makes ack generation at recvmsg() time quite random.
Address the issue ensuring mptcp_write_options() is invoked even for fallback sockets, and just update the needed info in such a case.
The issue went unnoticed for a long time, as mptcp currently overshots the fallback socket receive buffer autotune significantly. It is going to change in the near future.
Fixes: e3859603ba13 ("mptcp: better msk receive window updates") Cc: stable@vger.kernel.org Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/594 Signed-off-by: Paolo Abeni pabeni@redhat.com Reviewed-by: Geliang Tang geliang@kernel.org Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org Link: https://patch.msgid.link/20251118-net-mptcp-misc-fixes-6-18-rc6-v1-1-806d378... Signed-off-by: Jakub Kicinski kuba@kernel.org [ Adjust context ] Signed-off-by: Sasha Levin sashal@kernel.org --- net/mptcp/options.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/net/mptcp/options.c b/net/mptcp/options.c index a71ef6de8c682..b4237e50e23fd 100644 --- a/net/mptcp/options.c +++ b/net/mptcp/options.c @@ -810,8 +810,11 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb,
opts->suboptions = 0;
+ /* Force later mptcp_write_options(), but do not use any actual + * option space. + */ if (unlikely(__mptcp_check_fallback(msk))) - return false; + return true;
if (unlikely(skb && TCP_SKB_CB(skb)->tcp_flags & TCPHDR_RST)) { if (mptcp_established_options_mp_fail(sk, &opt_size, remaining, opts)) { @@ -1222,6 +1225,20 @@ static void mptcp_set_rwin(const struct tcp_sock *tp) WRITE_ONCE(msk->rcv_wnd_sent, ack_seq); }
+static void mptcp_track_rwin(const struct tcp_sock *tp) +{ + const struct sock *ssk = (const struct sock *)tp; + struct mptcp_subflow_context *subflow; + struct mptcp_sock *msk; + + if (!ssk) + return; + + subflow = mptcp_subflow_ctx(ssk); + msk = mptcp_sk(subflow->conn); + WRITE_ONCE(msk->old_wspace, tp->rcv_wnd); +} + __sum16 __mptcp_make_csum(u64 data_seq, u32 subflow_seq, u16 data_len, __wsum sum) { struct csum_pseudo_header header; @@ -1283,6 +1300,12 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp, return; }
+ /* Fallback to TCP */ + if (unlikely(!opts->suboptions)) { + mptcp_track_rwin(tp); + return; + } + /* DSS, MPC, MPJ and ADD_ADDR are mutually exclusive, see * mptcp_established_options*() */