From aff4d5d10f2dcb4a9b604e27414dafa1d51b6406 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Thu, 8 Oct 2026 12:00:27 +0200 Subject: [PATCH] batman-adv: tt: send ROAM_ADV on each roamed back client When a ROAMING_ADV is received for an announced local client, batadv_roam_tvlv_unicast_handler_v1() creates a global entry with the BATADV_TT_CLIENT_ROAM flag set. If the client sends a frame again before the next TTVN commit, batadv_tt_local_add_roam() is expected to announce this return via a ROAM_ADV frame. But this doesn't happen because the global entry (created by the first ROAMING_ADV) carries BATADV_TT_CLIENT_ROAM until the new originator announces the client. Let batadv_tt_local_add_roam() always handle a roamed back client - independent of the ROAM flag of the global entry: * trigger sending of the ROAM_ADV frame(s) * remove the (with the roaming) associated global entry Cc: stable@vger.kernel.org Fixes: 068ee6e204e1 ("batman-adv: roaming handling mechanism redesign") Signed-off-by: Sven Eckelmann --- net/batman-adv/translation-table.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index e13c2828da47..0df51523dcf0 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -819,14 +819,21 @@ static void batadv_tt_local_add_roam(struct batadv_priv *bat_priv, if (!tt_global) return; - /* Check whether it is a roaming, but don't do anything if the roaming - * process has already been handled + /* Handle newly roamed client - but not roamed back client. + * + * A client which roamed back must always be reclaimed from the + * originator(s) which sent the ROAMING_ADV. The global entry created by + * this ROAMING_ADV might still carry BATADV_TT_CLIENT_ROAM because the + * new originator did not yet announce the client. */ - scoped_guard(spinlock_bh, &tt_global->common.flags_lock) { - if (tt_global->common.flags & BATADV_TT_CLIENT_ROAM) - return; + if (!roamed_back) { + scoped_guard(spinlock_bh, &tt_global->common.flags_lock) { + /* Check whether it is a roaming, but don't do anything + * if the roaming process has already been handled. + */ + if (tt_global->common.flags & BATADV_TT_CLIENT_ROAM) + return; - if (!roamed_back) { /* The global entry has to be marked as ROAMING and has to be * kept for consistency purpose. *