aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/translation-table.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/batman-adv/translation-table.c')
-rw-r--r--net/batman-adv/translation-table.c416
1 files changed, 256 insertions, 160 deletions
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 99dd8f75b3ff..112edd371b2f 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -34,6 +34,10 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
34static void batadv_tt_purge(struct work_struct *work); 34static void batadv_tt_purge(struct work_struct *work);
35static void 35static void
36batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry); 36batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry);
37static void batadv_tt_global_del(struct batadv_priv *bat_priv,
38 struct batadv_orig_node *orig_node,
39 const unsigned char *addr,
40 const char *message, bool roaming);
37 41
38/* returns 1 if they are the same mac addr */ 42/* returns 1 if they are the same mac addr */
39static int batadv_compare_tt(const struct hlist_node *node, const void *data2) 43static int batadv_compare_tt(const struct hlist_node *node, const void *data2)
@@ -46,8 +50,8 @@ static int batadv_compare_tt(const struct hlist_node *node, const void *data2)
46 50
47static void batadv_tt_start_timer(struct batadv_priv *bat_priv) 51static void batadv_tt_start_timer(struct batadv_priv *bat_priv)
48{ 52{
49 INIT_DELAYED_WORK(&bat_priv->tt_work, batadv_tt_purge); 53 INIT_DELAYED_WORK(&bat_priv->tt.work, batadv_tt_purge);
50 queue_delayed_work(batadv_event_workqueue, &bat_priv->tt_work, 54 queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work,
51 msecs_to_jiffies(5000)); 55 msecs_to_jiffies(5000));
52} 56}
53 57
@@ -88,7 +92,7 @@ batadv_tt_local_hash_find(struct batadv_priv *bat_priv, const void *data)
88 struct batadv_tt_common_entry *tt_common_entry; 92 struct batadv_tt_common_entry *tt_common_entry;
89 struct batadv_tt_local_entry *tt_local_entry = NULL; 93 struct batadv_tt_local_entry *tt_local_entry = NULL;
90 94
91 tt_common_entry = batadv_tt_hash_find(bat_priv->tt_local_hash, data); 95 tt_common_entry = batadv_tt_hash_find(bat_priv->tt.local_hash, data);
92 if (tt_common_entry) 96 if (tt_common_entry)
93 tt_local_entry = container_of(tt_common_entry, 97 tt_local_entry = container_of(tt_common_entry,
94 struct batadv_tt_local_entry, 98 struct batadv_tt_local_entry,
@@ -102,7 +106,7 @@ batadv_tt_global_hash_find(struct batadv_priv *bat_priv, const void *data)
102 struct batadv_tt_common_entry *tt_common_entry; 106 struct batadv_tt_common_entry *tt_common_entry;
103 struct batadv_tt_global_entry *tt_global_entry = NULL; 107 struct batadv_tt_global_entry *tt_global_entry = NULL;
104 108
105 tt_common_entry = batadv_tt_hash_find(bat_priv->tt_global_hash, data); 109 tt_common_entry = batadv_tt_hash_find(bat_priv->tt.global_hash, data);
106 if (tt_common_entry) 110 if (tt_common_entry)
107 tt_global_entry = container_of(tt_common_entry, 111 tt_global_entry = container_of(tt_common_entry,
108 struct batadv_tt_global_entry, 112 struct batadv_tt_global_entry,
@@ -152,6 +156,8 @@ static void batadv_tt_orig_list_entry_free_rcu(struct rcu_head *rcu)
152static void 156static void
153batadv_tt_orig_list_entry_free_ref(struct batadv_tt_orig_list_entry *orig_entry) 157batadv_tt_orig_list_entry_free_ref(struct batadv_tt_orig_list_entry *orig_entry)
154{ 158{
159 if (!atomic_dec_and_test(&orig_entry->refcount))
160 return;
155 /* to avoid race conditions, immediately decrease the tt counter */ 161 /* to avoid race conditions, immediately decrease the tt counter */
156 atomic_dec(&orig_entry->orig_node->tt_size); 162 atomic_dec(&orig_entry->orig_node->tt_size);
157 call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu); 163 call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu);
@@ -175,8 +181,8 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv,
175 del_op_requested = flags & BATADV_TT_CLIENT_DEL; 181 del_op_requested = flags & BATADV_TT_CLIENT_DEL;
176 182
177 /* check for ADD+DEL or DEL+ADD events */ 183 /* check for ADD+DEL or DEL+ADD events */
178 spin_lock_bh(&bat_priv->tt_changes_list_lock); 184 spin_lock_bh(&bat_priv->tt.changes_list_lock);
179 list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list, 185 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
180 list) { 186 list) {
181 if (!batadv_compare_eth(entry->change.addr, addr)) 187 if (!batadv_compare_eth(entry->change.addr, addr))
182 continue; 188 continue;
@@ -203,15 +209,15 @@ del:
203 } 209 }
204 210
205 /* track the change in the OGMinterval list */ 211 /* track the change in the OGMinterval list */
206 list_add_tail(&tt_change_node->list, &bat_priv->tt_changes_list); 212 list_add_tail(&tt_change_node->list, &bat_priv->tt.changes_list);
207 213
208unlock: 214unlock:
209 spin_unlock_bh(&bat_priv->tt_changes_list_lock); 215 spin_unlock_bh(&bat_priv->tt.changes_list_lock);
210 216
211 if (event_removed) 217 if (event_removed)
212 atomic_dec(&bat_priv->tt_local_changes); 218 atomic_dec(&bat_priv->tt.local_changes);
213 else 219 else
214 atomic_inc(&bat_priv->tt_local_changes); 220 atomic_inc(&bat_priv->tt.local_changes);
215} 221}
216 222
217int batadv_tt_len(int changes_num) 223int batadv_tt_len(int changes_num)
@@ -221,12 +227,12 @@ int batadv_tt_len(int changes_num)
221 227
222static int batadv_tt_local_init(struct batadv_priv *bat_priv) 228static int batadv_tt_local_init(struct batadv_priv *bat_priv)
223{ 229{
224 if (bat_priv->tt_local_hash) 230 if (bat_priv->tt.local_hash)
225 return 0; 231 return 0;
226 232
227 bat_priv->tt_local_hash = batadv_hash_new(1024); 233 bat_priv->tt.local_hash = batadv_hash_new(1024);
228 234
229 if (!bat_priv->tt_local_hash) 235 if (!bat_priv->tt.local_hash)
230 return -ENOMEM; 236 return -ENOMEM;
231 237
232 return 0; 238 return 0;
@@ -258,7 +264,7 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
258 264
259 batadv_dbg(BATADV_DBG_TT, bat_priv, 265 batadv_dbg(BATADV_DBG_TT, bat_priv,
260 "Creating new local tt entry: %pM (ttvn: %d)\n", addr, 266 "Creating new local tt entry: %pM (ttvn: %d)\n", addr,
261 (uint8_t)atomic_read(&bat_priv->ttvn)); 267 (uint8_t)atomic_read(&bat_priv->tt.vn));
262 268
263 memcpy(tt_local_entry->common.addr, addr, ETH_ALEN); 269 memcpy(tt_local_entry->common.addr, addr, ETH_ALEN);
264 tt_local_entry->common.flags = BATADV_NO_FLAGS; 270 tt_local_entry->common.flags = BATADV_NO_FLAGS;
@@ -266,6 +272,7 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
266 tt_local_entry->common.flags |= BATADV_TT_CLIENT_WIFI; 272 tt_local_entry->common.flags |= BATADV_TT_CLIENT_WIFI;
267 atomic_set(&tt_local_entry->common.refcount, 2); 273 atomic_set(&tt_local_entry->common.refcount, 2);
268 tt_local_entry->last_seen = jiffies; 274 tt_local_entry->last_seen = jiffies;
275 tt_local_entry->common.added_at = tt_local_entry->last_seen;
269 276
270 /* the batman interface mac address should never be purged */ 277 /* the batman interface mac address should never be purged */
271 if (batadv_compare_eth(addr, soft_iface->dev_addr)) 278 if (batadv_compare_eth(addr, soft_iface->dev_addr))
@@ -277,7 +284,7 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
277 */ 284 */
278 tt_local_entry->common.flags |= BATADV_TT_CLIENT_NEW; 285 tt_local_entry->common.flags |= BATADV_TT_CLIENT_NEW;
279 286
280 hash_added = batadv_hash_add(bat_priv->tt_local_hash, batadv_compare_tt, 287 hash_added = batadv_hash_add(bat_priv->tt.local_hash, batadv_compare_tt,
281 batadv_choose_orig, 288 batadv_choose_orig,
282 &tt_local_entry->common, 289 &tt_local_entry->common,
283 &tt_local_entry->common.hash_entry); 290 &tt_local_entry->common.hash_entry);
@@ -348,7 +355,7 @@ static void batadv_tt_prepare_packet_buff(struct batadv_priv *bat_priv,
348 primary_if = batadv_primary_if_get_selected(bat_priv); 355 primary_if = batadv_primary_if_get_selected(bat_priv);
349 356
350 req_len = min_packet_len; 357 req_len = min_packet_len;
351 req_len += batadv_tt_len(atomic_read(&bat_priv->tt_local_changes)); 358 req_len += batadv_tt_len(atomic_read(&bat_priv->tt.local_changes));
352 359
353 /* if we have too many changes for one packet don't send any 360 /* if we have too many changes for one packet don't send any
354 * and wait for the tt table request which will be fragmented 361 * and wait for the tt table request which will be fragmented
@@ -381,10 +388,10 @@ static int batadv_tt_changes_fill_buff(struct batadv_priv *bat_priv,
381 if (new_len > 0) 388 if (new_len > 0)
382 tot_changes = new_len / batadv_tt_len(1); 389 tot_changes = new_len / batadv_tt_len(1);
383 390
384 spin_lock_bh(&bat_priv->tt_changes_list_lock); 391 spin_lock_bh(&bat_priv->tt.changes_list_lock);
385 atomic_set(&bat_priv->tt_local_changes, 0); 392 atomic_set(&bat_priv->tt.local_changes, 0);
386 393
387 list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list, 394 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
388 list) { 395 list) {
389 if (count < tot_changes) { 396 if (count < tot_changes) {
390 memcpy(tt_buff + batadv_tt_len(count), 397 memcpy(tt_buff + batadv_tt_len(count),
@@ -394,25 +401,25 @@ static int batadv_tt_changes_fill_buff(struct batadv_priv *bat_priv,
394 list_del(&entry->list); 401 list_del(&entry->list);
395 kfree(entry); 402 kfree(entry);
396 } 403 }
397 spin_unlock_bh(&bat_priv->tt_changes_list_lock); 404 spin_unlock_bh(&bat_priv->tt.changes_list_lock);
398 405
399 /* Keep the buffer for possible tt_request */ 406 /* Keep the buffer for possible tt_request */
400 spin_lock_bh(&bat_priv->tt_buff_lock); 407 spin_lock_bh(&bat_priv->tt.last_changeset_lock);
401 kfree(bat_priv->tt_buff); 408 kfree(bat_priv->tt.last_changeset);
402 bat_priv->tt_buff_len = 0; 409 bat_priv->tt.last_changeset_len = 0;
403 bat_priv->tt_buff = NULL; 410 bat_priv->tt.last_changeset = NULL;
404 /* check whether this new OGM has no changes due to size problems */ 411 /* check whether this new OGM has no changes due to size problems */
405 if (new_len > 0) { 412 if (new_len > 0) {
406 /* if kmalloc() fails we will reply with the full table 413 /* if kmalloc() fails we will reply with the full table
407 * instead of providing the diff 414 * instead of providing the diff
408 */ 415 */
409 bat_priv->tt_buff = kmalloc(new_len, GFP_ATOMIC); 416 bat_priv->tt.last_changeset = kmalloc(new_len, GFP_ATOMIC);
410 if (bat_priv->tt_buff) { 417 if (bat_priv->tt.last_changeset) {
411 memcpy(bat_priv->tt_buff, tt_buff, new_len); 418 memcpy(bat_priv->tt.last_changeset, tt_buff, new_len);
412 bat_priv->tt_buff_len = new_len; 419 bat_priv->tt.last_changeset_len = new_len;
413 } 420 }
414 } 421 }
415 spin_unlock_bh(&bat_priv->tt_buff_lock); 422 spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
416 423
417 return count; 424 return count;
418} 425}
@@ -421,7 +428,7 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
421{ 428{
422 struct net_device *net_dev = (struct net_device *)seq->private; 429 struct net_device *net_dev = (struct net_device *)seq->private;
423 struct batadv_priv *bat_priv = netdev_priv(net_dev); 430 struct batadv_priv *bat_priv = netdev_priv(net_dev);
424 struct batadv_hashtable *hash = bat_priv->tt_local_hash; 431 struct batadv_hashtable *hash = bat_priv->tt.local_hash;
425 struct batadv_tt_common_entry *tt_common_entry; 432 struct batadv_tt_common_entry *tt_common_entry;
426 struct batadv_hard_iface *primary_if; 433 struct batadv_hard_iface *primary_if;
427 struct hlist_node *node; 434 struct hlist_node *node;
@@ -446,7 +453,7 @@ int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
446 453
447 seq_printf(seq, 454 seq_printf(seq,
448 "Locally retrieved addresses (from %s) announced via TT (TTVN: %u):\n", 455 "Locally retrieved addresses (from %s) announced via TT (TTVN: %u):\n",
449 net_dev->name, (uint8_t)atomic_read(&bat_priv->ttvn)); 456 net_dev->name, (uint8_t)atomic_read(&bat_priv->tt.vn));
450 457
451 for (i = 0; i < hash->size; i++) { 458 for (i = 0; i < hash->size; i++) {
452 head = &hash->table[i]; 459 head = &hash->table[i];
@@ -544,7 +551,7 @@ static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv,
544 551
545static void batadv_tt_local_purge(struct batadv_priv *bat_priv) 552static void batadv_tt_local_purge(struct batadv_priv *bat_priv)
546{ 553{
547 struct batadv_hashtable *hash = bat_priv->tt_local_hash; 554 struct batadv_hashtable *hash = bat_priv->tt.local_hash;
548 struct hlist_head *head; 555 struct hlist_head *head;
549 spinlock_t *list_lock; /* protects write access to the hash lists */ 556 spinlock_t *list_lock; /* protects write access to the hash lists */
550 uint32_t i; 557 uint32_t i;
@@ -570,10 +577,10 @@ static void batadv_tt_local_table_free(struct batadv_priv *bat_priv)
570 struct hlist_head *head; 577 struct hlist_head *head;
571 uint32_t i; 578 uint32_t i;
572 579
573 if (!bat_priv->tt_local_hash) 580 if (!bat_priv->tt.local_hash)
574 return; 581 return;
575 582
576 hash = bat_priv->tt_local_hash; 583 hash = bat_priv->tt.local_hash;
577 584
578 for (i = 0; i < hash->size; i++) { 585 for (i = 0; i < hash->size; i++) {
579 head = &hash->table[i]; 586 head = &hash->table[i];
@@ -593,17 +600,17 @@ static void batadv_tt_local_table_free(struct batadv_priv *bat_priv)
593 600
594 batadv_hash_destroy(hash); 601 batadv_hash_destroy(hash);
595 602
596 bat_priv->tt_local_hash = NULL; 603 bat_priv->tt.local_hash = NULL;
597} 604}
598 605
599static int batadv_tt_global_init(struct batadv_priv *bat_priv) 606static int batadv_tt_global_init(struct batadv_priv *bat_priv)
600{ 607{
601 if (bat_priv->tt_global_hash) 608 if (bat_priv->tt.global_hash)
602 return 0; 609 return 0;
603 610
604 bat_priv->tt_global_hash = batadv_hash_new(1024); 611 bat_priv->tt.global_hash = batadv_hash_new(1024);
605 612
606 if (!bat_priv->tt_global_hash) 613 if (!bat_priv->tt.global_hash)
607 return -ENOMEM; 614 return -ENOMEM;
608 615
609 return 0; 616 return 0;
@@ -613,62 +620,99 @@ static void batadv_tt_changes_list_free(struct batadv_priv *bat_priv)
613{ 620{
614 struct batadv_tt_change_node *entry, *safe; 621 struct batadv_tt_change_node *entry, *safe;
615 622
616 spin_lock_bh(&bat_priv->tt_changes_list_lock); 623 spin_lock_bh(&bat_priv->tt.changes_list_lock);
617 624
618 list_for_each_entry_safe(entry, safe, &bat_priv->tt_changes_list, 625 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
619 list) { 626 list) {
620 list_del(&entry->list); 627 list_del(&entry->list);
621 kfree(entry); 628 kfree(entry);
622 } 629 }
623 630
624 atomic_set(&bat_priv->tt_local_changes, 0); 631 atomic_set(&bat_priv->tt.local_changes, 0);
625 spin_unlock_bh(&bat_priv->tt_changes_list_lock); 632 spin_unlock_bh(&bat_priv->tt.changes_list_lock);
626} 633}
627 634
628/* find out if an orig_node is already in the list of a tt_global_entry. 635/* retrieves the orig_tt_list_entry belonging to orig_node from the
629 * returns 1 if found, 0 otherwise 636 * batadv_tt_global_entry list
637 *
638 * returns it with an increased refcounter, NULL if not found
630 */ 639 */
631static bool 640static struct batadv_tt_orig_list_entry *
632batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry, 641batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry,
633 const struct batadv_orig_node *orig_node) 642 const struct batadv_orig_node *orig_node)
634{ 643{
635 struct batadv_tt_orig_list_entry *tmp_orig_entry; 644 struct batadv_tt_orig_list_entry *tmp_orig_entry, *orig_entry = NULL;
636 const struct hlist_head *head; 645 const struct hlist_head *head;
637 struct hlist_node *node; 646 struct hlist_node *node;
638 bool found = false;
639 647
640 rcu_read_lock(); 648 rcu_read_lock();
641 head = &entry->orig_list; 649 head = &entry->orig_list;
642 hlist_for_each_entry_rcu(tmp_orig_entry, node, head, list) { 650 hlist_for_each_entry_rcu(tmp_orig_entry, node, head, list) {
643 if (tmp_orig_entry->orig_node == orig_node) { 651 if (tmp_orig_entry->orig_node != orig_node)
644 found = true; 652 continue;
645 break; 653 if (!atomic_inc_not_zero(&tmp_orig_entry->refcount))
646 } 654 continue;
655
656 orig_entry = tmp_orig_entry;
657 break;
647 } 658 }
648 rcu_read_unlock(); 659 rcu_read_unlock();
660
661 return orig_entry;
662}
663
664/* find out if an orig_node is already in the list of a tt_global_entry.
665 * returns true if found, false otherwise
666 */
667static bool
668batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry,
669 const struct batadv_orig_node *orig_node)
670{
671 struct batadv_tt_orig_list_entry *orig_entry;
672 bool found = false;
673
674 orig_entry = batadv_tt_global_orig_entry_find(entry, orig_node);
675 if (orig_entry) {
676 found = true;
677 batadv_tt_orig_list_entry_free_ref(orig_entry);
678 }
679
649 return found; 680 return found;
650} 681}
651 682
652static void 683static void
653batadv_tt_global_add_orig_entry(struct batadv_tt_global_entry *tt_global_entry, 684batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
654 struct batadv_orig_node *orig_node, int ttvn) 685 struct batadv_orig_node *orig_node, int ttvn)
655{ 686{
656 struct batadv_tt_orig_list_entry *orig_entry; 687 struct batadv_tt_orig_list_entry *orig_entry;
657 688
689 orig_entry = batadv_tt_global_orig_entry_find(tt_global, orig_node);
690 if (orig_entry) {
691 /* refresh the ttvn: the current value could be a bogus one that
692 * was added during a "temporary client detection"
693 */
694 orig_entry->ttvn = ttvn;
695 goto out;
696 }
697
658 orig_entry = kzalloc(sizeof(*orig_entry), GFP_ATOMIC); 698 orig_entry = kzalloc(sizeof(*orig_entry), GFP_ATOMIC);
659 if (!orig_entry) 699 if (!orig_entry)
660 return; 700 goto out;
661 701
662 INIT_HLIST_NODE(&orig_entry->list); 702 INIT_HLIST_NODE(&orig_entry->list);
663 atomic_inc(&orig_node->refcount); 703 atomic_inc(&orig_node->refcount);
664 atomic_inc(&orig_node->tt_size); 704 atomic_inc(&orig_node->tt_size);
665 orig_entry->orig_node = orig_node; 705 orig_entry->orig_node = orig_node;
666 orig_entry->ttvn = ttvn; 706 orig_entry->ttvn = ttvn;
707 atomic_set(&orig_entry->refcount, 2);
667 708
668 spin_lock_bh(&tt_global_entry->list_lock); 709 spin_lock_bh(&tt_global->list_lock);
669 hlist_add_head_rcu(&orig_entry->list, 710 hlist_add_head_rcu(&orig_entry->list,
670 &tt_global_entry->orig_list); 711 &tt_global->orig_list);
671 spin_unlock_bh(&tt_global_entry->list_lock); 712 spin_unlock_bh(&tt_global->list_lock);
713out:
714 if (orig_entry)
715 batadv_tt_orig_list_entry_free_ref(orig_entry);
672} 716}
673 717
674/* caller must hold orig_node refcount */ 718/* caller must hold orig_node refcount */
@@ -695,11 +739,12 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv,
695 common->flags = flags; 739 common->flags = flags;
696 tt_global_entry->roam_at = 0; 740 tt_global_entry->roam_at = 0;
697 atomic_set(&common->refcount, 2); 741 atomic_set(&common->refcount, 2);
742 common->added_at = jiffies;
698 743
699 INIT_HLIST_HEAD(&tt_global_entry->orig_list); 744 INIT_HLIST_HEAD(&tt_global_entry->orig_list);
700 spin_lock_init(&tt_global_entry->list_lock); 745 spin_lock_init(&tt_global_entry->list_lock);
701 746
702 hash_added = batadv_hash_add(bat_priv->tt_global_hash, 747 hash_added = batadv_hash_add(bat_priv->tt.global_hash,
703 batadv_compare_tt, 748 batadv_compare_tt,
704 batadv_choose_orig, common, 749 batadv_choose_orig, common,
705 &common->hash_entry); 750 &common->hash_entry);
@@ -709,11 +754,20 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv,
709 batadv_tt_global_entry_free_ref(tt_global_entry); 754 batadv_tt_global_entry_free_ref(tt_global_entry);
710 goto out_remove; 755 goto out_remove;
711 } 756 }
712
713 batadv_tt_global_add_orig_entry(tt_global_entry, orig_node,
714 ttvn);
715 } else { 757 } else {
716 /* there is already a global entry, use this one. */ 758 /* If there is already a global entry, we can use this one for
759 * our processing.
760 * But if we are trying to add a temporary client we can exit
761 * directly because the temporary information should never
762 * override any already known client state (whatever it is)
763 */
764 if (flags & BATADV_TT_CLIENT_TEMP)
765 goto out;
766
767 /* if the client was temporary added before receiving the first
768 * OGM announcing it, we have to clear the TEMP flag
769 */
770 tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_TEMP;
717 771
718 /* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only 772 /* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only
719 * one originator left in the list and we previously received a 773 * one originator left in the list and we previously received a
@@ -727,12 +781,9 @@ int batadv_tt_global_add(struct batadv_priv *bat_priv,
727 tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_ROAM; 781 tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_ROAM;
728 tt_global_entry->roam_at = 0; 782 tt_global_entry->roam_at = 0;
729 } 783 }
730
731 if (!batadv_tt_global_entry_has_orig(tt_global_entry,
732 orig_node))
733 batadv_tt_global_add_orig_entry(tt_global_entry,
734 orig_node, ttvn);
735 } 784 }
785 /* add the new orig_entry (if needed) or update it */
786 batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn);
736 787
737 batadv_dbg(BATADV_DBG_TT, bat_priv, 788 batadv_dbg(BATADV_DBG_TT, bat_priv,
738 "Creating new global tt entry: %pM (via %pM)\n", 789 "Creating new global tt entry: %pM (via %pM)\n",
@@ -771,11 +822,12 @@ batadv_tt_global_print_entry(struct batadv_tt_global_entry *tt_global_entry,
771 hlist_for_each_entry_rcu(orig_entry, node, head, list) { 822 hlist_for_each_entry_rcu(orig_entry, node, head, list) {
772 flags = tt_common_entry->flags; 823 flags = tt_common_entry->flags;
773 last_ttvn = atomic_read(&orig_entry->orig_node->last_ttvn); 824 last_ttvn = atomic_read(&orig_entry->orig_node->last_ttvn);
774 seq_printf(seq, " * %pM (%3u) via %pM (%3u) [%c%c]\n", 825 seq_printf(seq, " * %pM (%3u) via %pM (%3u) [%c%c%c]\n",
775 tt_global_entry->common.addr, orig_entry->ttvn, 826 tt_global_entry->common.addr, orig_entry->ttvn,
776 orig_entry->orig_node->orig, last_ttvn, 827 orig_entry->orig_node->orig, last_ttvn,
777 (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'), 828 (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
778 (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.')); 829 (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
830 (flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.'));
779 } 831 }
780} 832}
781 833
@@ -783,7 +835,7 @@ int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset)
783{ 835{
784 struct net_device *net_dev = (struct net_device *)seq->private; 836 struct net_device *net_dev = (struct net_device *)seq->private;
785 struct batadv_priv *bat_priv = netdev_priv(net_dev); 837 struct batadv_priv *bat_priv = netdev_priv(net_dev);
786 struct batadv_hashtable *hash = bat_priv->tt_global_hash; 838 struct batadv_hashtable *hash = bat_priv->tt.global_hash;
787 struct batadv_tt_common_entry *tt_common_entry; 839 struct batadv_tt_common_entry *tt_common_entry;
788 struct batadv_tt_global_entry *tt_global; 840 struct batadv_tt_global_entry *tt_global;
789 struct batadv_hard_iface *primary_if; 841 struct batadv_hard_iface *primary_if;
@@ -884,7 +936,7 @@ batadv_tt_global_del_struct(struct batadv_priv *bat_priv,
884 "Deleting global tt entry %pM: %s\n", 936 "Deleting global tt entry %pM: %s\n",
885 tt_global_entry->common.addr, message); 937 tt_global_entry->common.addr, message);
886 938
887 batadv_hash_remove(bat_priv->tt_global_hash, batadv_compare_tt, 939 batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt,
888 batadv_choose_orig, tt_global_entry->common.addr); 940 batadv_choose_orig, tt_global_entry->common.addr);
889 batadv_tt_global_entry_free_ref(tt_global_entry); 941 batadv_tt_global_entry_free_ref(tt_global_entry);
890 942
@@ -995,7 +1047,7 @@ void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
995 struct batadv_tt_global_entry *tt_global; 1047 struct batadv_tt_global_entry *tt_global;
996 struct batadv_tt_common_entry *tt_common_entry; 1048 struct batadv_tt_common_entry *tt_common_entry;
997 uint32_t i; 1049 uint32_t i;
998 struct batadv_hashtable *hash = bat_priv->tt_global_hash; 1050 struct batadv_hashtable *hash = bat_priv->tt.global_hash;
999 struct hlist_node *node, *safe; 1051 struct hlist_node *node, *safe;
1000 struct hlist_head *head; 1052 struct hlist_head *head;
1001 spinlock_t *list_lock; /* protects write access to the hash lists */ 1053 spinlock_t *list_lock; /* protects write access to the hash lists */
@@ -1030,49 +1082,63 @@ void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
1030 orig_node->tt_initialised = false; 1082 orig_node->tt_initialised = false;
1031} 1083}
1032 1084
1033static void batadv_tt_global_roam_purge_list(struct batadv_priv *bat_priv, 1085static bool batadv_tt_global_to_purge(struct batadv_tt_global_entry *tt_global,
1034 struct hlist_head *head) 1086 char **msg)
1035{ 1087{
1036 struct batadv_tt_common_entry *tt_common_entry; 1088 bool purge = false;
1037 struct batadv_tt_global_entry *tt_global_entry; 1089 unsigned long roam_timeout = BATADV_TT_CLIENT_ROAM_TIMEOUT;
1038 struct hlist_node *node, *node_tmp; 1090 unsigned long temp_timeout = BATADV_TT_CLIENT_TEMP_TIMEOUT;
1039
1040 hlist_for_each_entry_safe(tt_common_entry, node, node_tmp, head,
1041 hash_entry) {
1042 tt_global_entry = container_of(tt_common_entry,
1043 struct batadv_tt_global_entry,
1044 common);
1045 if (!(tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM))
1046 continue;
1047 if (!batadv_has_timed_out(tt_global_entry->roam_at,
1048 BATADV_TT_CLIENT_ROAM_TIMEOUT))
1049 continue;
1050 1091
1051 batadv_dbg(BATADV_DBG_TT, bat_priv, 1092 if ((tt_global->common.flags & BATADV_TT_CLIENT_ROAM) &&
1052 "Deleting global tt entry (%pM): Roaming timeout\n", 1093 batadv_has_timed_out(tt_global->roam_at, roam_timeout)) {
1053 tt_global_entry->common.addr); 1094 purge = true;
1095 *msg = "Roaming timeout\n";
1096 }
1054 1097
1055 hlist_del_rcu(node); 1098 if ((tt_global->common.flags & BATADV_TT_CLIENT_TEMP) &&
1056 batadv_tt_global_entry_free_ref(tt_global_entry); 1099 batadv_has_timed_out(tt_global->common.added_at, temp_timeout)) {
1100 purge = true;
1101 *msg = "Temporary client timeout\n";
1057 } 1102 }
1103
1104 return purge;
1058} 1105}
1059 1106
1060static void batadv_tt_global_roam_purge(struct batadv_priv *bat_priv) 1107static void batadv_tt_global_purge(struct batadv_priv *bat_priv)
1061{ 1108{
1062 struct batadv_hashtable *hash = bat_priv->tt_global_hash; 1109 struct batadv_hashtable *hash = bat_priv->tt.global_hash;
1063 struct hlist_head *head; 1110 struct hlist_head *head;
1111 struct hlist_node *node, *node_tmp;
1064 spinlock_t *list_lock; /* protects write access to the hash lists */ 1112 spinlock_t *list_lock; /* protects write access to the hash lists */
1065 uint32_t i; 1113 uint32_t i;
1114 char *msg = NULL;
1115 struct batadv_tt_common_entry *tt_common;
1116 struct batadv_tt_global_entry *tt_global;
1066 1117
1067 for (i = 0; i < hash->size; i++) { 1118 for (i = 0; i < hash->size; i++) {
1068 head = &hash->table[i]; 1119 head = &hash->table[i];
1069 list_lock = &hash->list_locks[i]; 1120 list_lock = &hash->list_locks[i];
1070 1121
1071 spin_lock_bh(list_lock); 1122 spin_lock_bh(list_lock);
1072 batadv_tt_global_roam_purge_list(bat_priv, head); 1123 hlist_for_each_entry_safe(tt_common, node, node_tmp, head,
1124 hash_entry) {
1125 tt_global = container_of(tt_common,
1126 struct batadv_tt_global_entry,
1127 common);
1128
1129 if (!batadv_tt_global_to_purge(tt_global, &msg))
1130 continue;
1131
1132 batadv_dbg(BATADV_DBG_TT, bat_priv,
1133 "Deleting global tt entry (%pM): %s\n",
1134 tt_global->common.addr, msg);
1135
1136 hlist_del_rcu(node);
1137
1138 batadv_tt_global_entry_free_ref(tt_global);
1139 }
1073 spin_unlock_bh(list_lock); 1140 spin_unlock_bh(list_lock);
1074 } 1141 }
1075
1076} 1142}
1077 1143
1078static void batadv_tt_global_table_free(struct batadv_priv *bat_priv) 1144static void batadv_tt_global_table_free(struct batadv_priv *bat_priv)
@@ -1085,10 +1151,10 @@ static void batadv_tt_global_table_free(struct batadv_priv *bat_priv)
1085 struct hlist_head *head; 1151 struct hlist_head *head;
1086 uint32_t i; 1152 uint32_t i;
1087 1153
1088 if (!bat_priv->tt_global_hash) 1154 if (!bat_priv->tt.global_hash)
1089 return; 1155 return;
1090 1156
1091 hash = bat_priv->tt_global_hash; 1157 hash = bat_priv->tt.global_hash;
1092 1158
1093 for (i = 0; i < hash->size; i++) { 1159 for (i = 0; i < hash->size; i++) {
1094 head = &hash->table[i]; 1160 head = &hash->table[i];
@@ -1108,7 +1174,7 @@ static void batadv_tt_global_table_free(struct batadv_priv *bat_priv)
1108 1174
1109 batadv_hash_destroy(hash); 1175 batadv_hash_destroy(hash);
1110 1176
1111 bat_priv->tt_global_hash = NULL; 1177 bat_priv->tt.global_hash = NULL;
1112} 1178}
1113 1179
1114static bool 1180static bool
@@ -1187,7 +1253,7 @@ static uint16_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
1187 struct batadv_orig_node *orig_node) 1253 struct batadv_orig_node *orig_node)
1188{ 1254{
1189 uint16_t total = 0, total_one; 1255 uint16_t total = 0, total_one;
1190 struct batadv_hashtable *hash = bat_priv->tt_global_hash; 1256 struct batadv_hashtable *hash = bat_priv->tt.global_hash;
1191 struct batadv_tt_common_entry *tt_common; 1257 struct batadv_tt_common_entry *tt_common;
1192 struct batadv_tt_global_entry *tt_global; 1258 struct batadv_tt_global_entry *tt_global;
1193 struct hlist_node *node; 1259 struct hlist_node *node;
@@ -1210,6 +1276,12 @@ static uint16_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
1210 */ 1276 */
1211 if (tt_common->flags & BATADV_TT_CLIENT_ROAM) 1277 if (tt_common->flags & BATADV_TT_CLIENT_ROAM)
1212 continue; 1278 continue;
1279 /* Temporary clients have not been announced yet, so
1280 * they have to be skipped while computing the global
1281 * crc
1282 */
1283 if (tt_common->flags & BATADV_TT_CLIENT_TEMP)
1284 continue;
1213 1285
1214 /* find out if this global entry is announced by this 1286 /* find out if this global entry is announced by this
1215 * originator 1287 * originator
@@ -1234,7 +1306,7 @@ static uint16_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
1234static uint16_t batadv_tt_local_crc(struct batadv_priv *bat_priv) 1306static uint16_t batadv_tt_local_crc(struct batadv_priv *bat_priv)
1235{ 1307{
1236 uint16_t total = 0, total_one; 1308 uint16_t total = 0, total_one;
1237 struct batadv_hashtable *hash = bat_priv->tt_local_hash; 1309 struct batadv_hashtable *hash = bat_priv->tt.local_hash;
1238 struct batadv_tt_common_entry *tt_common; 1310 struct batadv_tt_common_entry *tt_common;
1239 struct hlist_node *node; 1311 struct hlist_node *node;
1240 struct hlist_head *head; 1312 struct hlist_head *head;
@@ -1267,14 +1339,14 @@ static void batadv_tt_req_list_free(struct batadv_priv *bat_priv)
1267{ 1339{
1268 struct batadv_tt_req_node *node, *safe; 1340 struct batadv_tt_req_node *node, *safe;
1269 1341
1270 spin_lock_bh(&bat_priv->tt_req_list_lock); 1342 spin_lock_bh(&bat_priv->tt.req_list_lock);
1271 1343
1272 list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) { 1344 list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
1273 list_del(&node->list); 1345 list_del(&node->list);
1274 kfree(node); 1346 kfree(node);
1275 } 1347 }
1276 1348
1277 spin_unlock_bh(&bat_priv->tt_req_list_lock); 1349 spin_unlock_bh(&bat_priv->tt.req_list_lock);
1278} 1350}
1279 1351
1280static void batadv_tt_save_orig_buffer(struct batadv_priv *bat_priv, 1352static void batadv_tt_save_orig_buffer(struct batadv_priv *bat_priv,
@@ -1304,15 +1376,15 @@ static void batadv_tt_req_purge(struct batadv_priv *bat_priv)
1304{ 1376{
1305 struct batadv_tt_req_node *node, *safe; 1377 struct batadv_tt_req_node *node, *safe;
1306 1378
1307 spin_lock_bh(&bat_priv->tt_req_list_lock); 1379 spin_lock_bh(&bat_priv->tt.req_list_lock);
1308 list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) { 1380 list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
1309 if (batadv_has_timed_out(node->issued_at, 1381 if (batadv_has_timed_out(node->issued_at,
1310 BATADV_TT_REQUEST_TIMEOUT)) { 1382 BATADV_TT_REQUEST_TIMEOUT)) {
1311 list_del(&node->list); 1383 list_del(&node->list);
1312 kfree(node); 1384 kfree(node);
1313 } 1385 }
1314 } 1386 }
1315 spin_unlock_bh(&bat_priv->tt_req_list_lock); 1387 spin_unlock_bh(&bat_priv->tt.req_list_lock);
1316} 1388}
1317 1389
1318/* returns the pointer to the new tt_req_node struct if no request 1390/* returns the pointer to the new tt_req_node struct if no request
@@ -1324,8 +1396,8 @@ batadv_new_tt_req_node(struct batadv_priv *bat_priv,
1324{ 1396{
1325 struct batadv_tt_req_node *tt_req_node_tmp, *tt_req_node = NULL; 1397 struct batadv_tt_req_node *tt_req_node_tmp, *tt_req_node = NULL;
1326 1398
1327 spin_lock_bh(&bat_priv->tt_req_list_lock); 1399 spin_lock_bh(&bat_priv->tt.req_list_lock);
1328 list_for_each_entry(tt_req_node_tmp, &bat_priv->tt_req_list, list) { 1400 list_for_each_entry(tt_req_node_tmp, &bat_priv->tt.req_list, list) {
1329 if (batadv_compare_eth(tt_req_node_tmp, orig_node) && 1401 if (batadv_compare_eth(tt_req_node_tmp, orig_node) &&
1330 !batadv_has_timed_out(tt_req_node_tmp->issued_at, 1402 !batadv_has_timed_out(tt_req_node_tmp->issued_at,
1331 BATADV_TT_REQUEST_TIMEOUT)) 1403 BATADV_TT_REQUEST_TIMEOUT))
@@ -1339,9 +1411,9 @@ batadv_new_tt_req_node(struct batadv_priv *bat_priv,
1339 memcpy(tt_req_node->addr, orig_node->orig, ETH_ALEN); 1411 memcpy(tt_req_node->addr, orig_node->orig, ETH_ALEN);
1340 tt_req_node->issued_at = jiffies; 1412 tt_req_node->issued_at = jiffies;
1341 1413
1342 list_add(&tt_req_node->list, &bat_priv->tt_req_list); 1414 list_add(&tt_req_node->list, &bat_priv->tt.req_list);
1343unlock: 1415unlock:
1344 spin_unlock_bh(&bat_priv->tt_req_list_lock); 1416 spin_unlock_bh(&bat_priv->tt.req_list_lock);
1345 return tt_req_node; 1417 return tt_req_node;
1346} 1418}
1347 1419
@@ -1363,7 +1435,8 @@ static int batadv_tt_global_valid(const void *entry_ptr,
1363 const struct batadv_tt_global_entry *tt_global_entry; 1435 const struct batadv_tt_global_entry *tt_global_entry;
1364 const struct batadv_orig_node *orig_node = data_ptr; 1436 const struct batadv_orig_node *orig_node = data_ptr;
1365 1437
1366 if (tt_common_entry->flags & BATADV_TT_CLIENT_ROAM) 1438 if (tt_common_entry->flags & BATADV_TT_CLIENT_ROAM ||
1439 tt_common_entry->flags & BATADV_TT_CLIENT_TEMP)
1367 return 0; 1440 return 0;
1368 1441
1369 tt_global_entry = container_of(tt_common_entry, 1442 tt_global_entry = container_of(tt_common_entry,
@@ -1507,9 +1580,9 @@ out:
1507 if (ret) 1580 if (ret)
1508 kfree_skb(skb); 1581 kfree_skb(skb);
1509 if (ret && tt_req_node) { 1582 if (ret && tt_req_node) {
1510 spin_lock_bh(&bat_priv->tt_req_list_lock); 1583 spin_lock_bh(&bat_priv->tt.req_list_lock);
1511 list_del(&tt_req_node->list); 1584 list_del(&tt_req_node->list);
1512 spin_unlock_bh(&bat_priv->tt_req_list_lock); 1585 spin_unlock_bh(&bat_priv->tt.req_list_lock);
1513 kfree(tt_req_node); 1586 kfree(tt_req_node);
1514 } 1587 }
1515 return ret; 1588 return ret;
@@ -1530,6 +1603,7 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv,
1530 uint16_t tt_len, tt_tot; 1603 uint16_t tt_len, tt_tot;
1531 struct sk_buff *skb = NULL; 1604 struct sk_buff *skb = NULL;
1532 struct batadv_tt_query_packet *tt_response; 1605 struct batadv_tt_query_packet *tt_response;
1606 uint8_t *packet_pos;
1533 size_t len; 1607 size_t len;
1534 1608
1535 batadv_dbg(BATADV_DBG_TT, bat_priv, 1609 batadv_dbg(BATADV_DBG_TT, bat_priv,
@@ -1583,8 +1657,8 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv,
1583 goto unlock; 1657 goto unlock;
1584 1658
1585 skb_reserve(skb, ETH_HLEN); 1659 skb_reserve(skb, ETH_HLEN);
1586 tt_response = (struct batadv_tt_query_packet *)skb_put(skb, 1660 packet_pos = skb_put(skb, len);
1587 len); 1661 tt_response = (struct batadv_tt_query_packet *)packet_pos;
1588 tt_response->ttvn = req_ttvn; 1662 tt_response->ttvn = req_ttvn;
1589 tt_response->tt_data = htons(tt_tot); 1663 tt_response->tt_data = htons(tt_tot);
1590 1664
@@ -1600,7 +1674,7 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv,
1600 ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn); 1674 ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn);
1601 1675
1602 skb = batadv_tt_response_fill_table(tt_len, ttvn, 1676 skb = batadv_tt_response_fill_table(tt_len, ttvn,
1603 bat_priv->tt_global_hash, 1677 bat_priv->tt.global_hash,
1604 primary_if, 1678 primary_if,
1605 batadv_tt_global_valid, 1679 batadv_tt_global_valid,
1606 req_dst_orig_node); 1680 req_dst_orig_node);
@@ -1663,6 +1737,7 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
1663 uint16_t tt_len, tt_tot; 1737 uint16_t tt_len, tt_tot;
1664 struct sk_buff *skb = NULL; 1738 struct sk_buff *skb = NULL;
1665 struct batadv_tt_query_packet *tt_response; 1739 struct batadv_tt_query_packet *tt_response;
1740 uint8_t *packet_pos;
1666 size_t len; 1741 size_t len;
1667 1742
1668 batadv_dbg(BATADV_DBG_TT, bat_priv, 1743 batadv_dbg(BATADV_DBG_TT, bat_priv,
@@ -1671,7 +1746,7 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
1671 (tt_request->flags & BATADV_TT_FULL_TABLE ? 'F' : '.')); 1746 (tt_request->flags & BATADV_TT_FULL_TABLE ? 'F' : '.'));
1672 1747
1673 1748
1674 my_ttvn = (uint8_t)atomic_read(&bat_priv->ttvn); 1749 my_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
1675 req_ttvn = tt_request->ttvn; 1750 req_ttvn = tt_request->ttvn;
1676 1751
1677 orig_node = batadv_orig_hash_find(bat_priv, tt_request->src); 1752 orig_node = batadv_orig_hash_find(bat_priv, tt_request->src);
@@ -1690,7 +1765,7 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
1690 * is too big send the whole local translation table 1765 * is too big send the whole local translation table
1691 */ 1766 */
1692 if (tt_request->flags & BATADV_TT_FULL_TABLE || my_ttvn != req_ttvn || 1767 if (tt_request->flags & BATADV_TT_FULL_TABLE || my_ttvn != req_ttvn ||
1693 !bat_priv->tt_buff) 1768 !bat_priv->tt.last_changeset)
1694 full_table = true; 1769 full_table = true;
1695 else 1770 else
1696 full_table = false; 1771 full_table = false;
@@ -1699,8 +1774,8 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
1699 * I'll send only one packet with as much TT entries as I can 1774 * I'll send only one packet with as much TT entries as I can
1700 */ 1775 */
1701 if (!full_table) { 1776 if (!full_table) {
1702 spin_lock_bh(&bat_priv->tt_buff_lock); 1777 spin_lock_bh(&bat_priv->tt.last_changeset_lock);
1703 tt_len = bat_priv->tt_buff_len; 1778 tt_len = bat_priv->tt.last_changeset_len;
1704 tt_tot = tt_len / sizeof(struct batadv_tt_change); 1779 tt_tot = tt_len / sizeof(struct batadv_tt_change);
1705 1780
1706 len = sizeof(*tt_response) + tt_len; 1781 len = sizeof(*tt_response) + tt_len;
@@ -1709,22 +1784,22 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
1709 goto unlock; 1784 goto unlock;
1710 1785
1711 skb_reserve(skb, ETH_HLEN); 1786 skb_reserve(skb, ETH_HLEN);
1712 tt_response = (struct batadv_tt_query_packet *)skb_put(skb, 1787 packet_pos = skb_put(skb, len);
1713 len); 1788 tt_response = (struct batadv_tt_query_packet *)packet_pos;
1714 tt_response->ttvn = req_ttvn; 1789 tt_response->ttvn = req_ttvn;
1715 tt_response->tt_data = htons(tt_tot); 1790 tt_response->tt_data = htons(tt_tot);
1716 1791
1717 tt_buff = skb->data + sizeof(*tt_response); 1792 tt_buff = skb->data + sizeof(*tt_response);
1718 memcpy(tt_buff, bat_priv->tt_buff, 1793 memcpy(tt_buff, bat_priv->tt.last_changeset,
1719 bat_priv->tt_buff_len); 1794 bat_priv->tt.last_changeset_len);
1720 spin_unlock_bh(&bat_priv->tt_buff_lock); 1795 spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
1721 } else { 1796 } else {
1722 tt_len = (uint16_t)atomic_read(&bat_priv->num_local_tt); 1797 tt_len = (uint16_t)atomic_read(&bat_priv->tt.local_entry_num);
1723 tt_len *= sizeof(struct batadv_tt_change); 1798 tt_len *= sizeof(struct batadv_tt_change);
1724 ttvn = (uint8_t)atomic_read(&bat_priv->ttvn); 1799 ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
1725 1800
1726 skb = batadv_tt_response_fill_table(tt_len, ttvn, 1801 skb = batadv_tt_response_fill_table(tt_len, ttvn,
1727 bat_priv->tt_local_hash, 1802 bat_priv->tt.local_hash,
1728 primary_if, 1803 primary_if,
1729 batadv_tt_local_valid_entry, 1804 batadv_tt_local_valid_entry,
1730 NULL); 1805 NULL);
@@ -1756,7 +1831,7 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
1756 goto out; 1831 goto out;
1757 1832
1758unlock: 1833unlock:
1759 spin_unlock_bh(&bat_priv->tt_buff_lock); 1834 spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
1760out: 1835out:
1761 if (orig_node) 1836 if (orig_node)
1762 batadv_orig_node_free_ref(orig_node); 1837 batadv_orig_node_free_ref(orig_node);
@@ -1909,14 +1984,14 @@ void batadv_handle_tt_response(struct batadv_priv *bat_priv,
1909 } 1984 }
1910 1985
1911 /* Delete the tt_req_node from pending tt_requests list */ 1986 /* Delete the tt_req_node from pending tt_requests list */
1912 spin_lock_bh(&bat_priv->tt_req_list_lock); 1987 spin_lock_bh(&bat_priv->tt.req_list_lock);
1913 list_for_each_entry_safe(node, safe, &bat_priv->tt_req_list, list) { 1988 list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
1914 if (!batadv_compare_eth(node->addr, tt_response->src)) 1989 if (!batadv_compare_eth(node->addr, tt_response->src))
1915 continue; 1990 continue;
1916 list_del(&node->list); 1991 list_del(&node->list);
1917 kfree(node); 1992 kfree(node);
1918 } 1993 }
1919 spin_unlock_bh(&bat_priv->tt_req_list_lock); 1994 spin_unlock_bh(&bat_priv->tt.req_list_lock);
1920 1995
1921 /* Recalculate the CRC for this orig_node and store it */ 1996 /* Recalculate the CRC for this orig_node and store it */
1922 orig_node->tt_crc = batadv_tt_global_crc(bat_priv, orig_node); 1997 orig_node->tt_crc = batadv_tt_global_crc(bat_priv, orig_node);
@@ -1950,22 +2025,22 @@ static void batadv_tt_roam_list_free(struct batadv_priv *bat_priv)
1950{ 2025{
1951 struct batadv_tt_roam_node *node, *safe; 2026 struct batadv_tt_roam_node *node, *safe;
1952 2027
1953 spin_lock_bh(&bat_priv->tt_roam_list_lock); 2028 spin_lock_bh(&bat_priv->tt.roam_list_lock);
1954 2029
1955 list_for_each_entry_safe(node, safe, &bat_priv->tt_roam_list, list) { 2030 list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) {
1956 list_del(&node->list); 2031 list_del(&node->list);
1957 kfree(node); 2032 kfree(node);
1958 } 2033 }
1959 2034
1960 spin_unlock_bh(&bat_priv->tt_roam_list_lock); 2035 spin_unlock_bh(&bat_priv->tt.roam_list_lock);
1961} 2036}
1962 2037
1963static void batadv_tt_roam_purge(struct batadv_priv *bat_priv) 2038static void batadv_tt_roam_purge(struct batadv_priv *bat_priv)
1964{ 2039{
1965 struct batadv_tt_roam_node *node, *safe; 2040 struct batadv_tt_roam_node *node, *safe;
1966 2041
1967 spin_lock_bh(&bat_priv->tt_roam_list_lock); 2042 spin_lock_bh(&bat_priv->tt.roam_list_lock);
1968 list_for_each_entry_safe(node, safe, &bat_priv->tt_roam_list, list) { 2043 list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) {
1969 if (!batadv_has_timed_out(node->first_time, 2044 if (!batadv_has_timed_out(node->first_time,
1970 BATADV_ROAMING_MAX_TIME)) 2045 BATADV_ROAMING_MAX_TIME))
1971 continue; 2046 continue;
@@ -1973,7 +2048,7 @@ static void batadv_tt_roam_purge(struct batadv_priv *bat_priv)
1973 list_del(&node->list); 2048 list_del(&node->list);
1974 kfree(node); 2049 kfree(node);
1975 } 2050 }
1976 spin_unlock_bh(&bat_priv->tt_roam_list_lock); 2051 spin_unlock_bh(&bat_priv->tt.roam_list_lock);
1977} 2052}
1978 2053
1979/* This function checks whether the client already reached the 2054/* This function checks whether the client already reached the
@@ -1988,11 +2063,11 @@ static bool batadv_tt_check_roam_count(struct batadv_priv *bat_priv,
1988 struct batadv_tt_roam_node *tt_roam_node; 2063 struct batadv_tt_roam_node *tt_roam_node;
1989 bool ret = false; 2064 bool ret = false;
1990 2065
1991 spin_lock_bh(&bat_priv->tt_roam_list_lock); 2066 spin_lock_bh(&bat_priv->tt.roam_list_lock);
1992 /* The new tt_req will be issued only if I'm not waiting for a 2067 /* The new tt_req will be issued only if I'm not waiting for a
1993 * reply from the same orig_node yet 2068 * reply from the same orig_node yet
1994 */ 2069 */
1995 list_for_each_entry(tt_roam_node, &bat_priv->tt_roam_list, list) { 2070 list_for_each_entry(tt_roam_node, &bat_priv->tt.roam_list, list) {
1996 if (!batadv_compare_eth(tt_roam_node->addr, client)) 2071 if (!batadv_compare_eth(tt_roam_node->addr, client))
1997 continue; 2072 continue;
1998 2073
@@ -2017,12 +2092,12 @@ static bool batadv_tt_check_roam_count(struct batadv_priv *bat_priv,
2017 BATADV_ROAMING_MAX_COUNT - 1); 2092 BATADV_ROAMING_MAX_COUNT - 1);
2018 memcpy(tt_roam_node->addr, client, ETH_ALEN); 2093 memcpy(tt_roam_node->addr, client, ETH_ALEN);
2019 2094
2020 list_add(&tt_roam_node->list, &bat_priv->tt_roam_list); 2095 list_add(&tt_roam_node->list, &bat_priv->tt.roam_list);
2021 ret = true; 2096 ret = true;
2022 } 2097 }
2023 2098
2024unlock: 2099unlock:
2025 spin_unlock_bh(&bat_priv->tt_roam_list_lock); 2100 spin_unlock_bh(&bat_priv->tt.roam_list_lock);
2026 return ret; 2101 return ret;
2027} 2102}
2028 2103
@@ -2086,13 +2161,15 @@ out:
2086static void batadv_tt_purge(struct work_struct *work) 2161static void batadv_tt_purge(struct work_struct *work)
2087{ 2162{
2088 struct delayed_work *delayed_work; 2163 struct delayed_work *delayed_work;
2164 struct batadv_priv_tt *priv_tt;
2089 struct batadv_priv *bat_priv; 2165 struct batadv_priv *bat_priv;
2090 2166
2091 delayed_work = container_of(work, struct delayed_work, work); 2167 delayed_work = container_of(work, struct delayed_work, work);
2092 bat_priv = container_of(delayed_work, struct batadv_priv, tt_work); 2168 priv_tt = container_of(delayed_work, struct batadv_priv_tt, work);
2169 bat_priv = container_of(priv_tt, struct batadv_priv, tt);
2093 2170
2094 batadv_tt_local_purge(bat_priv); 2171 batadv_tt_local_purge(bat_priv);
2095 batadv_tt_global_roam_purge(bat_priv); 2172 batadv_tt_global_purge(bat_priv);
2096 batadv_tt_req_purge(bat_priv); 2173 batadv_tt_req_purge(bat_priv);
2097 batadv_tt_roam_purge(bat_priv); 2174 batadv_tt_roam_purge(bat_priv);
2098 2175
@@ -2101,7 +2178,7 @@ static void batadv_tt_purge(struct work_struct *work)
2101 2178
2102void batadv_tt_free(struct batadv_priv *bat_priv) 2179void batadv_tt_free(struct batadv_priv *bat_priv)
2103{ 2180{
2104 cancel_delayed_work_sync(&bat_priv->tt_work); 2181 cancel_delayed_work_sync(&bat_priv->tt.work);
2105 2182
2106 batadv_tt_local_table_free(bat_priv); 2183 batadv_tt_local_table_free(bat_priv);
2107 batadv_tt_global_table_free(bat_priv); 2184 batadv_tt_global_table_free(bat_priv);
@@ -2109,7 +2186,7 @@ void batadv_tt_free(struct batadv_priv *bat_priv)
2109 batadv_tt_changes_list_free(bat_priv); 2186 batadv_tt_changes_list_free(bat_priv);
2110 batadv_tt_roam_list_free(bat_priv); 2187 batadv_tt_roam_list_free(bat_priv);
2111 2188
2112 kfree(bat_priv->tt_buff); 2189 kfree(bat_priv->tt.last_changeset);
2113} 2190}
2114 2191
2115/* This function will enable or disable the specified flags for all the entries 2192/* This function will enable or disable the specified flags for all the entries
@@ -2153,7 +2230,7 @@ out:
2153/* Purge out all the tt local entries marked with BATADV_TT_CLIENT_PENDING */ 2230/* Purge out all the tt local entries marked with BATADV_TT_CLIENT_PENDING */
2154static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv) 2231static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
2155{ 2232{
2156 struct batadv_hashtable *hash = bat_priv->tt_local_hash; 2233 struct batadv_hashtable *hash = bat_priv->tt.local_hash;
2157 struct batadv_tt_common_entry *tt_common; 2234 struct batadv_tt_common_entry *tt_common;
2158 struct batadv_tt_local_entry *tt_local; 2235 struct batadv_tt_local_entry *tt_local;
2159 struct hlist_node *node, *node_tmp; 2236 struct hlist_node *node, *node_tmp;
@@ -2178,7 +2255,7 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
2178 "Deleting local tt entry (%pM): pending\n", 2255 "Deleting local tt entry (%pM): pending\n",
2179 tt_common->addr); 2256 tt_common->addr);
2180 2257
2181 atomic_dec(&bat_priv->num_local_tt); 2258 atomic_dec(&bat_priv->tt.local_entry_num);
2182 hlist_del_rcu(node); 2259 hlist_del_rcu(node);
2183 tt_local = container_of(tt_common, 2260 tt_local = container_of(tt_common,
2184 struct batadv_tt_local_entry, 2261 struct batadv_tt_local_entry,
@@ -2196,26 +2273,26 @@ static int batadv_tt_commit_changes(struct batadv_priv *bat_priv,
2196{ 2273{
2197 uint16_t changed_num = 0; 2274 uint16_t changed_num = 0;
2198 2275
2199 if (atomic_read(&bat_priv->tt_local_changes) < 1) 2276 if (atomic_read(&bat_priv->tt.local_changes) < 1)
2200 return -ENOENT; 2277 return -ENOENT;
2201 2278
2202 changed_num = batadv_tt_set_flags(bat_priv->tt_local_hash, 2279 changed_num = batadv_tt_set_flags(bat_priv->tt.local_hash,
2203 BATADV_TT_CLIENT_NEW, false); 2280 BATADV_TT_CLIENT_NEW, false);
2204 2281
2205 /* all reset entries have to be counted as local entries */ 2282 /* all reset entries have to be counted as local entries */
2206 atomic_add(changed_num, &bat_priv->num_local_tt); 2283 atomic_add(changed_num, &bat_priv->tt.local_entry_num);
2207 batadv_tt_local_purge_pending_clients(bat_priv); 2284 batadv_tt_local_purge_pending_clients(bat_priv);
2208 bat_priv->tt_crc = batadv_tt_local_crc(bat_priv); 2285 bat_priv->tt.local_crc = batadv_tt_local_crc(bat_priv);
2209 2286
2210 /* Increment the TTVN only once per OGM interval */ 2287 /* Increment the TTVN only once per OGM interval */
2211 atomic_inc(&bat_priv->ttvn); 2288 atomic_inc(&bat_priv->tt.vn);
2212 batadv_dbg(BATADV_DBG_TT, bat_priv, 2289 batadv_dbg(BATADV_DBG_TT, bat_priv,
2213 "Local changes committed, updating to ttvn %u\n", 2290 "Local changes committed, updating to ttvn %u\n",
2214 (uint8_t)atomic_read(&bat_priv->ttvn)); 2291 (uint8_t)atomic_read(&bat_priv->tt.vn));
2215 bat_priv->tt_poss_change = false; 2292 bat_priv->tt.poss_change = false;
2216 2293
2217 /* reset the sending counter */ 2294 /* reset the sending counter */
2218 atomic_set(&bat_priv->tt_ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX); 2295 atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX);
2219 2296
2220 return batadv_tt_changes_fill_buff(bat_priv, packet_buff, 2297 return batadv_tt_changes_fill_buff(bat_priv, packet_buff,
2221 packet_buff_len, packet_min_len); 2298 packet_buff_len, packet_min_len);
@@ -2235,7 +2312,7 @@ int batadv_tt_append_diff(struct batadv_priv *bat_priv,
2235 2312
2236 /* if the changes have been sent often enough */ 2313 /* if the changes have been sent often enough */
2237 if ((tt_num_changes < 0) && 2314 if ((tt_num_changes < 0) &&
2238 (!batadv_atomic_dec_not_zero(&bat_priv->tt_ogm_append_cnt))) { 2315 (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt))) {
2239 batadv_tt_realloc_packet_buff(packet_buff, packet_buff_len, 2316 batadv_tt_realloc_packet_buff(packet_buff, packet_buff_len,
2240 packet_min_len, packet_min_len); 2317 packet_min_len, packet_min_len);
2241 tt_num_changes = 0; 2318 tt_num_changes = 0;
@@ -2366,3 +2443,22 @@ bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv,
2366out: 2443out:
2367 return ret; 2444 return ret;
2368} 2445}
2446
2447bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
2448 struct batadv_orig_node *orig_node,
2449 const unsigned char *addr)
2450{
2451 bool ret = false;
2452
2453 if (!batadv_tt_global_add(bat_priv, orig_node, addr,
2454 BATADV_TT_CLIENT_TEMP,
2455 atomic_read(&orig_node->last_ttvn)))
2456 goto out;
2457
2458 batadv_dbg(BATADV_DBG_TT, bat_priv,
2459 "Added temporary global client (addr: %pM orig: %pM)\n",
2460 addr, orig_node->orig);
2461 ret = true;
2462out:
2463 return ret;
2464}