B.A.T.M.A.N Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Sven Eckelmann <sven@narfation.org>
To: sashiko-reviews@lists.linux.dev
Cc: antonio@mandelbit.com, b.a.t.m.a.n@lists.open-mesh.org
Subject: Re: [PATCH batadv 2/4] batman-adv: tt: only update flags for TT events
Date: Wed, 07 Oct 2026 13:32:27 +0200	[thread overview]
Message-ID: <5328232.31r3eYUQgx@sven-l14> (raw)
In-Reply-To: <sashiko-outbox-162887@kernel.org>

[-- Attachment #1: Type: text/plain, Size: 7110 bytes --]

On Wednesday, 7 October 2026 12:54:50 CEST sashiko-bot@kernel.org wrote:
[...]
> [Severity: High]
> While this masks BATADV_TT_CLIENT_ROAM for the incremental event, doesn't the
> flag remain corrupted in the local TT entry (common->flags)?
> 
> Earlier in batadv_tt_local_refresh(), there is this structure:
> 
>                 if (common->flags & BATADV_TT_CLIENT_PENDING) {
>                         ...
>                         common->flags &= ~BATADV_TT_CLIENT_PENDING;
>                         announce = true;
>                 } else if (common->flags & BATADV_TT_CLIENT_ROAM) {
>                         ...
>                         common->flags &= ~BATADV_TT_CLIENT_ROAM;
>                         *roamed_back = true;
>                 }
> 
> When a client roams away, batadv_tt_local_mark_removed() sets both
> BATADV_TT_CLIENT_ROAM and BATADV_TT_CLIENT_PENDING.
> 
> When the client returns, batadv_tt_local_refresh() clears the PENDING flag
> but skips the else if branch. This leaves BATADV_TT_CLIENT_ROAM set
> locally and *roamed_back as false.
> 
> Consequently, won't any full TT dump (batadv_tt_tvlv_generate) erroneously
> announce the returning client as roaming, causing other nodes to mistakenly
> purge their originators for this client or blackhole traffic?
> 
> Furthermore, does the skipped roamed_back assignment prevent
> batadv_tt_local_add_roam() from freeing the global entry and reclaiming the
> client?

Antonio,

this is exactly what I meant in 
https://lore.kernel.org/batman/20261007-tt-avoid-unhashed-event-v1-0-01c763657916@narfation.org/T/#m35e1aeec45790b26b17d4f4297d77bd8d5b90450 
and which was also previously reported at 
https://www.open-mesh.org/issues/482#change-1886


Maybe needed steps are:


Clear ROAM for pending clients after readd (from local and whenever the global 
still has the client_roam set):


diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index e46040fd745ea8ed0d5b3b497e86b6f37c9c8e25..89098976e31d178829fb575546679178b0d7d0eb 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -865,13 +865,18 @@ static void batadv_tt_local_add_roam(struct batadv_priv *bat_priv,
 		return;
 
 	/* Check whether it is a roaming, but don't do anything if the roaming
-	 * process has already been handled
+	 * process has already been handled.
+	 *
+	 * 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) {
+			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.
 			 *
@@ -939,6 +944,7 @@ static bool batadv_tt_local_add_existing(struct batadv_priv *bat_priv,
 					 bool *roamed_back)
 {
 	struct batadv_tt_common_entry *common = &tt_local->common;
+	bool readded = false;
 
 	tt_local->last_seen = jiffies;
 
@@ -953,10 +959,14 @@ static bool batadv_tt_local_add_existing(struct batadv_priv *bat_priv,
 			 * flag can be reset like it was never enqueued
 			 */
 			common->flags &= ~BATADV_TT_CLIENT_PENDING;
-
-			return true;
+			readded = true;
 		}
 
+		/* a pending client can also carry the ROAM flag when it was
+		 * removed because of a roaming_advertisement. It must not keep
+		 * it after being re-added or it would no longer be considered
+		 * as served by this node
+		 */
 		if (common->flags & BATADV_TT_CLIENT_ROAM) {
 			batadv_dbg(BATADV_DBG_TT, bat_priv,
 				   "Roaming client %pM (vid: %d) came back to its original location\n",
@@ -971,7 +981,7 @@ static bool batadv_tt_local_add_existing(struct batadv_priv *bat_priv,
 		}
 	}
 
-	return false;
+	return readded;
 }
 
 /**





Only transmit ROAM events with DEL:


diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 89098976e31d178829fb575546679178b0d7d0eb..b14593b6ec6d52986bbb23647420391520e37dc5 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -696,9 +696,17 @@ static void __batadv_tt_local_event(struct batadv_priv *bat_priv,
 	ether_addr_copy(tt_change_node->change.addr, common->addr);
 	tt_change_node->change.vid = htons(common->vid);
 
-	tt_change_node->change.flags = flags;
 	del_op_requested = flags & BATADV_TT_CLIENT_DEL;
 
+	/* the ROAM flag is only meaningful for the receiver in combination
+	 * with a DEL. An ADD with ROAM would be interpreted as a roaming
+	 * advertisement
+	 */
+	if (!del_op_requested)
+		flags &= ~BATADV_TT_CLIENT_ROAM;
+
+	tt_change_node->change.flags = flags;
+
 	/* check for ADD+DEL, DEL+ADD, ADD+ADD or DEL+DEL events */
 	spin_lock_bh(&bat_priv->tt.changes_list_lock);
 	changes = READ_ONCE(bat_priv->tt.local_changes);
@@ -3405,8 +3413,12 @@ static bool batadv_tt_local_valid(void *entry_ptr,
 	if (tt_flags & BATADV_TT_CLIENT_NEW)
 		return false;
 
+	/* the entry is (still) announced. A ROAM flag of an entry which is
+	 * pending to be removed must not be transmitted. Otherwise, the
+	 * receiver would handle it like a roaming advertisement
+	 */
 	if (flags)
-		*flags = tt_flags;
+		*flags = tt_flags & ~BATADV_TT_CLIENT_ROAM;
 
 	return true;
 }




Ignore ROAM for an ADD received for a global entry update via event:


diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index b14593b6ec6d52986bbb23647420391520e37dc5..8dd5822c9c7128e67cd8abdb4ddce5dc0c6eec9e 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -3996,22 +3996,31 @@ static void _batadv_tt_update_changes(struct batadv_priv *bat_priv,
 				      struct batadv_tvlv_tt_change *tt_change,
 				      u16 tt_num_changes, u8 ttvn)
 {
+	u8 flags;
 	int roams;
 	int i;
 
 	for (i = 0; i < tt_num_changes; i++) {
-		if ((tt_change + i)->flags & BATADV_TT_CLIENT_DEL) {
-			roams = (tt_change + i)->flags & BATADV_TT_CLIENT_ROAM;
+		flags = (tt_change + i)->flags;
+
+		if (flags & BATADV_TT_CLIENT_DEL) {
+			roams = flags & BATADV_TT_CLIENT_ROAM;
 			batadv_tt_global_del(bat_priv, orig_node,
 					     (tt_change + i)->addr,
 					     ntohs((tt_change + i)->vid),
 					     "tt removed by changes",
 					     roams);
 		} else {
+			/* an announced client cannot have roamed away from
+			 * orig_node. Only a ROAMING_ADV is allowed to add a
+			 * global entry with the ROAM flag
+			 */
+			flags &= ~BATADV_TT_CLIENT_ROAM;
+
 			if (!batadv_tt_global_add(bat_priv, orig_node,
 						  (tt_change + i)->addr,
 						  ntohs((tt_change + i)->vid),
-						  (tt_change + i)->flags, ttvn))
+						  flags, ttvn))
 				/* In case of problem while storing a
 				 * global_entry, we stop the updating
 				 * procedure without committing the

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

  parent reply	other threads:[~2026-10-07 11:32 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-07 10:29 [PATCH batadv 0/4] batman-adv: tt: shashiko 20260930 follow ups Sven Eckelmann
2026-10-07 10:29 ` [PATCH batadv 1/4] batman-adv: tt: don't queue local events for unhashed entries Sven Eckelmann
2026-10-07 10:29 ` [PATCH batadv 2/4] batman-adv: tt: only update flags for TT events Sven Eckelmann
2026-10-07 10:46   ` Sven Eckelmann
     [not found]   ` <sashiko-outbox-162887@kernel.org>
2026-10-07 11:32     ` Sven Eckelmann [this message]
2026-10-07 10:29 ` [PATCH batadv 3/4] batman-adv: tt: avoid list_lock for unchanged local clients Sven Eckelmann
2026-10-07 10:29 ` [PATCH batadv 4/4] batman-adv: tt: drop ADD+DEL events of never announced clients Sven Eckelmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5328232.31r3eYUQgx@sven-l14 \
    --to=sven@narfation.org \
    --cc=antonio@mandelbit.com \
    --cc=b.a.t.m.a.n@lists.open-mesh.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox