@@ -310,9 +310,7 @@ void schedule_own_packet(struct hard_iface *hard_iface)
/* if at least one change happened */
if (atomic_read(&bat_priv->tt_local_changes) > 0) {
prepare_packet_buffer(bat_priv, hard_iface);
- /* Increment the TTVN only once per OGM interval */
- atomic_inc(&bat_priv->ttvn);
- bat_priv->tt_poss_change = false;
+ tt_commit_changes(bat_priv);
}
/* if the changes have been sent enough times */
@@ -358,21 +358,6 @@ out:
return ret;
}
-static void tt_local_del(struct bat_priv *bat_priv,
- struct tt_local_entry *tt_local_entry,
- const char *message)
-{
- bat_dbg(DBG_TT, bat_priv, "Deleting local tt entry (%pM): %s\n",
- tt_local_entry->addr, message);
-
- atomic_dec(&bat_priv->num_local_tt);
-
- hash_remove(bat_priv->tt_local_hash, compare_ltt, choose_orig,
- tt_local_entry->addr);
-
- tt_local_entry_free_ref(tt_local_entry);
-}
-
void tt_local_remove(struct bat_priv *bat_priv, const uint8_t *addr,
const char *message, bool roaming)
{
@@ -381,7 +366,7 @@ void tt_local_remove(struct bat_priv *bat_priv, const uint8_t *addr,
tt_local_entry = tt_local_hash_find(bat_priv, addr);
if (!tt_local_entry)
- goto out;
+ return;
tt_local_event(bat_priv, tt_local_entry->addr,
tt_local_entry->flags | TT_CLIENT_DEL |
@@ -1636,3 +1621,66 @@ void tt_free(struct bat_priv *bat_priv)
kfree(bat_priv->tt_buff);
}
+
+/* This function will purge out the specified flags from all the entries in
+ * the given hash table */
+static void tt_purge_flags(struct hashtable_t *hash, uint16_t flags)
+{
+ int i;
+ struct hlist_head *head;
+ struct hlist_node *node;
+ struct tt_local_entry *tt_local_entry;
+
+ for (i = 0; i < hash->size; i++) {
+ head = &hash->table[i];
+
+ rcu_read_lock();
+ hlist_for_each_entry_rcu(tt_local_entry, node,
+ head, hash_entry) {
+ tt_local_entry->flags &= ~flags;
+ }
+ rcu_read_unlock();
+ }
+
+}
+
+static void tt_purge_local_pending_clients(struct bat_priv *bat_priv)
+{
+ struct hashtable_t *hash = bat_priv->tt_local_hash;
+ struct tt_local_entry *tt_local_entry;
+ struct hlist_node *node, *node_tmp;
+ struct hlist_head *head;
+ spinlock_t *list_lock; /* protects write access to the hash lists */
+ int i;
+
+ for (i = 0; i < hash->size; i++) {
+ head = &hash->table[i];
+ list_lock = &hash->list_locks[i];
+
+ spin_lock_bh(list_lock);
+ hlist_for_each_entry_safe(tt_local_entry, node, node_tmp,
+ head, hash_entry) {
+ if (!(tt_local_entry->flags & TT_CLIENT_PENDING))
+ continue;
+
+ bat_dbg(DBG_TT, bat_priv, "Deleting local tt entry "
+ "(%pM): pending\n", tt_local_entry->addr);
+
+ atomic_dec(&bat_priv->num_local_tt);
+ hlist_del_rcu(node);
+ tt_local_entry_free_ref(tt_local_entry);
+ }
+ spin_unlock_bh(list_lock);
+ }
+
+}
+
+void tt_commit_changes(struct bat_priv *bat_priv)
+{
+ tt_purge_flags(bat_priv->tt_local_hash, TT_CLIENT_ROAM);
+ tt_purge_local_pending_clients(bat_priv);
+
+ /* Increment the TTVN only once per OGM interval */
+ atomic_inc(&bat_priv->ttvn);
+ bat_priv->tt_poss_change = false;
+}
@@ -61,5 +61,6 @@ void handle_tt_response(struct bat_priv *bat_priv,
struct tt_query_packet *tt_response);
void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client,
struct orig_node *orig_node);
+void tt_commit_changes(struct bat_priv *bat_priv);
#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */
On ttvn increment all the collected changes have to be commited: - local clients marked with TT_CLIENT_ROAM have to be unmarked. - local clients marked with TT_CLIENT_PENDING have to be deleted. Signed-off-by: Antonio Quartulli <ordex@autistici.org> --- send.c | 4 +-- translation-table.c | 80 ++++++++++++++++++++++++++++++++++++++++---------- translation-table.h | 1 + 3 files changed, 66 insertions(+), 19 deletions(-)