in case of client roaming a new global entry is added while a corresponding
local one is still present. In this case the node can safely pass the WIFI flag
from the local to the global entry
Signed-off-by: Antonio Quartulli <ordex(a)autistici.org>
---
translation-table.c | 36 ++++++++++++++++++++++++++++--------
1 file changed, 28 insertions(+), 8 deletions(-)
diff --git a/translation-table.c b/translation-table.c
index 37ae4a9..2aacde9 100644
--- a/translation-table.c
+++ b/translation-table.c
@@ -500,21 +500,30 @@ batadv_tt_local_set_pending(struct batadv_priv *bat_priv,
tt_local_entry->common.addr, message);
}
+static void __batadv_tt_local_remove(struct batadv_priv *bat_priv,
+ struct batadv_tt_local_entry *tt_local,
+ const char *message, bool roaming)
+{
+ uint16_t flags;
+
+ flags = BATADV_TT_CLIENT_DEL;
+ if (roaming)
+ flags |= BATADV_TT_CLIENT_ROAM;
+
+ batadv_tt_local_set_pending(bat_priv, tt_local, flags, message);
+}
+
void batadv_tt_local_remove(struct batadv_priv *bat_priv, const uint8_t *addr,
const char *message, bool roaming)
{
struct batadv_tt_local_entry *tt_local_entry = NULL;
- uint16_t flags;
tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr);
if (!tt_local_entry)
goto out;
- flags = BATADV_TT_CLIENT_DEL;
- if (roaming)
- flags |= BATADV_TT_CLIENT_ROAM;
+ __batadv_tt_local_remove(bat_priv, tt_local_entry, message, roaming);
- batadv_tt_local_set_pending(bat_priv, tt_local_entry, flags, message);
out:
if (tt_local_entry)
batadv_tt_local_entry_free_ref(tt_local_entry);
@@ -721,9 +730,11 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv,
uint8_t ttvn)
{
struct batadv_tt_global_entry *tt_global_entry = NULL;
+ struct batadv_tt_local_entry *tt_local_entry = NULL;
int ret = 0;
int hash_added;
struct batadv_tt_common_entry *common;
+ uint16_t wifi_flag;
tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr);
@@ -789,14 +800,23 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv,
tt_global_entry->common.addr, orig_node->orig);
out_remove:
+ tt_local_entry = batadv_tt_local_hash_find(bat_priv, tt_addr);
+ if (!tt_local_entry)
+ goto out;
+
+ wifi_flag = tt_local_entry->common.flags & BATADV_TT_CLIENT_WIFI;
+ tt_global_entry->common.flags |= wifi_flag;
+
/* remove address from local hash if present */
- batadv_tt_local_remove(bat_priv, tt_global_entry->common.addr,
- "global tt received",
- flags & BATADV_TT_CLIENT_ROAM);
+ __batadv_tt_local_remove(bat_priv, tt_local_entry, "global tt received",
+ flags & BATADV_TT_CLIENT_ROAM);
+
ret = 1;
out:
if (tt_global_entry)
batadv_tt_global_entry_free_ref(tt_global_entry);
+ if (tt_local_entry)
+ batadv_tt_local_entry_free_ref(tt_local_entry);
return ret;
}
--
1.7.9.4