1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include "main.h"
21#include "translation-table.h"
22#include "soft-interface.h"
23#include "hard-interface.h"
24#include "send.h"
25#include "hash.h"
26#include "originator.h"
27#include "routing.h"
28#include "bridge_loop_avoidance.h"
29
30#include <linux/crc32c.h>
31
32
33static struct lock_class_key batadv_tt_local_hash_lock_class_key;
34static struct lock_class_key batadv_tt_global_hash_lock_class_key;
35
36static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
37 unsigned short vid,
38 struct batadv_orig_node *orig_node);
39static void batadv_tt_purge(struct work_struct *work);
40static void
41batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry);
42static void batadv_tt_global_del(struct batadv_priv *bat_priv,
43 struct batadv_orig_node *orig_node,
44 const unsigned char *addr,
45 unsigned short vid, const char *message,
46 bool roaming);
47
48
49static int batadv_compare_tt(const struct hlist_node *node, const void *data2)
50{
51 const void *data1 = container_of(node, struct batadv_tt_common_entry,
52 hash_entry);
53
54 return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0);
55}
56
57
58
59
60
61
62
63
64
65static inline uint32_t batadv_choose_tt(const void *data, uint32_t size)
66{
67 struct batadv_tt_common_entry *tt;
68 uint32_t hash = 0;
69
70 tt = (struct batadv_tt_common_entry *)data;
71 hash = batadv_hash_bytes(hash, &tt->addr, ETH_ALEN);
72 hash = batadv_hash_bytes(hash, &tt->vid, sizeof(tt->vid));
73
74 hash += (hash << 3);
75 hash ^= (hash >> 11);
76 hash += (hash << 15);
77
78 return hash % size;
79}
80
81
82
83
84
85
86
87
88
89
90static struct batadv_tt_common_entry *
91batadv_tt_hash_find(struct batadv_hashtable *hash, const uint8_t *addr,
92 unsigned short vid)
93{
94 struct hlist_head *head;
95 struct batadv_tt_common_entry to_search, *tt, *tt_tmp = NULL;
96 uint32_t index;
97
98 if (!hash)
99 return NULL;
100
101 memcpy(to_search.addr, addr, ETH_ALEN);
102 to_search.vid = vid;
103
104 index = batadv_choose_tt(&to_search, hash->size);
105 head = &hash->table[index];
106
107 rcu_read_lock();
108 hlist_for_each_entry_rcu(tt, head, hash_entry) {
109 if (!batadv_compare_eth(tt, addr))
110 continue;
111
112 if (tt->vid != vid)
113 continue;
114
115 if (!atomic_inc_not_zero(&tt->refcount))
116 continue;
117
118 tt_tmp = tt;
119 break;
120 }
121 rcu_read_unlock();
122
123 return tt_tmp;
124}
125
126
127
128
129
130
131
132
133
134
135static struct batadv_tt_local_entry *
136batadv_tt_local_hash_find(struct batadv_priv *bat_priv, const uint8_t *addr,
137 unsigned short vid)
138{
139 struct batadv_tt_common_entry *tt_common_entry;
140 struct batadv_tt_local_entry *tt_local_entry = NULL;
141
142 tt_common_entry = batadv_tt_hash_find(bat_priv->tt.local_hash, addr,
143 vid);
144 if (tt_common_entry)
145 tt_local_entry = container_of(tt_common_entry,
146 struct batadv_tt_local_entry,
147 common);
148 return tt_local_entry;
149}
150
151
152
153
154
155
156
157
158
159
160static struct batadv_tt_global_entry *
161batadv_tt_global_hash_find(struct batadv_priv *bat_priv, const uint8_t *addr,
162 unsigned short vid)
163{
164 struct batadv_tt_common_entry *tt_common_entry;
165 struct batadv_tt_global_entry *tt_global_entry = NULL;
166
167 tt_common_entry = batadv_tt_hash_find(bat_priv->tt.global_hash, addr,
168 vid);
169 if (tt_common_entry)
170 tt_global_entry = container_of(tt_common_entry,
171 struct batadv_tt_global_entry,
172 common);
173 return tt_global_entry;
174}
175
176static void
177batadv_tt_local_entry_free_ref(struct batadv_tt_local_entry *tt_local_entry)
178{
179 if (atomic_dec_and_test(&tt_local_entry->common.refcount))
180 kfree_rcu(tt_local_entry, common.rcu);
181}
182
183
184
185
186
187
188static void
189batadv_tt_global_entry_free_ref(struct batadv_tt_global_entry *tt_global_entry)
190{
191 if (atomic_dec_and_test(&tt_global_entry->common.refcount)) {
192 batadv_tt_global_del_orig_list(tt_global_entry);
193 kfree_rcu(tt_global_entry, common.rcu);
194 }
195}
196
197static void batadv_tt_orig_list_entry_free_rcu(struct rcu_head *rcu)
198{
199 struct batadv_tt_orig_list_entry *orig_entry;
200
201 orig_entry = container_of(rcu, struct batadv_tt_orig_list_entry, rcu);
202
203
204
205
206
207 batadv_orig_node_free_ref_now(orig_entry->orig_node);
208 kfree(orig_entry);
209}
210
211
212
213
214
215
216
217
218static void batadv_tt_local_size_mod(struct batadv_priv *bat_priv,
219 unsigned short vid, int v)
220{
221 struct batadv_softif_vlan *vlan;
222
223 vlan = batadv_softif_vlan_get(bat_priv, vid);
224 if (!vlan)
225 return;
226
227 atomic_add(v, &vlan->tt.num_entries);
228
229 batadv_softif_vlan_free_ref(vlan);
230}
231
232
233
234
235
236
237
238static void batadv_tt_local_size_inc(struct batadv_priv *bat_priv,
239 unsigned short vid)
240{
241 batadv_tt_local_size_mod(bat_priv, vid, 1);
242}
243
244
245
246
247
248
249
250static void batadv_tt_local_size_dec(struct batadv_priv *bat_priv,
251 unsigned short vid)
252{
253 batadv_tt_local_size_mod(bat_priv, vid, -1);
254}
255
256
257
258
259
260
261
262
263static void batadv_tt_global_size_mod(struct batadv_orig_node *orig_node,
264 unsigned short vid, int v)
265{
266 struct batadv_orig_node_vlan *vlan;
267
268 vlan = batadv_orig_node_vlan_new(orig_node, vid);
269 if (!vlan)
270 return;
271
272 if (atomic_add_return(v, &vlan->tt.num_entries) == 0) {
273 spin_lock_bh(&orig_node->vlan_list_lock);
274 list_del_rcu(&vlan->list);
275 spin_unlock_bh(&orig_node->vlan_list_lock);
276 batadv_orig_node_vlan_free_ref(vlan);
277 }
278
279 batadv_orig_node_vlan_free_ref(vlan);
280}
281
282
283
284
285
286
287
288static void batadv_tt_global_size_inc(struct batadv_orig_node *orig_node,
289 unsigned short vid)
290{
291 batadv_tt_global_size_mod(orig_node, vid, 1);
292}
293
294
295
296
297
298
299
300static void batadv_tt_global_size_dec(struct batadv_orig_node *orig_node,
301 unsigned short vid)
302{
303 batadv_tt_global_size_mod(orig_node, vid, -1);
304}
305
306static void
307batadv_tt_orig_list_entry_free_ref(struct batadv_tt_orig_list_entry *orig_entry)
308{
309 if (!atomic_dec_and_test(&orig_entry->refcount))
310 return;
311
312 call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu);
313}
314
315
316
317
318
319
320
321static void batadv_tt_local_event(struct batadv_priv *bat_priv,
322 struct batadv_tt_local_entry *tt_local_entry,
323 uint8_t event_flags)
324{
325 struct batadv_tt_change_node *tt_change_node, *entry, *safe;
326 struct batadv_tt_common_entry *common = &tt_local_entry->common;
327 uint8_t flags = common->flags | event_flags;
328 bool event_removed = false;
329 bool del_op_requested, del_op_entry;
330
331 tt_change_node = kmalloc(sizeof(*tt_change_node), GFP_ATOMIC);
332 if (!tt_change_node)
333 return;
334
335 tt_change_node->change.flags = flags;
336 memset(tt_change_node->change.reserved, 0,
337 sizeof(tt_change_node->change.reserved));
338 memcpy(tt_change_node->change.addr, common->addr, ETH_ALEN);
339 tt_change_node->change.vid = htons(common->vid);
340
341 del_op_requested = flags & BATADV_TT_CLIENT_DEL;
342
343
344 spin_lock_bh(&bat_priv->tt.changes_list_lock);
345 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
346 list) {
347 if (!batadv_compare_eth(entry->change.addr, common->addr))
348 continue;
349
350
351
352
353
354
355
356
357 del_op_entry = entry->change.flags & BATADV_TT_CLIENT_DEL;
358 if (!del_op_requested && del_op_entry)
359 goto del;
360 if (del_op_requested && !del_op_entry)
361 goto del;
362
363
364
365
366 if (!del_op_requested && !del_op_entry)
367 entry->change.flags = flags;
368
369 continue;
370del:
371 list_del(&entry->list);
372 kfree(entry);
373 kfree(tt_change_node);
374 event_removed = true;
375 goto unlock;
376 }
377
378
379 list_add_tail(&tt_change_node->list, &bat_priv->tt.changes_list);
380
381unlock:
382 spin_unlock_bh(&bat_priv->tt.changes_list_lock);
383
384 if (event_removed)
385 atomic_dec(&bat_priv->tt.local_changes);
386 else
387 atomic_inc(&bat_priv->tt.local_changes);
388}
389
390
391
392
393
394
395
396static int batadv_tt_len(int changes_num)
397{
398 return changes_num * sizeof(struct batadv_tvlv_tt_change);
399}
400
401
402
403
404
405
406
407static uint16_t batadv_tt_entries(uint16_t tt_len)
408{
409 return tt_len / batadv_tt_len(1);
410}
411
412
413
414
415
416
417
418
419static int batadv_tt_local_table_transmit_size(struct batadv_priv *bat_priv)
420{
421 uint16_t num_vlan = 0, tt_local_entries = 0;
422 struct batadv_softif_vlan *vlan;
423 int hdr_size;
424
425 rcu_read_lock();
426 hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
427 num_vlan++;
428 tt_local_entries += atomic_read(&vlan->tt.num_entries);
429 }
430 rcu_read_unlock();
431
432
433 hdr_size = sizeof(struct batadv_unicast_tvlv_packet);
434 hdr_size += sizeof(struct batadv_tvlv_hdr);
435 hdr_size += sizeof(struct batadv_tvlv_tt_data);
436 hdr_size += num_vlan * sizeof(struct batadv_tvlv_tt_vlan_data);
437
438 return hdr_size + batadv_tt_len(tt_local_entries);
439}
440
441static int batadv_tt_local_init(struct batadv_priv *bat_priv)
442{
443 if (bat_priv->tt.local_hash)
444 return 0;
445
446 bat_priv->tt.local_hash = batadv_hash_new(1024);
447
448 if (!bat_priv->tt.local_hash)
449 return -ENOMEM;
450
451 batadv_hash_set_lock_class(bat_priv->tt.local_hash,
452 &batadv_tt_local_hash_lock_class_key);
453
454 return 0;
455}
456
457static void batadv_tt_global_free(struct batadv_priv *bat_priv,
458 struct batadv_tt_global_entry *tt_global,
459 const char *message)
460{
461 batadv_dbg(BATADV_DBG_TT, bat_priv,
462 "Deleting global tt entry %pM (vid: %d): %s\n",
463 tt_global->common.addr,
464 BATADV_PRINT_VID(tt_global->common.vid), message);
465
466 batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt,
467 batadv_choose_tt, &tt_global->common);
468 batadv_tt_global_entry_free_ref(tt_global);
469}
470
471
472
473
474
475
476
477
478
479
480
481
482bool batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
483 unsigned short vid, int ifindex)
484{
485 struct batadv_priv *bat_priv = netdev_priv(soft_iface);
486 struct batadv_tt_local_entry *tt_local;
487 struct batadv_tt_global_entry *tt_global;
488 struct net_device *in_dev = NULL;
489 struct hlist_head *head;
490 struct batadv_tt_orig_list_entry *orig_entry;
491 int hash_added, table_size, packet_size_max;
492 bool ret = false, roamed_back = false;
493 uint8_t remote_flags;
494
495 if (ifindex != BATADV_NULL_IFINDEX)
496 in_dev = dev_get_by_index(&init_net, ifindex);
497
498 tt_local = batadv_tt_local_hash_find(bat_priv, addr, vid);
499 tt_global = batadv_tt_global_hash_find(bat_priv, addr, vid);
500
501 if (tt_local) {
502 tt_local->last_seen = jiffies;
503 if (tt_local->common.flags & BATADV_TT_CLIENT_PENDING) {
504 batadv_dbg(BATADV_DBG_TT, bat_priv,
505 "Re-adding pending client %pM (vid: %d)\n",
506 addr, BATADV_PRINT_VID(vid));
507
508
509
510
511
512 tt_local->common.flags &= ~BATADV_TT_CLIENT_PENDING;
513 goto add_event;
514 }
515
516 if (tt_local->common.flags & BATADV_TT_CLIENT_ROAM) {
517 batadv_dbg(BATADV_DBG_TT, bat_priv,
518 "Roaming client %pM (vid: %d) came back to its original location\n",
519 addr, BATADV_PRINT_VID(vid));
520
521
522
523
524
525 tt_local->common.flags &= ~BATADV_TT_CLIENT_ROAM;
526 roamed_back = true;
527 }
528 goto check_roaming;
529 }
530
531
532 table_size = batadv_tt_local_table_transmit_size(bat_priv);
533 table_size += batadv_tt_len(1);
534 packet_size_max = atomic_read(&bat_priv->packet_size_max);
535 if (table_size > packet_size_max) {
536 net_ratelimited_function(batadv_info, soft_iface,
537 "Local translation table size (%i) exceeds maximum packet size (%i); Ignoring new local tt entry: %pM\n",
538 table_size, packet_size_max, addr);
539 goto out;
540 }
541
542 tt_local = kmalloc(sizeof(*tt_local), GFP_ATOMIC);
543 if (!tt_local)
544 goto out;
545
546 batadv_dbg(BATADV_DBG_TT, bat_priv,
547 "Creating new local tt entry: %pM (vid: %d, ttvn: %d)\n",
548 addr, BATADV_PRINT_VID(vid),
549 (uint8_t)atomic_read(&bat_priv->tt.vn));
550
551 memcpy(tt_local->common.addr, addr, ETH_ALEN);
552
553
554
555
556 tt_local->common.flags = BATADV_TT_CLIENT_NEW;
557 tt_local->common.vid = vid;
558 if (batadv_is_wifi_netdev(in_dev))
559 tt_local->common.flags |= BATADV_TT_CLIENT_WIFI;
560 atomic_set(&tt_local->common.refcount, 2);
561 tt_local->last_seen = jiffies;
562 tt_local->common.added_at = tt_local->last_seen;
563
564
565 if (batadv_compare_eth(addr, soft_iface->dev_addr))
566 tt_local->common.flags |= BATADV_TT_CLIENT_NOPURGE;
567
568 hash_added = batadv_hash_add(bat_priv->tt.local_hash, batadv_compare_tt,
569 batadv_choose_tt, &tt_local->common,
570 &tt_local->common.hash_entry);
571
572 if (unlikely(hash_added != 0)) {
573
574 batadv_tt_local_entry_free_ref(tt_local);
575 goto out;
576 }
577
578add_event:
579 batadv_tt_local_event(bat_priv, tt_local, BATADV_NO_FLAGS);
580
581check_roaming:
582
583
584
585 if (tt_global && !(tt_global->common.flags & BATADV_TT_CLIENT_ROAM)) {
586
587 head = &tt_global->orig_list;
588 rcu_read_lock();
589 hlist_for_each_entry_rcu(orig_entry, head, list) {
590 batadv_send_roam_adv(bat_priv, tt_global->common.addr,
591 tt_global->common.vid,
592 orig_entry->orig_node);
593 }
594 rcu_read_unlock();
595 if (roamed_back) {
596 batadv_tt_global_free(bat_priv, tt_global,
597 "Roaming canceled");
598 tt_global = NULL;
599 } else {
600
601
602
603 tt_global->common.flags |= BATADV_TT_CLIENT_ROAM;
604 tt_global->roam_at = jiffies;
605 }
606 }
607
608
609
610
611 remote_flags = tt_local->common.flags & BATADV_TT_REMOTE_MASK;
612
613 if (batadv_is_wifi_netdev(in_dev))
614 tt_local->common.flags |= BATADV_TT_CLIENT_WIFI;
615 else
616 tt_local->common.flags &= ~BATADV_TT_CLIENT_WIFI;
617
618
619
620
621 if (remote_flags ^ (tt_local->common.flags & BATADV_TT_REMOTE_MASK))
622 batadv_tt_local_event(bat_priv, tt_local, BATADV_NO_FLAGS);
623
624 ret = true;
625out:
626 if (in_dev)
627 dev_put(in_dev);
628 if (tt_local)
629 batadv_tt_local_entry_free_ref(tt_local);
630 if (tt_global)
631 batadv_tt_global_entry_free_ref(tt_global);
632 return ret;
633}
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653static uint16_t
654batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node,
655 struct batadv_tvlv_tt_data **tt_data,
656 struct batadv_tvlv_tt_change **tt_change,
657 int32_t *tt_len)
658{
659 uint16_t num_vlan = 0, num_entries = 0, change_offset, tvlv_len;
660 struct batadv_tvlv_tt_vlan_data *tt_vlan;
661 struct batadv_orig_node_vlan *vlan;
662 uint8_t *tt_change_ptr;
663
664 rcu_read_lock();
665 list_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) {
666 num_vlan++;
667 num_entries += atomic_read(&vlan->tt.num_entries);
668 }
669
670 change_offset = sizeof(**tt_data);
671 change_offset += num_vlan * sizeof(*tt_vlan);
672
673
674 if (*tt_len < 0)
675 *tt_len = batadv_tt_len(num_entries);
676
677 tvlv_len = *tt_len;
678 tvlv_len += change_offset;
679
680 *tt_data = kmalloc(tvlv_len, GFP_ATOMIC);
681 if (!*tt_data) {
682 *tt_len = 0;
683 goto out;
684 }
685
686 (*tt_data)->flags = BATADV_NO_FLAGS;
687 (*tt_data)->ttvn = atomic_read(&orig_node->last_ttvn);
688 (*tt_data)->num_vlan = htons(num_vlan);
689
690 tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(*tt_data + 1);
691 list_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) {
692 tt_vlan->vid = htons(vlan->vid);
693 tt_vlan->crc = htonl(vlan->tt.crc);
694
695 tt_vlan++;
696 }
697
698 tt_change_ptr = (uint8_t *)*tt_data + change_offset;
699 *tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr;
700
701out:
702 rcu_read_unlock();
703 return tvlv_len;
704}
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724static uint16_t
725batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
726 struct batadv_tvlv_tt_data **tt_data,
727 struct batadv_tvlv_tt_change **tt_change,
728 int32_t *tt_len)
729{
730 struct batadv_tvlv_tt_vlan_data *tt_vlan;
731 struct batadv_softif_vlan *vlan;
732 uint16_t num_vlan = 0, num_entries = 0, tvlv_len;
733 uint8_t *tt_change_ptr;
734 int change_offset;
735
736 rcu_read_lock();
737 hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
738 num_vlan++;
739 num_entries += atomic_read(&vlan->tt.num_entries);
740 }
741
742 change_offset = sizeof(**tt_data);
743 change_offset += num_vlan * sizeof(*tt_vlan);
744
745
746 if (*tt_len < 0)
747 *tt_len = batadv_tt_len(num_entries);
748
749 tvlv_len = *tt_len;
750 tvlv_len += change_offset;
751
752 *tt_data = kmalloc(tvlv_len, GFP_ATOMIC);
753 if (!*tt_data) {
754 tvlv_len = 0;
755 goto out;
756 }
757
758 (*tt_data)->flags = BATADV_NO_FLAGS;
759 (*tt_data)->ttvn = atomic_read(&bat_priv->tt.vn);
760 (*tt_data)->num_vlan = htons(num_vlan);
761
762 tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(*tt_data + 1);
763 hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
764 tt_vlan->vid = htons(vlan->vid);
765 tt_vlan->crc = htonl(vlan->tt.crc);
766
767 tt_vlan++;
768 }
769
770 tt_change_ptr = (uint8_t *)*tt_data + change_offset;
771 *tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr;
772
773out:
774 rcu_read_unlock();
775 return tvlv_len;
776}
777
778
779
780
781
782
783static void batadv_tt_tvlv_container_update(struct batadv_priv *bat_priv)
784{
785 struct batadv_tt_change_node *entry, *safe;
786 struct batadv_tvlv_tt_data *tt_data;
787 struct batadv_tvlv_tt_change *tt_change;
788 int tt_diff_len, tt_change_len = 0;
789 int tt_diff_entries_num = 0, tt_diff_entries_count = 0;
790 uint16_t tvlv_len;
791
792 tt_diff_entries_num = atomic_read(&bat_priv->tt.local_changes);
793 tt_diff_len = batadv_tt_len(tt_diff_entries_num);
794
795
796
797
798 if (tt_diff_len > bat_priv->soft_iface->mtu)
799 tt_diff_len = 0;
800
801 tvlv_len = batadv_tt_prepare_tvlv_local_data(bat_priv, &tt_data,
802 &tt_change, &tt_diff_len);
803 if (!tvlv_len)
804 return;
805
806 tt_data->flags = BATADV_TT_OGM_DIFF;
807
808 if (tt_diff_len == 0)
809 goto container_register;
810
811 spin_lock_bh(&bat_priv->tt.changes_list_lock);
812 atomic_set(&bat_priv->tt.local_changes, 0);
813
814 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
815 list) {
816 if (tt_diff_entries_count < tt_diff_entries_num) {
817 memcpy(tt_change + tt_diff_entries_count,
818 &entry->change,
819 sizeof(struct batadv_tvlv_tt_change));
820 tt_diff_entries_count++;
821 }
822 list_del(&entry->list);
823 kfree(entry);
824 }
825 spin_unlock_bh(&bat_priv->tt.changes_list_lock);
826
827
828 spin_lock_bh(&bat_priv->tt.last_changeset_lock);
829 kfree(bat_priv->tt.last_changeset);
830 bat_priv->tt.last_changeset_len = 0;
831 bat_priv->tt.last_changeset = NULL;
832 tt_change_len = batadv_tt_len(tt_diff_entries_count);
833
834 if (tt_diff_entries_count > 0) {
835
836
837
838 bat_priv->tt.last_changeset = kzalloc(tt_diff_len, GFP_ATOMIC);
839 if (bat_priv->tt.last_changeset) {
840 memcpy(bat_priv->tt.last_changeset,
841 tt_change, tt_change_len);
842 bat_priv->tt.last_changeset_len = tt_diff_len;
843 }
844 }
845 spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
846
847container_register:
848 batadv_tvlv_container_register(bat_priv, BATADV_TVLV_TT, 1, tt_data,
849 tvlv_len);
850 kfree(tt_data);
851}
852
853int batadv_tt_local_seq_print_text(struct seq_file *seq, void *offset)
854{
855 struct net_device *net_dev = (struct net_device *)seq->private;
856 struct batadv_priv *bat_priv = netdev_priv(net_dev);
857 struct batadv_hashtable *hash = bat_priv->tt.local_hash;
858 struct batadv_tt_common_entry *tt_common_entry;
859 struct batadv_tt_local_entry *tt_local;
860 struct batadv_hard_iface *primary_if;
861 struct batadv_softif_vlan *vlan;
862 struct hlist_head *head;
863 unsigned short vid;
864 uint32_t i;
865 int last_seen_secs;
866 int last_seen_msecs;
867 unsigned long last_seen_jiffies;
868 bool no_purge;
869 uint16_t np_flag = BATADV_TT_CLIENT_NOPURGE;
870
871 primary_if = batadv_seq_print_text_primary_if_get(seq);
872 if (!primary_if)
873 goto out;
874
875 seq_printf(seq,
876 "Locally retrieved addresses (from %s) announced via TT (TTVN: %u):\n",
877 net_dev->name, (uint8_t)atomic_read(&bat_priv->tt.vn));
878 seq_printf(seq, " %-13s %s %-7s %-9s (%-10s)\n", "Client", "VID",
879 "Flags", "Last seen", "CRC");
880
881 for (i = 0; i < hash->size; i++) {
882 head = &hash->table[i];
883
884 rcu_read_lock();
885 hlist_for_each_entry_rcu(tt_common_entry,
886 head, hash_entry) {
887 tt_local = container_of(tt_common_entry,
888 struct batadv_tt_local_entry,
889 common);
890 vid = tt_common_entry->vid;
891 last_seen_jiffies = jiffies - tt_local->last_seen;
892 last_seen_msecs = jiffies_to_msecs(last_seen_jiffies);
893 last_seen_secs = last_seen_msecs / 1000;
894 last_seen_msecs = last_seen_msecs % 1000;
895
896 no_purge = tt_common_entry->flags & np_flag;
897
898 vlan = batadv_softif_vlan_get(bat_priv, vid);
899 if (!vlan) {
900 seq_printf(seq, "Cannot retrieve VLAN %d\n",
901 BATADV_PRINT_VID(vid));
902 continue;
903 }
904
905 seq_printf(seq,
906 " * %pM %4i [%c%c%c%c%c] %3u.%03u (%#.8x)\n",
907 tt_common_entry->addr,
908 BATADV_PRINT_VID(tt_common_entry->vid),
909 (tt_common_entry->flags &
910 BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
911 no_purge ? 'P' : '.',
912 (tt_common_entry->flags &
913 BATADV_TT_CLIENT_NEW ? 'N' : '.'),
914 (tt_common_entry->flags &
915 BATADV_TT_CLIENT_PENDING ? 'X' : '.'),
916 (tt_common_entry->flags &
917 BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
918 no_purge ? 0 : last_seen_secs,
919 no_purge ? 0 : last_seen_msecs,
920 vlan->tt.crc);
921
922 batadv_softif_vlan_free_ref(vlan);
923 }
924 rcu_read_unlock();
925 }
926out:
927 if (primary_if)
928 batadv_hardif_free_ref(primary_if);
929 return 0;
930}
931
932static void
933batadv_tt_local_set_pending(struct batadv_priv *bat_priv,
934 struct batadv_tt_local_entry *tt_local_entry,
935 uint16_t flags, const char *message)
936{
937 batadv_tt_local_event(bat_priv, tt_local_entry, flags);
938
939
940
941
942
943 tt_local_entry->common.flags |= BATADV_TT_CLIENT_PENDING;
944
945 batadv_dbg(BATADV_DBG_TT, bat_priv,
946 "Local tt entry (%pM, vid: %d) pending to be removed: %s\n",
947 tt_local_entry->common.addr,
948 BATADV_PRINT_VID(tt_local_entry->common.vid), message);
949}
950
951
952
953
954
955
956
957
958
959
960
961uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
962 const uint8_t *addr, unsigned short vid,
963 const char *message, bool roaming)
964{
965 struct batadv_tt_local_entry *tt_local_entry;
966 uint16_t flags, curr_flags = BATADV_NO_FLAGS;
967
968 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
969 if (!tt_local_entry)
970 goto out;
971
972 curr_flags = tt_local_entry->common.flags;
973
974 flags = BATADV_TT_CLIENT_DEL;
975
976
977
978
979 if (roaming) {
980 flags |= BATADV_TT_CLIENT_ROAM;
981
982 tt_local_entry->common.flags |= BATADV_TT_CLIENT_ROAM;
983 }
984
985 if (!(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW)) {
986 batadv_tt_local_set_pending(bat_priv, tt_local_entry, flags,
987 message);
988 goto out;
989 }
990
991
992
993 batadv_tt_local_event(bat_priv, tt_local_entry, BATADV_TT_CLIENT_DEL);
994 hlist_del_rcu(&tt_local_entry->common.hash_entry);
995 batadv_tt_local_entry_free_ref(tt_local_entry);
996
997out:
998 if (tt_local_entry)
999 batadv_tt_local_entry_free_ref(tt_local_entry);
1000
1001 return curr_flags;
1002}
1003
1004
1005
1006
1007
1008
1009
1010
1011static void batadv_tt_local_purge_list(struct batadv_priv *bat_priv,
1012 struct hlist_head *head,
1013 int timeout)
1014{
1015 struct batadv_tt_local_entry *tt_local_entry;
1016 struct batadv_tt_common_entry *tt_common_entry;
1017 struct hlist_node *node_tmp;
1018
1019 hlist_for_each_entry_safe(tt_common_entry, node_tmp, head,
1020 hash_entry) {
1021 tt_local_entry = container_of(tt_common_entry,
1022 struct batadv_tt_local_entry,
1023 common);
1024 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_NOPURGE)
1025 continue;
1026
1027
1028 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING)
1029 continue;
1030
1031 if (!batadv_has_timed_out(tt_local_entry->last_seen, timeout))
1032 continue;
1033
1034 batadv_tt_local_set_pending(bat_priv, tt_local_entry,
1035 BATADV_TT_CLIENT_DEL, "timed out");
1036 }
1037}
1038
1039
1040
1041
1042
1043
1044
1045static void batadv_tt_local_purge(struct batadv_priv *bat_priv,
1046 int timeout)
1047{
1048 struct batadv_hashtable *hash = bat_priv->tt.local_hash;
1049 struct hlist_head *head;
1050 spinlock_t *list_lock;
1051 uint32_t i;
1052
1053 for (i = 0; i < hash->size; i++) {
1054 head = &hash->table[i];
1055 list_lock = &hash->list_locks[i];
1056
1057 spin_lock_bh(list_lock);
1058 batadv_tt_local_purge_list(bat_priv, head, timeout);
1059 spin_unlock_bh(list_lock);
1060 }
1061}
1062
1063static void batadv_tt_local_table_free(struct batadv_priv *bat_priv)
1064{
1065 struct batadv_hashtable *hash;
1066 spinlock_t *list_lock;
1067 struct batadv_tt_common_entry *tt_common_entry;
1068 struct batadv_tt_local_entry *tt_local;
1069 struct hlist_node *node_tmp;
1070 struct hlist_head *head;
1071 uint32_t i;
1072
1073 if (!bat_priv->tt.local_hash)
1074 return;
1075
1076 hash = bat_priv->tt.local_hash;
1077
1078 for (i = 0; i < hash->size; i++) {
1079 head = &hash->table[i];
1080 list_lock = &hash->list_locks[i];
1081
1082 spin_lock_bh(list_lock);
1083 hlist_for_each_entry_safe(tt_common_entry, node_tmp,
1084 head, hash_entry) {
1085 hlist_del_rcu(&tt_common_entry->hash_entry);
1086 tt_local = container_of(tt_common_entry,
1087 struct batadv_tt_local_entry,
1088 common);
1089 batadv_tt_local_entry_free_ref(tt_local);
1090 }
1091 spin_unlock_bh(list_lock);
1092 }
1093
1094 batadv_hash_destroy(hash);
1095
1096 bat_priv->tt.local_hash = NULL;
1097}
1098
1099static int batadv_tt_global_init(struct batadv_priv *bat_priv)
1100{
1101 if (bat_priv->tt.global_hash)
1102 return 0;
1103
1104 bat_priv->tt.global_hash = batadv_hash_new(1024);
1105
1106 if (!bat_priv->tt.global_hash)
1107 return -ENOMEM;
1108
1109 batadv_hash_set_lock_class(bat_priv->tt.global_hash,
1110 &batadv_tt_global_hash_lock_class_key);
1111
1112 return 0;
1113}
1114
1115static void batadv_tt_changes_list_free(struct batadv_priv *bat_priv)
1116{
1117 struct batadv_tt_change_node *entry, *safe;
1118
1119 spin_lock_bh(&bat_priv->tt.changes_list_lock);
1120
1121 list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
1122 list) {
1123 list_del(&entry->list);
1124 kfree(entry);
1125 }
1126
1127 atomic_set(&bat_priv->tt.local_changes, 0);
1128 spin_unlock_bh(&bat_priv->tt.changes_list_lock);
1129}
1130
1131
1132
1133
1134
1135
1136static struct batadv_tt_orig_list_entry *
1137batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry,
1138 const struct batadv_orig_node *orig_node)
1139{
1140 struct batadv_tt_orig_list_entry *tmp_orig_entry, *orig_entry = NULL;
1141 const struct hlist_head *head;
1142
1143 rcu_read_lock();
1144 head = &entry->orig_list;
1145 hlist_for_each_entry_rcu(tmp_orig_entry, head, list) {
1146 if (tmp_orig_entry->orig_node != orig_node)
1147 continue;
1148 if (!atomic_inc_not_zero(&tmp_orig_entry->refcount))
1149 continue;
1150
1151 orig_entry = tmp_orig_entry;
1152 break;
1153 }
1154 rcu_read_unlock();
1155
1156 return orig_entry;
1157}
1158
1159
1160
1161
1162static bool
1163batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry,
1164 const struct batadv_orig_node *orig_node)
1165{
1166 struct batadv_tt_orig_list_entry *orig_entry;
1167 bool found = false;
1168
1169 orig_entry = batadv_tt_global_orig_entry_find(entry, orig_node);
1170 if (orig_entry) {
1171 found = true;
1172 batadv_tt_orig_list_entry_free_ref(orig_entry);
1173 }
1174
1175 return found;
1176}
1177
1178static void
1179batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
1180 struct batadv_orig_node *orig_node, int ttvn)
1181{
1182 struct batadv_tt_orig_list_entry *orig_entry;
1183
1184 orig_entry = batadv_tt_global_orig_entry_find(tt_global, orig_node);
1185 if (orig_entry) {
1186
1187
1188
1189 orig_entry->ttvn = ttvn;
1190 goto out;
1191 }
1192
1193 orig_entry = kzalloc(sizeof(*orig_entry), GFP_ATOMIC);
1194 if (!orig_entry)
1195 goto out;
1196
1197 INIT_HLIST_NODE(&orig_entry->list);
1198 atomic_inc(&orig_node->refcount);
1199 batadv_tt_global_size_inc(orig_node, tt_global->common.vid);
1200 orig_entry->orig_node = orig_node;
1201 orig_entry->ttvn = ttvn;
1202 atomic_set(&orig_entry->refcount, 2);
1203
1204 spin_lock_bh(&tt_global->list_lock);
1205 hlist_add_head_rcu(&orig_entry->list,
1206 &tt_global->orig_list);
1207 spin_unlock_bh(&tt_global->list_lock);
1208out:
1209 if (orig_entry)
1210 batadv_tt_orig_list_entry_free_ref(orig_entry);
1211}
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
1233 struct batadv_orig_node *orig_node,
1234 const unsigned char *tt_addr,
1235 unsigned short vid, uint16_t flags,
1236 uint8_t ttvn)
1237{
1238 struct batadv_tt_global_entry *tt_global_entry;
1239 struct batadv_tt_local_entry *tt_local_entry;
1240 bool ret = false;
1241 int hash_added;
1242 struct batadv_tt_common_entry *common;
1243 uint16_t local_flags;
1244
1245
1246 if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, vid))
1247 return true;
1248
1249 tt_global_entry = batadv_tt_global_hash_find(bat_priv, tt_addr, vid);
1250 tt_local_entry = batadv_tt_local_hash_find(bat_priv, tt_addr, vid);
1251
1252
1253
1254
1255
1256 if ((flags & BATADV_TT_CLIENT_TEMP) && tt_local_entry &&
1257 !(tt_local_entry->common.flags & BATADV_TT_CLIENT_NEW))
1258 goto out;
1259
1260 if (!tt_global_entry) {
1261 tt_global_entry = kzalloc(sizeof(*tt_global_entry), GFP_ATOMIC);
1262 if (!tt_global_entry)
1263 goto out;
1264
1265 common = &tt_global_entry->common;
1266 memcpy(common->addr, tt_addr, ETH_ALEN);
1267 common->vid = vid;
1268
1269 common->flags = flags;
1270 tt_global_entry->roam_at = 0;
1271
1272
1273
1274
1275 if (flags & BATADV_TT_CLIENT_ROAM)
1276 tt_global_entry->roam_at = jiffies;
1277 atomic_set(&common->refcount, 2);
1278 common->added_at = jiffies;
1279
1280 INIT_HLIST_HEAD(&tt_global_entry->orig_list);
1281 spin_lock_init(&tt_global_entry->list_lock);
1282
1283 hash_added = batadv_hash_add(bat_priv->tt.global_hash,
1284 batadv_compare_tt,
1285 batadv_choose_tt, common,
1286 &common->hash_entry);
1287
1288 if (unlikely(hash_added != 0)) {
1289
1290 batadv_tt_global_entry_free_ref(tt_global_entry);
1291 goto out_remove;
1292 }
1293 } else {
1294 common = &tt_global_entry->common;
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305 if (flags & BATADV_TT_CLIENT_TEMP) {
1306 if (!(common->flags & BATADV_TT_CLIENT_TEMP))
1307 goto out;
1308 if (batadv_tt_global_entry_has_orig(tt_global_entry,
1309 orig_node))
1310 goto out_remove;
1311 batadv_tt_global_del_orig_list(tt_global_entry);
1312 goto add_orig_entry;
1313 }
1314
1315
1316
1317
1318 common->flags &= ~BATADV_TT_CLIENT_TEMP;
1319
1320
1321
1322
1323
1324 tt_global_entry->common.flags |= flags;
1325
1326
1327
1328
1329
1330
1331
1332
1333 if (common->flags & BATADV_TT_CLIENT_ROAM) {
1334 batadv_tt_global_del_orig_list(tt_global_entry);
1335 common->flags &= ~BATADV_TT_CLIENT_ROAM;
1336 tt_global_entry->roam_at = 0;
1337 }
1338 }
1339add_orig_entry:
1340
1341 batadv_tt_global_orig_entry_add(tt_global_entry, orig_node, ttvn);
1342
1343 batadv_dbg(BATADV_DBG_TT, bat_priv,
1344 "Creating new global tt entry: %pM (vid: %d, via %pM)\n",
1345 common->addr, BATADV_PRINT_VID(common->vid),
1346 orig_node->orig);
1347 ret = true;
1348
1349out_remove:
1350
1351
1352 local_flags = batadv_tt_local_remove(bat_priv, tt_addr, vid,
1353 "global tt received",
1354 flags & BATADV_TT_CLIENT_ROAM);
1355 tt_global_entry->common.flags |= local_flags & BATADV_TT_CLIENT_WIFI;
1356
1357 if (!(flags & BATADV_TT_CLIENT_ROAM))
1358
1359
1360
1361 tt_global_entry->common.flags &= ~BATADV_TT_CLIENT_ROAM;
1362
1363out:
1364 if (tt_global_entry)
1365 batadv_tt_global_entry_free_ref(tt_global_entry);
1366 if (tt_local_entry)
1367 batadv_tt_local_entry_free_ref(tt_local_entry);
1368 return ret;
1369}
1370
1371
1372
1373
1374
1375
1376
1377
1378static struct batadv_tt_orig_list_entry *
1379batadv_transtable_best_orig(struct batadv_priv *bat_priv,
1380 struct batadv_tt_global_entry *tt_global_entry)
1381{
1382 struct batadv_neigh_node *router, *best_router = NULL;
1383 struct batadv_algo_ops *bao = bat_priv->bat_algo_ops;
1384 struct hlist_head *head;
1385 struct batadv_tt_orig_list_entry *orig_entry, *best_entry = NULL;
1386
1387 head = &tt_global_entry->orig_list;
1388 hlist_for_each_entry_rcu(orig_entry, head, list) {
1389 router = batadv_orig_node_get_router(orig_entry->orig_node);
1390 if (!router)
1391 continue;
1392
1393 if (best_router &&
1394 bao->bat_neigh_cmp(router, best_router) <= 0) {
1395 batadv_neigh_node_free_ref(router);
1396 continue;
1397 }
1398
1399
1400 if (best_router)
1401 batadv_neigh_node_free_ref(best_router);
1402
1403 best_entry = orig_entry;
1404 best_router = router;
1405 }
1406
1407 if (best_router)
1408 batadv_neigh_node_free_ref(best_router);
1409
1410 return best_entry;
1411}
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421static void
1422batadv_tt_global_print_entry(struct batadv_priv *bat_priv,
1423 struct batadv_tt_global_entry *tt_global_entry,
1424 struct seq_file *seq)
1425{
1426 struct batadv_tt_orig_list_entry *orig_entry, *best_entry;
1427 struct batadv_tt_common_entry *tt_common_entry;
1428 struct batadv_orig_node_vlan *vlan;
1429 struct hlist_head *head;
1430 uint8_t last_ttvn;
1431 uint16_t flags;
1432
1433 tt_common_entry = &tt_global_entry->common;
1434 flags = tt_common_entry->flags;
1435
1436 best_entry = batadv_transtable_best_orig(bat_priv, tt_global_entry);
1437 if (best_entry) {
1438 vlan = batadv_orig_node_vlan_get(best_entry->orig_node,
1439 tt_common_entry->vid);
1440 if (!vlan) {
1441 seq_printf(seq,
1442 " * Cannot retrieve VLAN %d for originator %pM\n",
1443 BATADV_PRINT_VID(tt_common_entry->vid),
1444 best_entry->orig_node->orig);
1445 goto print_list;
1446 }
1447
1448 last_ttvn = atomic_read(&best_entry->orig_node->last_ttvn);
1449 seq_printf(seq,
1450 " %c %pM %4i (%3u) via %pM (%3u) (%#.8x) [%c%c%c]\n",
1451 '*', tt_global_entry->common.addr,
1452 BATADV_PRINT_VID(tt_global_entry->common.vid),
1453 best_entry->ttvn, best_entry->orig_node->orig,
1454 last_ttvn, vlan->tt.crc,
1455 (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
1456 (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
1457 (flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.'));
1458
1459 batadv_orig_node_vlan_free_ref(vlan);
1460 }
1461
1462print_list:
1463 head = &tt_global_entry->orig_list;
1464
1465 hlist_for_each_entry_rcu(orig_entry, head, list) {
1466 if (best_entry == orig_entry)
1467 continue;
1468
1469 vlan = batadv_orig_node_vlan_get(orig_entry->orig_node,
1470 tt_common_entry->vid);
1471 if (!vlan) {
1472 seq_printf(seq,
1473 " + Cannot retrieve VLAN %d for originator %pM\n",
1474 BATADV_PRINT_VID(tt_common_entry->vid),
1475 orig_entry->orig_node->orig);
1476 continue;
1477 }
1478
1479 last_ttvn = atomic_read(&orig_entry->orig_node->last_ttvn);
1480 seq_printf(seq,
1481 " %c %pM %4d (%3u) via %pM (%3u) (%#.8x) [%c%c%c]\n",
1482 '+', tt_global_entry->common.addr,
1483 BATADV_PRINT_VID(tt_global_entry->common.vid),
1484 orig_entry->ttvn, orig_entry->orig_node->orig,
1485 last_ttvn, vlan->tt.crc,
1486 (flags & BATADV_TT_CLIENT_ROAM ? 'R' : '.'),
1487 (flags & BATADV_TT_CLIENT_WIFI ? 'W' : '.'),
1488 (flags & BATADV_TT_CLIENT_TEMP ? 'T' : '.'));
1489
1490 batadv_orig_node_vlan_free_ref(vlan);
1491 }
1492}
1493
1494int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset)
1495{
1496 struct net_device *net_dev = (struct net_device *)seq->private;
1497 struct batadv_priv *bat_priv = netdev_priv(net_dev);
1498 struct batadv_hashtable *hash = bat_priv->tt.global_hash;
1499 struct batadv_tt_common_entry *tt_common_entry;
1500 struct batadv_tt_global_entry *tt_global;
1501 struct batadv_hard_iface *primary_if;
1502 struct hlist_head *head;
1503 uint32_t i;
1504
1505 primary_if = batadv_seq_print_text_primary_if_get(seq);
1506 if (!primary_if)
1507 goto out;
1508
1509 seq_printf(seq,
1510 "Globally announced TT entries received via the mesh %s\n",
1511 net_dev->name);
1512 seq_printf(seq, " %-13s %s %s %-15s %s (%-10s) %s\n",
1513 "Client", "VID", "(TTVN)", "Originator", "(Curr TTVN)",
1514 "CRC", "Flags");
1515
1516 for (i = 0; i < hash->size; i++) {
1517 head = &hash->table[i];
1518
1519 rcu_read_lock();
1520 hlist_for_each_entry_rcu(tt_common_entry,
1521 head, hash_entry) {
1522 tt_global = container_of(tt_common_entry,
1523 struct batadv_tt_global_entry,
1524 common);
1525 batadv_tt_global_print_entry(bat_priv, tt_global, seq);
1526 }
1527 rcu_read_unlock();
1528 }
1529out:
1530 if (primary_if)
1531 batadv_hardif_free_ref(primary_if);
1532 return 0;
1533}
1534
1535
1536static void
1537batadv_tt_global_del_orig_list(struct batadv_tt_global_entry *tt_global_entry)
1538{
1539 struct hlist_head *head;
1540 struct hlist_node *safe;
1541 struct batadv_tt_orig_list_entry *orig_entry;
1542
1543 spin_lock_bh(&tt_global_entry->list_lock);
1544 head = &tt_global_entry->orig_list;
1545 hlist_for_each_entry_safe(orig_entry, safe, head, list) {
1546 hlist_del_rcu(&orig_entry->list);
1547 batadv_tt_global_size_dec(orig_entry->orig_node,
1548 tt_global_entry->common.vid);
1549 batadv_tt_orig_list_entry_free_ref(orig_entry);
1550 }
1551 spin_unlock_bh(&tt_global_entry->list_lock);
1552}
1553
1554static void
1555batadv_tt_global_del_orig_entry(struct batadv_priv *bat_priv,
1556 struct batadv_tt_global_entry *tt_global_entry,
1557 struct batadv_orig_node *orig_node,
1558 const char *message)
1559{
1560 struct hlist_head *head;
1561 struct hlist_node *safe;
1562 struct batadv_tt_orig_list_entry *orig_entry;
1563 unsigned short vid;
1564
1565 spin_lock_bh(&tt_global_entry->list_lock);
1566 head = &tt_global_entry->orig_list;
1567 hlist_for_each_entry_safe(orig_entry, safe, head, list) {
1568 if (orig_entry->orig_node == orig_node) {
1569 vid = tt_global_entry->common.vid;
1570 batadv_dbg(BATADV_DBG_TT, bat_priv,
1571 "Deleting %pM from global tt entry %pM (vid: %d): %s\n",
1572 orig_node->orig,
1573 tt_global_entry->common.addr,
1574 BATADV_PRINT_VID(vid), message);
1575 hlist_del_rcu(&orig_entry->list);
1576 batadv_tt_global_size_dec(orig_node,
1577 tt_global_entry->common.vid);
1578 batadv_tt_orig_list_entry_free_ref(orig_entry);
1579 }
1580 }
1581 spin_unlock_bh(&tt_global_entry->list_lock);
1582}
1583
1584
1585
1586
1587
1588static void
1589batadv_tt_global_del_roaming(struct batadv_priv *bat_priv,
1590 struct batadv_tt_global_entry *tt_global_entry,
1591 struct batadv_orig_node *orig_node,
1592 const char *message)
1593{
1594 bool last_entry = true;
1595 struct hlist_head *head;
1596 struct batadv_tt_orig_list_entry *orig_entry;
1597
1598
1599
1600
1601
1602 rcu_read_lock();
1603 head = &tt_global_entry->orig_list;
1604 hlist_for_each_entry_rcu(orig_entry, head, list) {
1605 if (orig_entry->orig_node != orig_node) {
1606 last_entry = false;
1607 break;
1608 }
1609 }
1610 rcu_read_unlock();
1611
1612 if (last_entry) {
1613
1614 tt_global_entry->common.flags |= BATADV_TT_CLIENT_ROAM;
1615 tt_global_entry->roam_at = jiffies;
1616 } else
1617
1618
1619
1620 batadv_tt_global_del_orig_entry(bat_priv, tt_global_entry,
1621 orig_node, message);
1622}
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634static void batadv_tt_global_del(struct batadv_priv *bat_priv,
1635 struct batadv_orig_node *orig_node,
1636 const unsigned char *addr, unsigned short vid,
1637 const char *message, bool roaming)
1638{
1639 struct batadv_tt_global_entry *tt_global_entry;
1640 struct batadv_tt_local_entry *local_entry = NULL;
1641
1642 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
1643 if (!tt_global_entry)
1644 goto out;
1645
1646 if (!roaming) {
1647 batadv_tt_global_del_orig_entry(bat_priv, tt_global_entry,
1648 orig_node, message);
1649
1650 if (hlist_empty(&tt_global_entry->orig_list))
1651 batadv_tt_global_free(bat_priv, tt_global_entry,
1652 message);
1653
1654 goto out;
1655 }
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670 local_entry = batadv_tt_local_hash_find(bat_priv,
1671 tt_global_entry->common.addr,
1672 vid);
1673 if (local_entry) {
1674
1675 batadv_tt_global_del_orig_list(tt_global_entry);
1676 batadv_tt_global_free(bat_priv, tt_global_entry, message);
1677 } else
1678
1679 batadv_tt_global_del_roaming(bat_priv, tt_global_entry,
1680 orig_node, message);
1681
1682
1683out:
1684 if (tt_global_entry)
1685 batadv_tt_global_entry_free_ref(tt_global_entry);
1686 if (local_entry)
1687 batadv_tt_local_entry_free_ref(local_entry);
1688}
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
1700 struct batadv_orig_node *orig_node,
1701 int32_t match_vid,
1702 const char *message)
1703{
1704 struct batadv_tt_global_entry *tt_global;
1705 struct batadv_tt_common_entry *tt_common_entry;
1706 uint32_t i;
1707 struct batadv_hashtable *hash = bat_priv->tt.global_hash;
1708 struct hlist_node *safe;
1709 struct hlist_head *head;
1710 spinlock_t *list_lock;
1711 unsigned short vid;
1712
1713 if (!hash)
1714 return;
1715
1716 for (i = 0; i < hash->size; i++) {
1717 head = &hash->table[i];
1718 list_lock = &hash->list_locks[i];
1719
1720 spin_lock_bh(list_lock);
1721 hlist_for_each_entry_safe(tt_common_entry, safe,
1722 head, hash_entry) {
1723
1724 if (match_vid >= 0 && tt_common_entry->vid != match_vid)
1725 continue;
1726
1727 tt_global = container_of(tt_common_entry,
1728 struct batadv_tt_global_entry,
1729 common);
1730
1731 batadv_tt_global_del_orig_entry(bat_priv, tt_global,
1732 orig_node, message);
1733
1734 if (hlist_empty(&tt_global->orig_list)) {
1735 vid = tt_global->common.vid;
1736 batadv_dbg(BATADV_DBG_TT, bat_priv,
1737 "Deleting global tt entry %pM (vid: %d): %s\n",
1738 tt_global->common.addr,
1739 BATADV_PRINT_VID(vid), message);
1740 hlist_del_rcu(&tt_common_entry->hash_entry);
1741 batadv_tt_global_entry_free_ref(tt_global);
1742 }
1743 }
1744 spin_unlock_bh(list_lock);
1745 }
1746 orig_node->tt_initialised = false;
1747}
1748
1749static bool batadv_tt_global_to_purge(struct batadv_tt_global_entry *tt_global,
1750 char **msg)
1751{
1752 bool purge = false;
1753 unsigned long roam_timeout = BATADV_TT_CLIENT_ROAM_TIMEOUT;
1754 unsigned long temp_timeout = BATADV_TT_CLIENT_TEMP_TIMEOUT;
1755
1756 if ((tt_global->common.flags & BATADV_TT_CLIENT_ROAM) &&
1757 batadv_has_timed_out(tt_global->roam_at, roam_timeout)) {
1758 purge = true;
1759 *msg = "Roaming timeout\n";
1760 }
1761
1762 if ((tt_global->common.flags & BATADV_TT_CLIENT_TEMP) &&
1763 batadv_has_timed_out(tt_global->common.added_at, temp_timeout)) {
1764 purge = true;
1765 *msg = "Temporary client timeout\n";
1766 }
1767
1768 return purge;
1769}
1770
1771static void batadv_tt_global_purge(struct batadv_priv *bat_priv)
1772{
1773 struct batadv_hashtable *hash = bat_priv->tt.global_hash;
1774 struct hlist_head *head;
1775 struct hlist_node *node_tmp;
1776 spinlock_t *list_lock;
1777 uint32_t i;
1778 char *msg = NULL;
1779 struct batadv_tt_common_entry *tt_common;
1780 struct batadv_tt_global_entry *tt_global;
1781
1782 for (i = 0; i < hash->size; i++) {
1783 head = &hash->table[i];
1784 list_lock = &hash->list_locks[i];
1785
1786 spin_lock_bh(list_lock);
1787 hlist_for_each_entry_safe(tt_common, node_tmp, head,
1788 hash_entry) {
1789 tt_global = container_of(tt_common,
1790 struct batadv_tt_global_entry,
1791 common);
1792
1793 if (!batadv_tt_global_to_purge(tt_global, &msg))
1794 continue;
1795
1796 batadv_dbg(BATADV_DBG_TT, bat_priv,
1797 "Deleting global tt entry %pM (vid: %d): %s\n",
1798 tt_global->common.addr,
1799 BATADV_PRINT_VID(tt_global->common.vid),
1800 msg);
1801
1802 hlist_del_rcu(&tt_common->hash_entry);
1803
1804 batadv_tt_global_entry_free_ref(tt_global);
1805 }
1806 spin_unlock_bh(list_lock);
1807 }
1808}
1809
1810static void batadv_tt_global_table_free(struct batadv_priv *bat_priv)
1811{
1812 struct batadv_hashtable *hash;
1813 spinlock_t *list_lock;
1814 struct batadv_tt_common_entry *tt_common_entry;
1815 struct batadv_tt_global_entry *tt_global;
1816 struct hlist_node *node_tmp;
1817 struct hlist_head *head;
1818 uint32_t i;
1819
1820 if (!bat_priv->tt.global_hash)
1821 return;
1822
1823 hash = bat_priv->tt.global_hash;
1824
1825 for (i = 0; i < hash->size; i++) {
1826 head = &hash->table[i];
1827 list_lock = &hash->list_locks[i];
1828
1829 spin_lock_bh(list_lock);
1830 hlist_for_each_entry_safe(tt_common_entry, node_tmp,
1831 head, hash_entry) {
1832 hlist_del_rcu(&tt_common_entry->hash_entry);
1833 tt_global = container_of(tt_common_entry,
1834 struct batadv_tt_global_entry,
1835 common);
1836 batadv_tt_global_entry_free_ref(tt_global);
1837 }
1838 spin_unlock_bh(list_lock);
1839 }
1840
1841 batadv_hash_destroy(hash);
1842
1843 bat_priv->tt.global_hash = NULL;
1844}
1845
1846static bool
1847_batadv_is_ap_isolated(struct batadv_tt_local_entry *tt_local_entry,
1848 struct batadv_tt_global_entry *tt_global_entry)
1849{
1850 bool ret = false;
1851
1852 if (tt_local_entry->common.flags & BATADV_TT_CLIENT_WIFI &&
1853 tt_global_entry->common.flags & BATADV_TT_CLIENT_WIFI)
1854 ret = true;
1855
1856 return ret;
1857}
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873struct batadv_orig_node *batadv_transtable_search(struct batadv_priv *bat_priv,
1874 const uint8_t *src,
1875 const uint8_t *addr,
1876 unsigned short vid)
1877{
1878 struct batadv_tt_local_entry *tt_local_entry = NULL;
1879 struct batadv_tt_global_entry *tt_global_entry = NULL;
1880 struct batadv_orig_node *orig_node = NULL;
1881 struct batadv_tt_orig_list_entry *best_entry;
1882 bool ap_isolation_enabled = false;
1883 struct batadv_softif_vlan *vlan;
1884
1885
1886
1887
1888 vlan = batadv_softif_vlan_get(bat_priv, vid);
1889 if (vlan) {
1890 ap_isolation_enabled = atomic_read(&vlan->ap_isolation);
1891 batadv_softif_vlan_free_ref(vlan);
1892 }
1893
1894 if (src && ap_isolation_enabled) {
1895 tt_local_entry = batadv_tt_local_hash_find(bat_priv, src, vid);
1896 if (!tt_local_entry ||
1897 (tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING))
1898 goto out;
1899 }
1900
1901 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
1902 if (!tt_global_entry)
1903 goto out;
1904
1905
1906
1907
1908 if (tt_local_entry &&
1909 _batadv_is_ap_isolated(tt_local_entry, tt_global_entry))
1910 goto out;
1911
1912 rcu_read_lock();
1913 best_entry = batadv_transtable_best_orig(bat_priv, tt_global_entry);
1914
1915 if (best_entry)
1916 orig_node = best_entry->orig_node;
1917 if (orig_node && !atomic_inc_not_zero(&orig_node->refcount))
1918 orig_node = NULL;
1919 rcu_read_unlock();
1920
1921out:
1922 if (tt_global_entry)
1923 batadv_tt_global_entry_free_ref(tt_global_entry);
1924 if (tt_local_entry)
1925 batadv_tt_local_entry_free_ref(tt_local_entry);
1926
1927 return orig_node;
1928}
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954static uint32_t batadv_tt_global_crc(struct batadv_priv *bat_priv,
1955 struct batadv_orig_node *orig_node,
1956 unsigned short vid)
1957{
1958 struct batadv_hashtable *hash = bat_priv->tt.global_hash;
1959 struct batadv_tt_common_entry *tt_common;
1960 struct batadv_tt_global_entry *tt_global;
1961 struct hlist_head *head;
1962 uint32_t i, crc_tmp, crc = 0;
1963 uint8_t flags;
1964
1965 for (i = 0; i < hash->size; i++) {
1966 head = &hash->table[i];
1967
1968 rcu_read_lock();
1969 hlist_for_each_entry_rcu(tt_common, head, hash_entry) {
1970 tt_global = container_of(tt_common,
1971 struct batadv_tt_global_entry,
1972 common);
1973
1974
1975
1976 if (tt_common->vid != vid)
1977 continue;
1978
1979
1980
1981
1982
1983
1984 if (tt_common->flags & BATADV_TT_CLIENT_ROAM)
1985 continue;
1986
1987
1988
1989
1990 if (tt_common->flags & BATADV_TT_CLIENT_TEMP)
1991 continue;
1992
1993
1994
1995
1996 if (!batadv_tt_global_entry_has_orig(tt_global,
1997 orig_node))
1998 continue;
1999
2000 crc_tmp = crc32c(0, &tt_common->vid,
2001 sizeof(tt_common->vid));
2002
2003
2004
2005
2006 flags = tt_common->flags & BATADV_TT_SYNC_MASK;
2007 crc_tmp = crc32c(crc_tmp, &flags, sizeof(flags));
2008
2009 crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN);
2010 }
2011 rcu_read_unlock();
2012 }
2013
2014 return crc;
2015}
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027static uint32_t batadv_tt_local_crc(struct batadv_priv *bat_priv,
2028 unsigned short vid)
2029{
2030 struct batadv_hashtable *hash = bat_priv->tt.local_hash;
2031 struct batadv_tt_common_entry *tt_common;
2032 struct hlist_head *head;
2033 uint32_t i, crc_tmp, crc = 0;
2034 uint8_t flags;
2035
2036 for (i = 0; i < hash->size; i++) {
2037 head = &hash->table[i];
2038
2039 rcu_read_lock();
2040 hlist_for_each_entry_rcu(tt_common, head, hash_entry) {
2041
2042
2043
2044 if (tt_common->vid != vid)
2045 continue;
2046
2047
2048
2049
2050 if (tt_common->flags & BATADV_TT_CLIENT_NEW)
2051 continue;
2052
2053 crc_tmp = crc32c(0, &tt_common->vid,
2054 sizeof(tt_common->vid));
2055
2056
2057
2058
2059 flags = tt_common->flags & BATADV_TT_SYNC_MASK;
2060 crc_tmp = crc32c(crc_tmp, &flags, sizeof(flags));
2061
2062 crc ^= crc32c(crc_tmp, tt_common->addr, ETH_ALEN);
2063 }
2064 rcu_read_unlock();
2065 }
2066
2067 return crc;
2068}
2069
2070static void batadv_tt_req_list_free(struct batadv_priv *bat_priv)
2071{
2072 struct batadv_tt_req_node *node, *safe;
2073
2074 spin_lock_bh(&bat_priv->tt.req_list_lock);
2075
2076 list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
2077 list_del(&node->list);
2078 kfree(node);
2079 }
2080
2081 spin_unlock_bh(&bat_priv->tt.req_list_lock);
2082}
2083
2084static void batadv_tt_save_orig_buffer(struct batadv_priv *bat_priv,
2085 struct batadv_orig_node *orig_node,
2086 const void *tt_buff,
2087 uint16_t tt_buff_len)
2088{
2089
2090
2091
2092 spin_lock_bh(&orig_node->tt_buff_lock);
2093 if (tt_buff_len > 0) {
2094 kfree(orig_node->tt_buff);
2095 orig_node->tt_buff_len = 0;
2096 orig_node->tt_buff = kmalloc(tt_buff_len, GFP_ATOMIC);
2097 if (orig_node->tt_buff) {
2098 memcpy(orig_node->tt_buff, tt_buff, tt_buff_len);
2099 orig_node->tt_buff_len = tt_buff_len;
2100 }
2101 }
2102 spin_unlock_bh(&orig_node->tt_buff_lock);
2103}
2104
2105static void batadv_tt_req_purge(struct batadv_priv *bat_priv)
2106{
2107 struct batadv_tt_req_node *node, *safe;
2108
2109 spin_lock_bh(&bat_priv->tt.req_list_lock);
2110 list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
2111 if (batadv_has_timed_out(node->issued_at,
2112 BATADV_TT_REQUEST_TIMEOUT)) {
2113 list_del(&node->list);
2114 kfree(node);
2115 }
2116 }
2117 spin_unlock_bh(&bat_priv->tt.req_list_lock);
2118}
2119
2120
2121
2122
2123static struct batadv_tt_req_node *
2124batadv_new_tt_req_node(struct batadv_priv *bat_priv,
2125 struct batadv_orig_node *orig_node)
2126{
2127 struct batadv_tt_req_node *tt_req_node_tmp, *tt_req_node = NULL;
2128
2129 spin_lock_bh(&bat_priv->tt.req_list_lock);
2130 list_for_each_entry(tt_req_node_tmp, &bat_priv->tt.req_list, list) {
2131 if (batadv_compare_eth(tt_req_node_tmp, orig_node) &&
2132 !batadv_has_timed_out(tt_req_node_tmp->issued_at,
2133 BATADV_TT_REQUEST_TIMEOUT))
2134 goto unlock;
2135 }
2136
2137 tt_req_node = kmalloc(sizeof(*tt_req_node), GFP_ATOMIC);
2138 if (!tt_req_node)
2139 goto unlock;
2140
2141 memcpy(tt_req_node->addr, orig_node->orig, ETH_ALEN);
2142 tt_req_node->issued_at = jiffies;
2143
2144 list_add(&tt_req_node->list, &bat_priv->tt.req_list);
2145unlock:
2146 spin_unlock_bh(&bat_priv->tt.req_list_lock);
2147 return tt_req_node;
2148}
2149
2150
2151
2152
2153
2154
2155
2156
2157static int batadv_tt_local_valid(const void *entry_ptr, const void *data_ptr)
2158{
2159 const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
2160
2161 if (tt_common_entry->flags & BATADV_TT_CLIENT_NEW)
2162 return 0;
2163 return 1;
2164}
2165
2166static int batadv_tt_global_valid(const void *entry_ptr,
2167 const void *data_ptr)
2168{
2169 const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
2170 const struct batadv_tt_global_entry *tt_global_entry;
2171 const struct batadv_orig_node *orig_node = data_ptr;
2172
2173 if (tt_common_entry->flags & BATADV_TT_CLIENT_ROAM ||
2174 tt_common_entry->flags & BATADV_TT_CLIENT_TEMP)
2175 return 0;
2176
2177 tt_global_entry = container_of(tt_common_entry,
2178 struct batadv_tt_global_entry,
2179 common);
2180
2181 return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node);
2182}
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
2195 struct batadv_hashtable *hash,
2196 void *tvlv_buff, uint16_t tt_len,
2197 int (*valid_cb)(const void *, const void *),
2198 void *cb_data)
2199{
2200 struct batadv_tt_common_entry *tt_common_entry;
2201 struct batadv_tvlv_tt_change *tt_change;
2202 struct hlist_head *head;
2203 uint16_t tt_tot, tt_num_entries = 0;
2204 uint32_t i;
2205
2206 tt_tot = batadv_tt_entries(tt_len);
2207 tt_change = (struct batadv_tvlv_tt_change *)tvlv_buff;
2208
2209 rcu_read_lock();
2210 for (i = 0; i < hash->size; i++) {
2211 head = &hash->table[i];
2212
2213 hlist_for_each_entry_rcu(tt_common_entry,
2214 head, hash_entry) {
2215 if (tt_tot == tt_num_entries)
2216 break;
2217
2218 if ((valid_cb) && (!valid_cb(tt_common_entry, cb_data)))
2219 continue;
2220
2221 memcpy(tt_change->addr, tt_common_entry->addr,
2222 ETH_ALEN);
2223 tt_change->flags = tt_common_entry->flags;
2224 tt_change->vid = htons(tt_common_entry->vid);
2225 memset(tt_change->reserved, 0,
2226 sizeof(tt_change->reserved));
2227
2228 tt_num_entries++;
2229 tt_change++;
2230 }
2231 }
2232 rcu_read_unlock();
2233}
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245static bool batadv_tt_global_check_crc(struct batadv_orig_node *orig_node,
2246 struct batadv_tvlv_tt_vlan_data *tt_vlan,
2247 uint16_t num_vlan)
2248{
2249 struct batadv_tvlv_tt_vlan_data *tt_vlan_tmp;
2250 struct batadv_orig_node_vlan *vlan;
2251 int i;
2252
2253
2254 for (i = 0; i < num_vlan; i++) {
2255 tt_vlan_tmp = tt_vlan + i;
2256
2257
2258
2259
2260 if (batadv_bla_is_backbone_gw_orig(orig_node->bat_priv,
2261 orig_node->orig,
2262 ntohs(tt_vlan_tmp->vid)))
2263 continue;
2264
2265 vlan = batadv_orig_node_vlan_get(orig_node,
2266 ntohs(tt_vlan_tmp->vid));
2267 if (!vlan)
2268 return false;
2269
2270 if (vlan->tt.crc != ntohl(tt_vlan_tmp->crc))
2271 return false;
2272 }
2273
2274 return true;
2275}
2276
2277
2278
2279
2280
2281static void batadv_tt_local_update_crc(struct batadv_priv *bat_priv)
2282{
2283 struct batadv_softif_vlan *vlan;
2284
2285
2286 rcu_read_lock();
2287 hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
2288 vlan->tt.crc = batadv_tt_local_crc(bat_priv, vlan->vid);
2289 }
2290 rcu_read_unlock();
2291}
2292
2293
2294
2295
2296
2297
2298static void batadv_tt_global_update_crc(struct batadv_priv *bat_priv,
2299 struct batadv_orig_node *orig_node)
2300{
2301 struct batadv_orig_node_vlan *vlan;
2302 uint32_t crc;
2303
2304
2305 rcu_read_lock();
2306 list_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) {
2307
2308
2309
2310 if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig,
2311 vlan->vid))
2312 continue;
2313
2314 crc = batadv_tt_global_crc(bat_priv, orig_node, vlan->vid);
2315 vlan->tt.crc = crc;
2316 }
2317 rcu_read_unlock();
2318}
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330static int batadv_send_tt_request(struct batadv_priv *bat_priv,
2331 struct batadv_orig_node *dst_orig_node,
2332 uint8_t ttvn,
2333 struct batadv_tvlv_tt_vlan_data *tt_vlan,
2334 uint16_t num_vlan, bool full_table)
2335{
2336 struct batadv_tvlv_tt_data *tvlv_tt_data = NULL;
2337 struct batadv_tt_req_node *tt_req_node = NULL;
2338 struct batadv_tvlv_tt_vlan_data *tt_vlan_req;
2339 struct batadv_hard_iface *primary_if;
2340 bool ret = false;
2341 int i, size;
2342
2343 primary_if = batadv_primary_if_get_selected(bat_priv);
2344 if (!primary_if)
2345 goto out;
2346
2347
2348
2349
2350 tt_req_node = batadv_new_tt_req_node(bat_priv, dst_orig_node);
2351 if (!tt_req_node)
2352 goto out;
2353
2354 size = sizeof(*tvlv_tt_data) + sizeof(*tt_vlan_req) * num_vlan;
2355 tvlv_tt_data = kzalloc(size, GFP_ATOMIC);
2356 if (!tvlv_tt_data)
2357 goto out;
2358
2359 tvlv_tt_data->flags = BATADV_TT_REQUEST;
2360 tvlv_tt_data->ttvn = ttvn;
2361 tvlv_tt_data->num_vlan = htons(num_vlan);
2362
2363
2364
2365
2366 tt_vlan_req = (struct batadv_tvlv_tt_vlan_data *)(tvlv_tt_data + 1);
2367 for (i = 0; i < num_vlan; i++) {
2368 tt_vlan_req->vid = tt_vlan->vid;
2369 tt_vlan_req->crc = tt_vlan->crc;
2370
2371 tt_vlan_req++;
2372 tt_vlan++;
2373 }
2374
2375 if (full_table)
2376 tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE;
2377
2378 batadv_dbg(BATADV_DBG_TT, bat_priv, "Sending TT_REQUEST to %pM [%c]\n",
2379 dst_orig_node->orig, full_table ? 'F' : '.');
2380
2381 batadv_inc_counter(bat_priv, BATADV_CNT_TT_REQUEST_TX);
2382 batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr,
2383 dst_orig_node->orig, BATADV_TVLV_TT, 1,
2384 tvlv_tt_data, size);
2385 ret = true;
2386
2387out:
2388 if (primary_if)
2389 batadv_hardif_free_ref(primary_if);
2390 if (ret && tt_req_node) {
2391 spin_lock_bh(&bat_priv->tt.req_list_lock);
2392 list_del(&tt_req_node->list);
2393 spin_unlock_bh(&bat_priv->tt.req_list_lock);
2394 kfree(tt_req_node);
2395 }
2396 kfree(tvlv_tt_data);
2397 return ret;
2398}
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410static bool batadv_send_other_tt_response(struct batadv_priv *bat_priv,
2411 struct batadv_tvlv_tt_data *tt_data,
2412 uint8_t *req_src, uint8_t *req_dst)
2413{
2414 struct batadv_orig_node *req_dst_orig_node;
2415 struct batadv_orig_node *res_dst_orig_node = NULL;
2416 struct batadv_tvlv_tt_change *tt_change;
2417 struct batadv_tvlv_tt_data *tvlv_tt_data = NULL;
2418 struct batadv_tvlv_tt_vlan_data *tt_vlan;
2419 bool ret = false, full_table;
2420 uint8_t orig_ttvn, req_ttvn;
2421 uint16_t tvlv_len;
2422 int32_t tt_len;
2423
2424 batadv_dbg(BATADV_DBG_TT, bat_priv,
2425 "Received TT_REQUEST from %pM for ttvn: %u (%pM) [%c]\n",
2426 req_src, tt_data->ttvn, req_dst,
2427 (tt_data->flags & BATADV_TT_FULL_TABLE ? 'F' : '.'));
2428
2429
2430 req_dst_orig_node = batadv_orig_hash_find(bat_priv, req_dst);
2431 if (!req_dst_orig_node)
2432 goto out;
2433
2434 res_dst_orig_node = batadv_orig_hash_find(bat_priv, req_src);
2435 if (!res_dst_orig_node)
2436 goto out;
2437
2438 orig_ttvn = (uint8_t)atomic_read(&req_dst_orig_node->last_ttvn);
2439 req_ttvn = tt_data->ttvn;
2440
2441 tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(tt_data + 1);
2442
2443 if (orig_ttvn != req_ttvn ||
2444 !batadv_tt_global_check_crc(req_dst_orig_node, tt_vlan,
2445 ntohs(tt_data->num_vlan)))
2446 goto out;
2447
2448
2449 if (tt_data->flags & BATADV_TT_FULL_TABLE ||
2450 !req_dst_orig_node->tt_buff)
2451 full_table = true;
2452 else
2453 full_table = false;
2454
2455
2456
2457
2458 if (!full_table) {
2459 spin_lock_bh(&req_dst_orig_node->tt_buff_lock);
2460 tt_len = req_dst_orig_node->tt_buff_len;
2461
2462 tvlv_len = batadv_tt_prepare_tvlv_global_data(req_dst_orig_node,
2463 &tvlv_tt_data,
2464 &tt_change,
2465 &tt_len);
2466 if (!tt_len)
2467 goto unlock;
2468
2469
2470 memcpy(tt_change, req_dst_orig_node->tt_buff,
2471 req_dst_orig_node->tt_buff_len);
2472 spin_unlock_bh(&req_dst_orig_node->tt_buff_lock);
2473 } else {
2474
2475
2476
2477 tt_len = -1;
2478 tvlv_len = batadv_tt_prepare_tvlv_global_data(req_dst_orig_node,
2479 &tvlv_tt_data,
2480 &tt_change,
2481 &tt_len);
2482 if (!tt_len)
2483 goto out;
2484
2485
2486 batadv_tt_tvlv_generate(bat_priv, bat_priv->tt.global_hash,
2487 tt_change, tt_len,
2488 batadv_tt_global_valid,
2489 req_dst_orig_node);
2490 }
2491
2492
2493 tt_len = sizeof(struct batadv_unicast_tvlv_packet) + tvlv_len;
2494 if (tt_len > atomic_read(&bat_priv->packet_size_max)) {
2495 net_ratelimited_function(batadv_info, bat_priv->soft_iface,
2496 "Ignoring TT_REQUEST from %pM; Response size exceeds max packet size.\n",
2497 res_dst_orig_node->orig);
2498 goto out;
2499 }
2500
2501 tvlv_tt_data->flags = BATADV_TT_RESPONSE;
2502 tvlv_tt_data->ttvn = req_ttvn;
2503
2504 if (full_table)
2505 tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE;
2506
2507 batadv_dbg(BATADV_DBG_TT, bat_priv,
2508 "Sending TT_RESPONSE %pM for %pM [%c] (ttvn: %u)\n",
2509 res_dst_orig_node->orig, req_dst_orig_node->orig,
2510 full_table ? 'F' : '.', req_ttvn);
2511
2512 batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX);
2513
2514 batadv_tvlv_unicast_send(bat_priv, req_dst_orig_node->orig,
2515 req_src, BATADV_TVLV_TT, 1, tvlv_tt_data,
2516 tvlv_len);
2517
2518 ret = true;
2519 goto out;
2520
2521unlock:
2522 spin_unlock_bh(&req_dst_orig_node->tt_buff_lock);
2523
2524out:
2525 if (res_dst_orig_node)
2526 batadv_orig_node_free_ref(res_dst_orig_node);
2527 if (req_dst_orig_node)
2528 batadv_orig_node_free_ref(req_dst_orig_node);
2529 kfree(tvlv_tt_data);
2530 return ret;
2531}
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542static bool batadv_send_my_tt_response(struct batadv_priv *bat_priv,
2543 struct batadv_tvlv_tt_data *tt_data,
2544 uint8_t *req_src)
2545{
2546 struct batadv_tvlv_tt_data *tvlv_tt_data = NULL;
2547 struct batadv_hard_iface *primary_if = NULL;
2548 struct batadv_tvlv_tt_change *tt_change;
2549 struct batadv_orig_node *orig_node;
2550 uint8_t my_ttvn, req_ttvn;
2551 uint16_t tvlv_len;
2552 bool full_table;
2553 int32_t tt_len;
2554
2555 batadv_dbg(BATADV_DBG_TT, bat_priv,
2556 "Received TT_REQUEST from %pM for ttvn: %u (me) [%c]\n",
2557 req_src, tt_data->ttvn,
2558 (tt_data->flags & BATADV_TT_FULL_TABLE ? 'F' : '.'));
2559
2560 spin_lock_bh(&bat_priv->tt.commit_lock);
2561
2562 my_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
2563 req_ttvn = tt_data->ttvn;
2564
2565 orig_node = batadv_orig_hash_find(bat_priv, req_src);
2566 if (!orig_node)
2567 goto out;
2568
2569 primary_if = batadv_primary_if_get_selected(bat_priv);
2570 if (!primary_if)
2571 goto out;
2572
2573
2574
2575
2576 if (tt_data->flags & BATADV_TT_FULL_TABLE || my_ttvn != req_ttvn ||
2577 !bat_priv->tt.last_changeset)
2578 full_table = true;
2579 else
2580 full_table = false;
2581
2582
2583
2584
2585 if (!full_table) {
2586 spin_lock_bh(&bat_priv->tt.last_changeset_lock);
2587
2588 tt_len = bat_priv->tt.last_changeset_len;
2589 tvlv_len = batadv_tt_prepare_tvlv_local_data(bat_priv,
2590 &tvlv_tt_data,
2591 &tt_change,
2592 &tt_len);
2593 if (!tt_len)
2594 goto unlock;
2595
2596
2597 memcpy(tt_change, bat_priv->tt.last_changeset,
2598 bat_priv->tt.last_changeset_len);
2599 spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
2600 } else {
2601 req_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn);
2602
2603
2604
2605
2606 tt_len = -1;
2607 tvlv_len = batadv_tt_prepare_tvlv_local_data(bat_priv,
2608 &tvlv_tt_data,
2609 &tt_change,
2610 &tt_len);
2611 if (!tt_len)
2612 goto out;
2613
2614
2615 batadv_tt_tvlv_generate(bat_priv, bat_priv->tt.local_hash,
2616 tt_change, tt_len,
2617 batadv_tt_local_valid, NULL);
2618 }
2619
2620 tvlv_tt_data->flags = BATADV_TT_RESPONSE;
2621 tvlv_tt_data->ttvn = req_ttvn;
2622
2623 if (full_table)
2624 tvlv_tt_data->flags |= BATADV_TT_FULL_TABLE;
2625
2626 batadv_dbg(BATADV_DBG_TT, bat_priv,
2627 "Sending TT_RESPONSE to %pM [%c] (ttvn: %u)\n",
2628 orig_node->orig, full_table ? 'F' : '.', req_ttvn);
2629
2630 batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX);
2631
2632 batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr,
2633 req_src, BATADV_TVLV_TT, 1, tvlv_tt_data,
2634 tvlv_len);
2635
2636 goto out;
2637
2638unlock:
2639 spin_unlock_bh(&bat_priv->tt.last_changeset_lock);
2640out:
2641 spin_unlock_bh(&bat_priv->tt.commit_lock);
2642 if (orig_node)
2643 batadv_orig_node_free_ref(orig_node);
2644 if (primary_if)
2645 batadv_hardif_free_ref(primary_if);
2646 kfree(tvlv_tt_data);
2647
2648 return true;
2649}
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660static bool batadv_send_tt_response(struct batadv_priv *bat_priv,
2661 struct batadv_tvlv_tt_data *tt_data,
2662 uint8_t *req_src, uint8_t *req_dst)
2663{
2664 if (batadv_is_my_mac(bat_priv, req_dst))
2665 return batadv_send_my_tt_response(bat_priv, tt_data, req_src);
2666 else
2667 return batadv_send_other_tt_response(bat_priv, tt_data,
2668 req_src, req_dst);
2669}
2670
2671static void _batadv_tt_update_changes(struct batadv_priv *bat_priv,
2672 struct batadv_orig_node *orig_node,
2673 struct batadv_tvlv_tt_change *tt_change,
2674 uint16_t tt_num_changes, uint8_t ttvn)
2675{
2676 int i;
2677 int roams;
2678
2679 for (i = 0; i < tt_num_changes; i++) {
2680 if ((tt_change + i)->flags & BATADV_TT_CLIENT_DEL) {
2681 roams = (tt_change + i)->flags & BATADV_TT_CLIENT_ROAM;
2682 batadv_tt_global_del(bat_priv, orig_node,
2683 (tt_change + i)->addr,
2684 ntohs((tt_change + i)->vid),
2685 "tt removed by changes",
2686 roams);
2687 } else {
2688 if (!batadv_tt_global_add(bat_priv, orig_node,
2689 (tt_change + i)->addr,
2690 ntohs((tt_change + i)->vid),
2691 (tt_change + i)->flags, ttvn))
2692
2693
2694
2695
2696
2697
2698 return;
2699 }
2700 }
2701 orig_node->tt_initialised = true;
2702}
2703
2704static void batadv_tt_fill_gtable(struct batadv_priv *bat_priv,
2705 struct batadv_tvlv_tt_change *tt_change,
2706 uint8_t ttvn, uint8_t *resp_src,
2707 uint16_t num_entries)
2708{
2709 struct batadv_orig_node *orig_node;
2710
2711 orig_node = batadv_orig_hash_find(bat_priv, resp_src);
2712 if (!orig_node)
2713 goto out;
2714
2715
2716 batadv_tt_global_del_orig(bat_priv, orig_node, -1,
2717 "Received full table");
2718
2719 _batadv_tt_update_changes(bat_priv, orig_node, tt_change, num_entries,
2720 ttvn);
2721
2722 spin_lock_bh(&orig_node->tt_buff_lock);
2723 kfree(orig_node->tt_buff);
2724 orig_node->tt_buff_len = 0;
2725 orig_node->tt_buff = NULL;
2726 spin_unlock_bh(&orig_node->tt_buff_lock);
2727
2728 atomic_set(&orig_node->last_ttvn, ttvn);
2729
2730out:
2731 if (orig_node)
2732 batadv_orig_node_free_ref(orig_node);
2733}
2734
2735static void batadv_tt_update_changes(struct batadv_priv *bat_priv,
2736 struct batadv_orig_node *orig_node,
2737 uint16_t tt_num_changes, uint8_t ttvn,
2738 struct batadv_tvlv_tt_change *tt_change)
2739{
2740 _batadv_tt_update_changes(bat_priv, orig_node, tt_change,
2741 tt_num_changes, ttvn);
2742
2743 batadv_tt_save_orig_buffer(bat_priv, orig_node, tt_change,
2744 batadv_tt_len(tt_num_changes));
2745 atomic_set(&orig_node->last_ttvn, ttvn);
2746}
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756bool batadv_is_my_client(struct batadv_priv *bat_priv, const uint8_t *addr,
2757 unsigned short vid)
2758{
2759 struct batadv_tt_local_entry *tt_local_entry;
2760 bool ret = false;
2761
2762 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
2763 if (!tt_local_entry)
2764 goto out;
2765
2766
2767
2768 if ((tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING) ||
2769 (tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM))
2770 goto out;
2771 ret = true;
2772out:
2773 if (tt_local_entry)
2774 batadv_tt_local_entry_free_ref(tt_local_entry);
2775 return ret;
2776}
2777
2778
2779
2780
2781
2782
2783
2784
2785static void batadv_handle_tt_response(struct batadv_priv *bat_priv,
2786 struct batadv_tvlv_tt_data *tt_data,
2787 uint8_t *resp_src, uint16_t num_entries)
2788{
2789 struct batadv_tt_req_node *node, *safe;
2790 struct batadv_orig_node *orig_node = NULL;
2791 struct batadv_tvlv_tt_change *tt_change;
2792 uint8_t *tvlv_ptr = (uint8_t *)tt_data;
2793 uint16_t change_offset;
2794
2795 batadv_dbg(BATADV_DBG_TT, bat_priv,
2796 "Received TT_RESPONSE from %pM for ttvn %d t_size: %d [%c]\n",
2797 resp_src, tt_data->ttvn, num_entries,
2798 (tt_data->flags & BATADV_TT_FULL_TABLE ? 'F' : '.'));
2799
2800 orig_node = batadv_orig_hash_find(bat_priv, resp_src);
2801 if (!orig_node)
2802 goto out;
2803
2804 spin_lock_bh(&orig_node->tt_lock);
2805
2806 change_offset = sizeof(struct batadv_tvlv_tt_vlan_data);
2807 change_offset *= ntohs(tt_data->num_vlan);
2808 change_offset += sizeof(*tt_data);
2809 tvlv_ptr += change_offset;
2810
2811 tt_change = (struct batadv_tvlv_tt_change *)tvlv_ptr;
2812 if (tt_data->flags & BATADV_TT_FULL_TABLE) {
2813 batadv_tt_fill_gtable(bat_priv, tt_change, tt_data->ttvn,
2814 resp_src, num_entries);
2815 } else {
2816 batadv_tt_update_changes(bat_priv, orig_node, num_entries,
2817 tt_data->ttvn, tt_change);
2818 }
2819
2820
2821 batadv_tt_global_update_crc(bat_priv, orig_node);
2822
2823 spin_unlock_bh(&orig_node->tt_lock);
2824
2825
2826 spin_lock_bh(&bat_priv->tt.req_list_lock);
2827 list_for_each_entry_safe(node, safe, &bat_priv->tt.req_list, list) {
2828 if (!batadv_compare_eth(node->addr, resp_src))
2829 continue;
2830 list_del(&node->list);
2831 kfree(node);
2832 }
2833
2834 spin_unlock_bh(&bat_priv->tt.req_list_lock);
2835out:
2836 if (orig_node)
2837 batadv_orig_node_free_ref(orig_node);
2838}
2839
2840static void batadv_tt_roam_list_free(struct batadv_priv *bat_priv)
2841{
2842 struct batadv_tt_roam_node *node, *safe;
2843
2844 spin_lock_bh(&bat_priv->tt.roam_list_lock);
2845
2846 list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) {
2847 list_del(&node->list);
2848 kfree(node);
2849 }
2850
2851 spin_unlock_bh(&bat_priv->tt.roam_list_lock);
2852}
2853
2854static void batadv_tt_roam_purge(struct batadv_priv *bat_priv)
2855{
2856 struct batadv_tt_roam_node *node, *safe;
2857
2858 spin_lock_bh(&bat_priv->tt.roam_list_lock);
2859 list_for_each_entry_safe(node, safe, &bat_priv->tt.roam_list, list) {
2860 if (!batadv_has_timed_out(node->first_time,
2861 BATADV_ROAMING_MAX_TIME))
2862 continue;
2863
2864 list_del(&node->list);
2865 kfree(node);
2866 }
2867 spin_unlock_bh(&bat_priv->tt.roam_list_lock);
2868}
2869
2870
2871
2872
2873
2874
2875
2876static bool batadv_tt_check_roam_count(struct batadv_priv *bat_priv,
2877 uint8_t *client)
2878{
2879 struct batadv_tt_roam_node *tt_roam_node;
2880 bool ret = false;
2881
2882 spin_lock_bh(&bat_priv->tt.roam_list_lock);
2883
2884
2885
2886 list_for_each_entry(tt_roam_node, &bat_priv->tt.roam_list, list) {
2887 if (!batadv_compare_eth(tt_roam_node->addr, client))
2888 continue;
2889
2890 if (batadv_has_timed_out(tt_roam_node->first_time,
2891 BATADV_ROAMING_MAX_TIME))
2892 continue;
2893
2894 if (!batadv_atomic_dec_not_zero(&tt_roam_node->counter))
2895
2896 goto unlock;
2897 ret = true;
2898 break;
2899 }
2900
2901 if (!ret) {
2902 tt_roam_node = kmalloc(sizeof(*tt_roam_node), GFP_ATOMIC);
2903 if (!tt_roam_node)
2904 goto unlock;
2905
2906 tt_roam_node->first_time = jiffies;
2907 atomic_set(&tt_roam_node->counter,
2908 BATADV_ROAMING_MAX_COUNT - 1);
2909 memcpy(tt_roam_node->addr, client, ETH_ALEN);
2910
2911 list_add(&tt_roam_node->list, &bat_priv->tt.roam_list);
2912 ret = true;
2913 }
2914
2915unlock:
2916 spin_unlock_bh(&bat_priv->tt.roam_list_lock);
2917 return ret;
2918}
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
2933 unsigned short vid,
2934 struct batadv_orig_node *orig_node)
2935{
2936 struct batadv_hard_iface *primary_if;
2937 struct batadv_tvlv_roam_adv tvlv_roam;
2938
2939 primary_if = batadv_primary_if_get_selected(bat_priv);
2940 if (!primary_if)
2941 goto out;
2942
2943
2944
2945
2946 if (!batadv_tt_check_roam_count(bat_priv, client))
2947 goto out;
2948
2949 batadv_dbg(BATADV_DBG_TT, bat_priv,
2950 "Sending ROAMING_ADV to %pM (client %pM, vid: %d)\n",
2951 orig_node->orig, client, BATADV_PRINT_VID(vid));
2952
2953 batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_TX);
2954
2955 memcpy(tvlv_roam.client, client, sizeof(tvlv_roam.client));
2956 tvlv_roam.vid = htons(vid);
2957
2958 batadv_tvlv_unicast_send(bat_priv, primary_if->net_dev->dev_addr,
2959 orig_node->orig, BATADV_TVLV_ROAM, 1,
2960 &tvlv_roam, sizeof(tvlv_roam));
2961
2962out:
2963 if (primary_if)
2964 batadv_hardif_free_ref(primary_if);
2965}
2966
2967static void batadv_tt_purge(struct work_struct *work)
2968{
2969 struct delayed_work *delayed_work;
2970 struct batadv_priv_tt *priv_tt;
2971 struct batadv_priv *bat_priv;
2972
2973 delayed_work = container_of(work, struct delayed_work, work);
2974 priv_tt = container_of(delayed_work, struct batadv_priv_tt, work);
2975 bat_priv = container_of(priv_tt, struct batadv_priv, tt);
2976
2977 batadv_tt_local_purge(bat_priv, BATADV_TT_LOCAL_TIMEOUT);
2978 batadv_tt_global_purge(bat_priv);
2979 batadv_tt_req_purge(bat_priv);
2980 batadv_tt_roam_purge(bat_priv);
2981
2982 queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work,
2983 msecs_to_jiffies(BATADV_TT_WORK_PERIOD));
2984}
2985
2986void batadv_tt_free(struct batadv_priv *bat_priv)
2987{
2988 batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_TT, 1);
2989 batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_TT, 1);
2990
2991 cancel_delayed_work_sync(&bat_priv->tt.work);
2992
2993 batadv_tt_local_table_free(bat_priv);
2994 batadv_tt_global_table_free(bat_priv);
2995 batadv_tt_req_list_free(bat_priv);
2996 batadv_tt_changes_list_free(bat_priv);
2997 batadv_tt_roam_list_free(bat_priv);
2998
2999 kfree(bat_priv->tt.last_changeset);
3000}
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010static void batadv_tt_local_set_flags(struct batadv_priv *bat_priv,
3011 uint16_t flags, bool enable, bool count)
3012{
3013 struct batadv_hashtable *hash = bat_priv->tt.local_hash;
3014 struct batadv_tt_common_entry *tt_common_entry;
3015 uint16_t changed_num = 0;
3016 struct hlist_head *head;
3017 uint32_t i;
3018
3019 if (!hash)
3020 return;
3021
3022 for (i = 0; i < hash->size; i++) {
3023 head = &hash->table[i];
3024
3025 rcu_read_lock();
3026 hlist_for_each_entry_rcu(tt_common_entry,
3027 head, hash_entry) {
3028 if (enable) {
3029 if ((tt_common_entry->flags & flags) == flags)
3030 continue;
3031 tt_common_entry->flags |= flags;
3032 } else {
3033 if (!(tt_common_entry->flags & flags))
3034 continue;
3035 tt_common_entry->flags &= ~flags;
3036 }
3037 changed_num++;
3038
3039 if (!count)
3040 continue;
3041
3042 batadv_tt_local_size_inc(bat_priv,
3043 tt_common_entry->vid);
3044 }
3045 rcu_read_unlock();
3046 }
3047}
3048
3049
3050static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
3051{
3052 struct batadv_hashtable *hash = bat_priv->tt.local_hash;
3053 struct batadv_tt_common_entry *tt_common;
3054 struct batadv_tt_local_entry *tt_local;
3055 struct hlist_node *node_tmp;
3056 struct hlist_head *head;
3057 spinlock_t *list_lock;
3058 uint32_t i;
3059
3060 if (!hash)
3061 return;
3062
3063 for (i = 0; i < hash->size; i++) {
3064 head = &hash->table[i];
3065 list_lock = &hash->list_locks[i];
3066
3067 spin_lock_bh(list_lock);
3068 hlist_for_each_entry_safe(tt_common, node_tmp, head,
3069 hash_entry) {
3070 if (!(tt_common->flags & BATADV_TT_CLIENT_PENDING))
3071 continue;
3072
3073 batadv_dbg(BATADV_DBG_TT, bat_priv,
3074 "Deleting local tt entry (%pM, vid: %d): pending\n",
3075 tt_common->addr,
3076 BATADV_PRINT_VID(tt_common->vid));
3077
3078 batadv_tt_local_size_dec(bat_priv, tt_common->vid);
3079 hlist_del_rcu(&tt_common->hash_entry);
3080 tt_local = container_of(tt_common,
3081 struct batadv_tt_local_entry,
3082 common);
3083 batadv_tt_local_entry_free_ref(tt_local);
3084 }
3085 spin_unlock_bh(list_lock);
3086 }
3087}
3088
3089
3090
3091
3092
3093
3094
3095
3096static void batadv_tt_local_commit_changes_nolock(struct batadv_priv *bat_priv)
3097{
3098 if (atomic_read(&bat_priv->tt.local_changes) < 1) {
3099 if (!batadv_atomic_dec_not_zero(&bat_priv->tt.ogm_append_cnt))
3100 batadv_tt_tvlv_container_update(bat_priv);
3101 return;
3102 }
3103
3104 batadv_tt_local_set_flags(bat_priv, BATADV_TT_CLIENT_NEW, false, true);
3105
3106 batadv_tt_local_purge_pending_clients(bat_priv);
3107 batadv_tt_local_update_crc(bat_priv);
3108
3109
3110 atomic_inc(&bat_priv->tt.vn);
3111 batadv_dbg(BATADV_DBG_TT, bat_priv,
3112 "Local changes committed, updating to ttvn %u\n",
3113 (uint8_t)atomic_read(&bat_priv->tt.vn));
3114
3115
3116 atomic_set(&bat_priv->tt.ogm_append_cnt, BATADV_TT_OGM_APPEND_MAX);
3117 batadv_tt_tvlv_container_update(bat_priv);
3118}
3119
3120
3121
3122
3123
3124
3125void batadv_tt_local_commit_changes(struct batadv_priv *bat_priv)
3126{
3127 spin_lock_bh(&bat_priv->tt.commit_lock);
3128 batadv_tt_local_commit_changes_nolock(bat_priv);
3129 spin_unlock_bh(&bat_priv->tt.commit_lock);
3130}
3131
3132bool batadv_is_ap_isolated(struct batadv_priv *bat_priv, uint8_t *src,
3133 uint8_t *dst, unsigned short vid)
3134{
3135 struct batadv_tt_local_entry *tt_local_entry = NULL;
3136 struct batadv_tt_global_entry *tt_global_entry = NULL;
3137 struct batadv_softif_vlan *vlan;
3138 bool ret = false;
3139
3140 vlan = batadv_softif_vlan_get(bat_priv, vid);
3141 if (!vlan || !atomic_read(&vlan->ap_isolation))
3142 goto out;
3143
3144 tt_local_entry = batadv_tt_local_hash_find(bat_priv, dst, vid);
3145 if (!tt_local_entry)
3146 goto out;
3147
3148 tt_global_entry = batadv_tt_global_hash_find(bat_priv, src, vid);
3149 if (!tt_global_entry)
3150 goto out;
3151
3152 if (!_batadv_is_ap_isolated(tt_local_entry, tt_global_entry))
3153 goto out;
3154
3155 ret = true;
3156
3157out:
3158 if (vlan)
3159 batadv_softif_vlan_free_ref(vlan);
3160 if (tt_global_entry)
3161 batadv_tt_global_entry_free_ref(tt_global_entry);
3162 if (tt_local_entry)
3163 batadv_tt_local_entry_free_ref(tt_local_entry);
3164 return ret;
3165}
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179static void batadv_tt_update_orig(struct batadv_priv *bat_priv,
3180 struct batadv_orig_node *orig_node,
3181 const void *tt_buff, uint16_t tt_num_vlan,
3182 struct batadv_tvlv_tt_change *tt_change,
3183 uint16_t tt_num_changes, uint8_t ttvn)
3184{
3185 uint8_t orig_ttvn = (uint8_t)atomic_read(&orig_node->last_ttvn);
3186 struct batadv_tvlv_tt_vlan_data *tt_vlan;
3187 bool full_table = true;
3188
3189 tt_vlan = (struct batadv_tvlv_tt_vlan_data *)tt_buff;
3190
3191
3192
3193 if ((!orig_node->tt_initialised && ttvn == 1) ||
3194 ttvn - orig_ttvn == 1) {
3195
3196
3197
3198
3199
3200 if (!tt_num_changes) {
3201 full_table = false;
3202 goto request_table;
3203 }
3204
3205 spin_lock_bh(&orig_node->tt_lock);
3206
3207 tt_change = (struct batadv_tvlv_tt_change *)tt_buff;
3208 batadv_tt_update_changes(bat_priv, orig_node, tt_num_changes,
3209 ttvn, tt_change);
3210
3211
3212
3213
3214
3215 batadv_tt_global_update_crc(bat_priv, orig_node);
3216
3217 spin_unlock_bh(&orig_node->tt_lock);
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228 if (!batadv_tt_global_check_crc(orig_node, tt_vlan,
3229 tt_num_vlan))
3230 goto request_table;
3231 } else {
3232
3233
3234
3235 if (!orig_node->tt_initialised || ttvn != orig_ttvn ||
3236 !batadv_tt_global_check_crc(orig_node, tt_vlan,
3237 tt_num_vlan)) {
3238request_table:
3239 batadv_dbg(BATADV_DBG_TT, bat_priv,
3240 "TT inconsistency for %pM. Need to retrieve the correct information (ttvn: %u last_ttvn: %u num_changes: %u)\n",
3241 orig_node->orig, ttvn, orig_ttvn,
3242 tt_num_changes);
3243 batadv_send_tt_request(bat_priv, orig_node, ttvn,
3244 tt_vlan, tt_num_vlan,
3245 full_table);
3246 return;
3247 }
3248 }
3249}
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261bool batadv_tt_global_client_is_roaming(struct batadv_priv *bat_priv,
3262 uint8_t *addr, unsigned short vid)
3263{
3264 struct batadv_tt_global_entry *tt_global_entry;
3265 bool ret = false;
3266
3267 tt_global_entry = batadv_tt_global_hash_find(bat_priv, addr, vid);
3268 if (!tt_global_entry)
3269 goto out;
3270
3271 ret = tt_global_entry->common.flags & BATADV_TT_CLIENT_ROAM;
3272 batadv_tt_global_entry_free_ref(tt_global_entry);
3273out:
3274 return ret;
3275}
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287bool batadv_tt_local_client_is_roaming(struct batadv_priv *bat_priv,
3288 uint8_t *addr, unsigned short vid)
3289{
3290 struct batadv_tt_local_entry *tt_local_entry;
3291 bool ret = false;
3292
3293 tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
3294 if (!tt_local_entry)
3295 goto out;
3296
3297 ret = tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM;
3298 batadv_tt_local_entry_free_ref(tt_local_entry);
3299out:
3300 return ret;
3301}
3302
3303bool batadv_tt_add_temporary_global_entry(struct batadv_priv *bat_priv,
3304 struct batadv_orig_node *orig_node,
3305 const unsigned char *addr,
3306 unsigned short vid)
3307{
3308 bool ret = false;
3309
3310 if (!batadv_tt_global_add(bat_priv, orig_node, addr, vid,
3311 BATADV_TT_CLIENT_TEMP,
3312 atomic_read(&orig_node->last_ttvn)))
3313 goto out;
3314
3315 batadv_dbg(BATADV_DBG_TT, bat_priv,
3316 "Added temporary global client (addr: %pM, vid: %d, orig: %pM)\n",
3317 addr, BATADV_PRINT_VID(vid), orig_node->orig);
3318 ret = true;
3319out:
3320 return ret;
3321}
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331void batadv_tt_local_resize_to_mtu(struct net_device *soft_iface)
3332{
3333 struct batadv_priv *bat_priv = netdev_priv(soft_iface);
3334 int packet_size_max = atomic_read(&bat_priv->packet_size_max);
3335 int table_size, timeout = BATADV_TT_LOCAL_TIMEOUT / 2;
3336 bool reduced = false;
3337
3338 spin_lock_bh(&bat_priv->tt.commit_lock);
3339
3340 while (true) {
3341 table_size = batadv_tt_local_table_transmit_size(bat_priv);
3342 if (packet_size_max >= table_size)
3343 break;
3344
3345 batadv_tt_local_purge(bat_priv, timeout);
3346 batadv_tt_local_purge_pending_clients(bat_priv);
3347
3348 timeout /= 2;
3349 reduced = true;
3350 net_ratelimited_function(batadv_info, soft_iface,
3351 "Forced to purge local tt entries to fit new maximum fragment MTU (%i)\n",
3352 packet_size_max);
3353 }
3354
3355
3356
3357
3358 if (reduced)
3359 batadv_tt_local_commit_changes_nolock(bat_priv);
3360
3361 spin_unlock_bh(&bat_priv->tt.commit_lock);
3362}
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372static void batadv_tt_tvlv_ogm_handler_v1(struct batadv_priv *bat_priv,
3373 struct batadv_orig_node *orig,
3374 uint8_t flags, void *tvlv_value,
3375 uint16_t tvlv_value_len)
3376{
3377 struct batadv_tvlv_tt_vlan_data *tt_vlan;
3378 struct batadv_tvlv_tt_change *tt_change;
3379 struct batadv_tvlv_tt_data *tt_data;
3380 uint16_t num_entries, num_vlan;
3381
3382 if (tvlv_value_len < sizeof(*tt_data))
3383 return;
3384
3385 tt_data = (struct batadv_tvlv_tt_data *)tvlv_value;
3386 tvlv_value_len -= sizeof(*tt_data);
3387
3388 num_vlan = ntohs(tt_data->num_vlan);
3389
3390 if (tvlv_value_len < sizeof(*tt_vlan) * num_vlan)
3391 return;
3392
3393 tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(tt_data + 1);
3394 tt_change = (struct batadv_tvlv_tt_change *)(tt_vlan + num_vlan);
3395 tvlv_value_len -= sizeof(*tt_vlan) * num_vlan;
3396
3397 num_entries = batadv_tt_entries(tvlv_value_len);
3398
3399 batadv_tt_update_orig(bat_priv, orig, tt_vlan, num_vlan, tt_change,
3400 num_entries, tt_data->ttvn);
3401}
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415static int batadv_tt_tvlv_unicast_handler_v1(struct batadv_priv *bat_priv,
3416 uint8_t *src, uint8_t *dst,
3417 void *tvlv_value,
3418 uint16_t tvlv_value_len)
3419{
3420 struct batadv_tvlv_tt_data *tt_data;
3421 uint16_t tt_vlan_len, tt_num_entries;
3422 char tt_flag;
3423 bool ret;
3424
3425 if (tvlv_value_len < sizeof(*tt_data))
3426 return NET_RX_SUCCESS;
3427
3428 tt_data = (struct batadv_tvlv_tt_data *)tvlv_value;
3429 tvlv_value_len -= sizeof(*tt_data);
3430
3431 tt_vlan_len = sizeof(struct batadv_tvlv_tt_vlan_data);
3432 tt_vlan_len *= ntohs(tt_data->num_vlan);
3433
3434 if (tvlv_value_len < tt_vlan_len)
3435 return NET_RX_SUCCESS;
3436
3437 tvlv_value_len -= tt_vlan_len;
3438 tt_num_entries = batadv_tt_entries(tvlv_value_len);
3439
3440 switch (tt_data->flags & BATADV_TT_DATA_TYPE_MASK) {
3441 case BATADV_TT_REQUEST:
3442 batadv_inc_counter(bat_priv, BATADV_CNT_TT_REQUEST_RX);
3443
3444
3445
3446
3447 ret = batadv_send_tt_response(bat_priv, tt_data, src, dst);
3448 if (!ret) {
3449 if (tt_data->flags & BATADV_TT_FULL_TABLE)
3450 tt_flag = 'F';
3451 else
3452 tt_flag = '.';
3453
3454 batadv_dbg(BATADV_DBG_TT, bat_priv,
3455 "Routing TT_REQUEST to %pM [%c]\n",
3456 dst, tt_flag);
3457
3458 return NET_RX_DROP;
3459 }
3460 break;
3461 case BATADV_TT_RESPONSE:
3462 batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_RX);
3463
3464 if (batadv_is_my_mac(bat_priv, dst)) {
3465 batadv_handle_tt_response(bat_priv, tt_data,
3466 src, tt_num_entries);
3467 return NET_RX_SUCCESS;
3468 }
3469
3470 if (tt_data->flags & BATADV_TT_FULL_TABLE)
3471 tt_flag = 'F';
3472 else
3473 tt_flag = '.';
3474
3475 batadv_dbg(BATADV_DBG_TT, bat_priv,
3476 "Routing TT_RESPONSE to %pM [%c]\n", dst, tt_flag);
3477
3478
3479 return NET_RX_DROP;
3480 }
3481
3482 return NET_RX_SUCCESS;
3483}
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496static int batadv_roam_tvlv_unicast_handler_v1(struct batadv_priv *bat_priv,
3497 uint8_t *src, uint8_t *dst,
3498 void *tvlv_value,
3499 uint16_t tvlv_value_len)
3500{
3501 struct batadv_tvlv_roam_adv *roaming_adv;
3502 struct batadv_orig_node *orig_node = NULL;
3503
3504
3505
3506
3507
3508 if (!batadv_is_my_mac(bat_priv, dst))
3509 return NET_RX_DROP;
3510
3511 if (tvlv_value_len < sizeof(*roaming_adv))
3512 goto out;
3513
3514 orig_node = batadv_orig_hash_find(bat_priv, src);
3515 if (!orig_node)
3516 goto out;
3517
3518 batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_RX);
3519 roaming_adv = (struct batadv_tvlv_roam_adv *)tvlv_value;
3520
3521 batadv_dbg(BATADV_DBG_TT, bat_priv,
3522 "Received ROAMING_ADV from %pM (client %pM)\n",
3523 src, roaming_adv->client);
3524
3525 batadv_tt_global_add(bat_priv, orig_node, roaming_adv->client,
3526 ntohs(roaming_adv->vid), BATADV_TT_CLIENT_ROAM,
3527 atomic_read(&orig_node->last_ttvn) + 1);
3528
3529out:
3530 if (orig_node)
3531 batadv_orig_node_free_ref(orig_node);
3532 return NET_RX_SUCCESS;
3533}
3534
3535
3536
3537
3538
3539
3540
3541int batadv_tt_init(struct batadv_priv *bat_priv)
3542{
3543 int ret;
3544
3545
3546 BUILD_BUG_ON(!(BATADV_TT_SYNC_MASK & BATADV_TT_REMOTE_MASK));
3547
3548 ret = batadv_tt_local_init(bat_priv);
3549 if (ret < 0)
3550 return ret;
3551
3552 ret = batadv_tt_global_init(bat_priv);
3553 if (ret < 0)
3554 return ret;
3555
3556 batadv_tvlv_handler_register(bat_priv, batadv_tt_tvlv_ogm_handler_v1,
3557 batadv_tt_tvlv_unicast_handler_v1,
3558 BATADV_TVLV_TT, 1, BATADV_NO_FLAGS);
3559
3560 batadv_tvlv_handler_register(bat_priv, NULL,
3561 batadv_roam_tvlv_unicast_handler_v1,
3562 BATADV_TVLV_ROAM, 1, BATADV_NO_FLAGS);
3563
3564 INIT_DELAYED_WORK(&bat_priv->tt.work, batadv_tt_purge);
3565 queue_delayed_work(batadv_event_workqueue, &bat_priv->tt.work,
3566 msecs_to_jiffies(BATADV_TT_WORK_PERIOD));
3567
3568 return 1;
3569}
3570