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@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; }