Re: [PATCH export v3 4/4] mptcp: fallback to TCP on MP_FAIL with a single subflow
Paolo Abeni <[email protected]>
| Newsgroups | dev.linux.lists.mptcp |
|---|---|
| Message-ID | <[email protected]> |
On 8/12/26 7:46 AM, Chenguang Zhao wrote: > From: Chenguang Zhao <[email protected]> > > Fall back immediately via mptcp_try_fallback() after accepting MP_FAIL > on a single contiguous subflow, as required by RFC8684 §3.7. > > Fixes: 1e39e5a32ad7 ("mptcp: infinite mapping sending") > Signed-off-by: Chenguang Zhao <[email protected]> > --- > net/mptcp/pm.c | 9 ++++++--- > net/mptcp/protocol.c | 4 +++- > 2 files changed, 9 insertions(+), 4 deletions(-) > > diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c > index 8c263084db7b..cb85caf1df43 100644 > --- a/net/mptcp/pm.c > +++ b/net/mptcp/pm.c > @@ -876,7 +876,6 @@ void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq) > > pr_debug("fail_seq=%llu\n", fail_seq); > > - /* After accepting the fail, we can't create any other subflows */ > spin_lock_bh(&msk->fallback_lock); > if (!msk->allow_infinite_fallback) { > spin_unlock_bh(&msk->fallback_lock); > @@ -891,8 +890,6 @@ void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq) > mptcp_subflow_reset(sk); > return; > } > - > - msk->allow_subflows = false; > spin_unlock_bh(&msk->fallback_lock); At this point another subflow can complete the join, and set allow_infinite_fallback = false ... > > if (!subflow->fail_tout) { > @@ -901,6 +898,12 @@ void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq) > subflow->send_mp_fail = 1; > subflow->send_infinite_map = 1; > tcp_send_ack(sk); ... so the this mp_fail processing will be bogus [1]. > + > + /* RFC8684 §3.7: fallback with a single subflow */ > + if (!mptcp_try_fallback(sk, MPTCP_MIB_MPFAILFALLBACK)) { > + MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_FALLBACKFAILED); > + mptcp_subflow_reset(sk); > + } > } else { > pr_debug("MP_FAIL response received\n"); > WRITE_ONCE(subflow->fail_tout, 0); > diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c > index f879b1061f2d..519e8d9c3164 100644 > --- a/net/mptcp/protocol.c > +++ b/net/mptcp/protocol.c > @@ -1418,7 +1418,9 @@ static void mptcp_update_infinite_map(struct mptcp_sock *msk, > mpext->infinite_map = 1; > mpext->data_len = 0; > > - if (!mptcp_try_fallback(ssk, MPTCP_MIB_INFINITEMAPTX)) { > + if (__mptcp_check_fallback(msk)) { > + MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_INFINITEMAPTX); > + } else if (!mptcp_try_fallback(ssk, MPTCP_MIB_INFINITEMAPTX)) { > MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_FALLBACKFAILED); > mptcp_subflow_reset(ssk); > return; I don't understand this change. Can we ever enter the `if (!mptcp_try_fallback(ssk, MPTCP_MIB_INFINITEMAPTX)) {` branch? The msk already tried to fallback in mptcp_pm_mp_fail_received(). If the fallback was successful, the code will enter the `if (__mptcp_check_fallback(msk)) {` branch and not this one. Otherwise the fallback will fail again (AFAICS nothing resets `allow_infinite_fallback` once in become false). /P