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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.