Re: [PATCH mptcp-next RFC v4 2/2] mptcp: send MP_FAIL and infinite mapping on the same ACK
Chenguang Zhao <[email protected]>
| Newsgroups | dev.linux.lists.mptcp |
|---|---|
| Message-ID | <[email protected]> |
在 2026/8/19 00:19, Matthieu Baerts 写道: > Hi Chenguang, > > On 18/08/2026 11:14, Chenguang Zhao wrote: >> From: Chenguang Zhao <[email protected]> >> >> On a single subflow, accepting MP_FAIL must leave MPTCP mode at once >> (RFC8684 §3.7). Emit the infinite mapping on the MP_FAIL reply ACK, >> then call mptcp_try_fallback() immediately after. > I think Sashiko is right about the issue of lacking option space to have > both the MP_FAIL and the infinite mapping sent together. Yes, Sashiko is right, I did not consider all the aspects. > Please also note this from RFC 8684 §3.7.11 [1]: > >> This infinite mapping will be a DSS option (Section 3.3) on the first >> new packet, containing a Data Sequence Mapping that acts retroactively > The "on the first new packet" seems to suggest the infinite mapping > shouldn't be attached to the MP_FAIL. > > [1] https://datatracker.ietf.org/doc/html/rfc8684#section-3.7-11 > > > Maybe a fallback for the single subflow without csum is enough? Or maybe > nothing needs to be done? Or maybe this fallback is just an > optimisation, and can be done in net-next (and both commits can be > combined)? WDYT? Hi Matthieu I am getting a bit confused, so let me summarize my current understanding to verify if I got this right. In the existing kernel code, fallback will be triggered upon receiving MP_FAIL. However, the FALLBACK_DONE flag is currently set inside mptcp_update_infinite_map(), which only gets invoked when transmitting a data packet. This creates a timing window between receiving MP_FAIL and sending the first subsequent packet, resulting in this minor bug. Our goal is to close this timing window: set the FALLBACK_DONE flag immediately after MP_FAIL is received. Besides, add a __mptcp_check_fallback() check within mptcp_can_accept_new_subflow() to reject MP_JOIN requests ahead of time. Is my understanding correct? I will send out a v5 RFC based on the above ideas. >> Fixes: 1e39e5a32ad7 ("mptcp: infinite mapping sending") >> Signed-off-by: Chenguang Zhao <[email protected]> >> --- >> net/mptcp/options.c | 33 ++++++++++++++++++++++++++++++++- >> net/mptcp/pm.c | 5 +++++ >> net/mptcp/protocol.c | 8 +------- >> 3 files changed, 38 insertions(+), 8 deletions(-) >> >> diff --git a/net/mptcp/options.c b/net/mptcp/options.c >> index 97da22668dbe..ecf77e77d2de 100644 >> --- a/net/mptcp/options.c >> +++ b/net/mptcp/options.c >> @@ -638,7 +638,29 @@ static bool mptcp_established_options_dss(struct sock *sk, struct sk_buff *skb, >> opts->csum_reqd = READ_ONCE(msk->csum_enabled); >> mpext = skb ? mptcp_get_ext(skb) : NULL; >> >> - if (!skb || (mpext && mpext->use_map) || snd_data_fin_enable) { >> + if (unlikely(subflow->send_infinite_map)) { >> + unsigned int map_size = TCPOLEN_MPTCP_DSS_BASE + TCPOLEN_MPTCP_DSS_MAP64; >> + >> + if (opts->csum_reqd) >> + map_size += TCPOLEN_MPTCP_DSS_CHECKSUM; >> + >> + if (mpext) { >> + opts->ext_copy = *mpext; >> + opts->ext_copy.infinite_map = 1; >> + opts->ext_copy.data_len = 0; >> + } else { >> + opts->ext_copy.use_map = 1; >> + opts->ext_copy.dsn64 = 1;> + opts->ext_copy.infinite_map = 1; >> + opts->ext_copy.data_len = 0; >> + opts->ext_copy.data_seq = READ_ONCE(msk->snd_nxt); >> + opts->ext_copy.subflow_seq = subflow->rel_write_seq; >> + } > You probably also need to reset "csum". Note that common fields > (infinite_map and data_len) can also be set once here. > > (...) > > Cheers, > Matt