When TCP option space is insufficient (e.g., IPv6 with tcp_timestamps enabled), the original code jumped to out_unlock without clearing the addr_signal flag. This caused mptcp_pm_add_timer to keep rescheduling indefinitely without sending ADD_ADDR, preventing the endpoint list from being traversed. In a pure ACK scenario (indicated by drop_other_suboptions=true), if the option space is insufficient to carry the ADD_ADDR suboption, it is appropriate to drop this address signal to allow the timer handler to move on to other addresses. Fixes: 00cfd77b9063 ("mptcp: retransmit ADD_ADDR when timeout") Signed-off-by: Li Xiasong --- Seeking feedback on: When announcing addresses to the peer, MPTCP sends a pure ACK packet to carry MPTCP options (ADD_ADDR). In this scenario, if the option space is insufficient for ADD_ADDR, clearing addr_signal would: - Prevent the timer from retrying infinitely - Allow the timer to continue traversing and processing other addresses - Not block other subflow creation or address announcement operations Is there any scenario where we should retry later instead of clearing the address signal/echo flag? However, if a pure ACK doesn't have enough space for the flag, subsequent packets won't either. --- net/mptcp/pm.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index 57a456690406..1d49779c6a1f 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -881,19 +881,18 @@ bool mptcp_pm_add_addr_signal(struct mptcp_sock *msk, const struct sk_buff *skb, } *echo = mptcp_pm_should_add_signal_echo(msk); + add_addr = msk->pm.addr_signal & + ~(*echo ? BIT(MPTCP_ADD_ADDR_ECHO) : BIT(MPTCP_ADD_ADDR_SIGNAL)); port = !!(*echo ? msk->pm.remote.port : msk->pm.local.port); - family = *echo ? msk->pm.remote.family : msk->pm.local.family; - if (remaining < mptcp_add_addr_len(family, *echo, port)) - goto out_unlock; - if (*echo) { - *addr = msk->pm.remote; - add_addr = msk->pm.addr_signal & ~BIT(MPTCP_ADD_ADDR_ECHO); - } else { - *addr = msk->pm.local; - add_addr = msk->pm.addr_signal & ~BIT(MPTCP_ADD_ADDR_SIGNAL); + if (remaining < mptcp_add_addr_len(family, *echo, port)) { + if (*drop_other_suboptions) + WRITE_ONCE(msk->pm.addr_signal, add_addr); + goto out_unlock; } + + *addr = *echo ? msk->pm.remote : msk->pm.local; WRITE_ONCE(msk->pm.addr_signal, add_addr); ret = true; -- 2.34.1