aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/vis.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/batman-adv/vis.c')
-rw-r--r--net/batman-adv/vis.c104
1 files changed, 43 insertions, 61 deletions
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c
index c39f20cc1ba..8a1b98589d7 100644
--- a/net/batman-adv/vis.c
+++ b/net/batman-adv/vis.c
@@ -30,22 +30,6 @@
30 30
31#define MAX_VIS_PACKET_SIZE 1000 31#define MAX_VIS_PACKET_SIZE 1000
32 32
33/* Returns the smallest signed integer in two's complement with the sizeof x */
34#define smallest_signed_int(x) (1u << (7u + 8u * (sizeof(x) - 1u)))
35
36/* Checks if a sequence number x is a predecessor/successor of y.
37 * they handle overflows/underflows and can correctly check for a
38 * predecessor/successor unless the variable sequence number has grown by
39 * more then 2**(bitwidth(x)-1)-1.
40 * This means that for a uint8_t with the maximum value 255, it would think:
41 * - when adding nothing - it is neither a predecessor nor a successor
42 * - before adding more than 127 to the starting value - it is a predecessor,
43 * - when adding 128 - it is neither a predecessor nor a successor,
44 * - after adding more than 127 to the starting value - it is a successor */
45#define seq_before(x, y) ({typeof(x) _dummy = (x - y); \
46 _dummy > smallest_signed_int(_dummy); })
47#define seq_after(x, y) seq_before(y, x)
48
49static void start_vis_timer(struct bat_priv *bat_priv); 33static void start_vis_timer(struct bat_priv *bat_priv);
50 34
51/* free the info */ 35/* free the info */
@@ -68,10 +52,10 @@ static void free_info(struct kref *ref)
68} 52}
69 53
70/* Compare two vis packets, used by the hashing algorithm */ 54/* Compare two vis packets, used by the hashing algorithm */
71static int vis_info_cmp(struct hlist_node *node, void *data2) 55static int vis_info_cmp(const struct hlist_node *node, const void *data2)
72{ 56{
73 struct vis_info *d1, *d2; 57 const struct vis_info *d1, *d2;
74 struct vis_packet *p1, *p2; 58 const struct vis_packet *p1, *p2;
75 59
76 d1 = container_of(node, struct vis_info, hash_entry); 60 d1 = container_of(node, struct vis_info, hash_entry);
77 d2 = data2; 61 d2 = data2;
@@ -82,11 +66,11 @@ static int vis_info_cmp(struct hlist_node *node, void *data2)
82 66
83/* hash function to choose an entry in a hash table of given size */ 67/* hash function to choose an entry in a hash table of given size */
84/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */ 68/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */
85static int vis_info_choose(void *data, int size) 69static int vis_info_choose(const void *data, int size)
86{ 70{
87 struct vis_info *vis_info = data; 71 const struct vis_info *vis_info = data;
88 struct vis_packet *packet; 72 const struct vis_packet *packet;
89 unsigned char *key; 73 const unsigned char *key;
90 uint32_t hash = 0; 74 uint32_t hash = 0;
91 size_t i; 75 size_t i;
92 76
@@ -106,7 +90,7 @@ static int vis_info_choose(void *data, int size)
106} 90}
107 91
108static struct vis_info *vis_hash_find(struct bat_priv *bat_priv, 92static struct vis_info *vis_hash_find(struct bat_priv *bat_priv,
109 void *data) 93 const void *data)
110{ 94{
111 struct hashtable_t *hash = bat_priv->vis_hash; 95 struct hashtable_t *hash = bat_priv->vis_hash;
112 struct hlist_head *head; 96 struct hlist_head *head;
@@ -143,7 +127,7 @@ static void vis_data_insert_interface(const uint8_t *interface,
143 struct hlist_node *pos; 127 struct hlist_node *pos;
144 128
145 hlist_for_each_entry(entry, pos, if_list, list) { 129 hlist_for_each_entry(entry, pos, if_list, list) {
146 if (compare_eth(entry->addr, (void *)interface)) 130 if (compare_eth(entry->addr, interface))
147 return; 131 return;
148 } 132 }
149 133
@@ -156,7 +140,8 @@ static void vis_data_insert_interface(const uint8_t *interface,
156 hlist_add_head(&entry->list, if_list); 140 hlist_add_head(&entry->list, if_list);
157} 141}
158 142
159static ssize_t vis_data_read_prim_sec(char *buff, struct hlist_head *if_list) 143static ssize_t vis_data_read_prim_sec(char *buff,
144 const struct hlist_head *if_list)
160{ 145{
161 struct if_list_entry *entry; 146 struct if_list_entry *entry;
162 struct hlist_node *pos; 147 struct hlist_node *pos;
@@ -189,8 +174,9 @@ static size_t vis_data_count_prim_sec(struct hlist_head *if_list)
189} 174}
190 175
191/* read an entry */ 176/* read an entry */
192static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry, 177static ssize_t vis_data_read_entry(char *buff,
193 uint8_t *src, bool primary) 178 const struct vis_info_entry *entry,
179 const uint8_t *src, bool primary)
194{ 180{
195 /* maximal length: max(4+17+2, 3+17+1+3+2) == 26 */ 181 /* maximal length: max(4+17+2, 3+17+1+3+2) == 26 */
196 if (primary && entry->quality == 0) 182 if (primary && entry->quality == 0)
@@ -239,7 +225,7 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
239 hlist_for_each_entry_rcu(info, node, head, hash_entry) { 225 hlist_for_each_entry_rcu(info, node, head, hash_entry) {
240 packet = (struct vis_packet *)info->skb_packet->data; 226 packet = (struct vis_packet *)info->skb_packet->data;
241 entries = (struct vis_info_entry *) 227 entries = (struct vis_info_entry *)
242 ((char *)packet + sizeof(struct vis_packet)); 228 ((char *)packet + sizeof(*packet));
243 229
244 for (j = 0; j < packet->entries; j++) { 230 for (j = 0; j < packet->entries; j++) {
245 if (entries[j].quality == 0) 231 if (entries[j].quality == 0)
@@ -287,7 +273,7 @@ int vis_seq_print_text(struct seq_file *seq, void *offset)
287 hlist_for_each_entry_rcu(info, node, head, hash_entry) { 273 hlist_for_each_entry_rcu(info, node, head, hash_entry) {
288 packet = (struct vis_packet *)info->skb_packet->data; 274 packet = (struct vis_packet *)info->skb_packet->data;
289 entries = (struct vis_info_entry *) 275 entries = (struct vis_info_entry *)
290 ((char *)packet + sizeof(struct vis_packet)); 276 ((char *)packet + sizeof(*packet));
291 277
292 for (j = 0; j < packet->entries; j++) { 278 for (j = 0; j < packet->entries; j++) {
293 if (entries[j].quality == 0) 279 if (entries[j].quality == 0)
@@ -361,11 +347,11 @@ static void send_list_del(struct vis_info *info)
361 347
362/* tries to add one entry to the receive list. */ 348/* tries to add one entry to the receive list. */
363static void recv_list_add(struct bat_priv *bat_priv, 349static void recv_list_add(struct bat_priv *bat_priv,
364 struct list_head *recv_list, char *mac) 350 struct list_head *recv_list, const char *mac)
365{ 351{
366 struct recvlist_node *entry; 352 struct recvlist_node *entry;
367 353
368 entry = kmalloc(sizeof(struct recvlist_node), GFP_ATOMIC); 354 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
369 if (!entry) 355 if (!entry)
370 return; 356 return;
371 357
@@ -377,9 +363,9 @@ static void recv_list_add(struct bat_priv *bat_priv,
377 363
378/* returns 1 if this mac is in the recv_list */ 364/* returns 1 if this mac is in the recv_list */
379static int recv_list_is_in(struct bat_priv *bat_priv, 365static int recv_list_is_in(struct bat_priv *bat_priv,
380 struct list_head *recv_list, char *mac) 366 const struct list_head *recv_list, const char *mac)
381{ 367{
382 struct recvlist_node *entry; 368 const struct recvlist_node *entry;
383 369
384 spin_lock_bh(&bat_priv->vis_list_lock); 370 spin_lock_bh(&bat_priv->vis_list_lock);
385 list_for_each_entry(entry, recv_list, list) { 371 list_for_each_entry(entry, recv_list, list) {
@@ -412,11 +398,11 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv,
412 return NULL; 398 return NULL;
413 399
414 /* see if the packet is already in vis_hash */ 400 /* see if the packet is already in vis_hash */
415 search_elem.skb_packet = dev_alloc_skb(sizeof(struct vis_packet)); 401 search_elem.skb_packet = dev_alloc_skb(sizeof(*search_packet));
416 if (!search_elem.skb_packet) 402 if (!search_elem.skb_packet)
417 return NULL; 403 return NULL;
418 search_packet = (struct vis_packet *)skb_put(search_elem.skb_packet, 404 search_packet = (struct vis_packet *)skb_put(search_elem.skb_packet,
419 sizeof(struct vis_packet)); 405 sizeof(*search_packet));
420 406
421 memcpy(search_packet->vis_orig, vis_packet->vis_orig, ETH_ALEN); 407 memcpy(search_packet->vis_orig, vis_packet->vis_orig, ETH_ALEN);
422 old_info = vis_hash_find(bat_priv, &search_elem); 408 old_info = vis_hash_find(bat_priv, &search_elem);
@@ -442,27 +428,26 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv,
442 kref_put(&old_info->refcount, free_info); 428 kref_put(&old_info->refcount, free_info);
443 } 429 }
444 430
445 info = kmalloc(sizeof(struct vis_info), GFP_ATOMIC); 431 info = kmalloc(sizeof(*info), GFP_ATOMIC);
446 if (!info) 432 if (!info)
447 return NULL; 433 return NULL;
448 434
449 info->skb_packet = dev_alloc_skb(sizeof(struct vis_packet) + 435 info->skb_packet = dev_alloc_skb(sizeof(*packet) + vis_info_len +
450 vis_info_len + sizeof(struct ethhdr)); 436 sizeof(struct ethhdr));
451 if (!info->skb_packet) { 437 if (!info->skb_packet) {
452 kfree(info); 438 kfree(info);
453 return NULL; 439 return NULL;
454 } 440 }
455 skb_reserve(info->skb_packet, sizeof(struct ethhdr)); 441 skb_reserve(info->skb_packet, sizeof(struct ethhdr));
456 packet = (struct vis_packet *)skb_put(info->skb_packet, 442 packet = (struct vis_packet *)skb_put(info->skb_packet, sizeof(*packet)
457 sizeof(struct vis_packet) + 443 + vis_info_len);
458 vis_info_len);
459 444
460 kref_init(&info->refcount); 445 kref_init(&info->refcount);
461 INIT_LIST_HEAD(&info->send_list); 446 INIT_LIST_HEAD(&info->send_list);
462 INIT_LIST_HEAD(&info->recv_list); 447 INIT_LIST_HEAD(&info->recv_list);
463 info->first_seen = jiffies; 448 info->first_seen = jiffies;
464 info->bat_priv = bat_priv; 449 info->bat_priv = bat_priv;
465 memcpy(packet, vis_packet, sizeof(struct vis_packet) + vis_info_len); 450 memcpy(packet, vis_packet, sizeof(*packet) + vis_info_len);
466 451
467 /* initialize and add new packet. */ 452 /* initialize and add new packet. */
468 *is_new = 1; 453 *is_new = 1;
@@ -599,9 +584,9 @@ static int find_best_vis_server(struct bat_priv *bat_priv,
599} 584}
600 585
601/* Return true if the vis packet is full. */ 586/* Return true if the vis packet is full. */
602static bool vis_packet_full(struct vis_info *info) 587static bool vis_packet_full(const struct vis_info *info)
603{ 588{
604 struct vis_packet *packet; 589 const struct vis_packet *packet;
605 packet = (struct vis_packet *)info->skb_packet->data; 590 packet = (struct vis_packet *)info->skb_packet->data;
606 591
607 if (MAX_VIS_PACKET_SIZE / sizeof(struct vis_info_entry) 592 if (MAX_VIS_PACKET_SIZE / sizeof(struct vis_info_entry)
@@ -619,7 +604,7 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
619 struct hlist_head *head; 604 struct hlist_head *head;
620 struct orig_node *orig_node; 605 struct orig_node *orig_node;
621 struct neigh_node *router; 606 struct neigh_node *router;
622 struct vis_info *info = (struct vis_info *)bat_priv->my_vis_info; 607 struct vis_info *info = bat_priv->my_vis_info;
623 struct vis_packet *packet = (struct vis_packet *)info->skb_packet->data; 608 struct vis_packet *packet = (struct vis_packet *)info->skb_packet->data;
624 struct vis_info_entry *entry; 609 struct vis_info_entry *entry;
625 struct tt_local_entry *tt_local_entry; 610 struct tt_local_entry *tt_local_entry;
@@ -632,7 +617,7 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
632 packet->ttl = TTL; 617 packet->ttl = TTL;
633 packet->seqno = htonl(ntohl(packet->seqno) + 1); 618 packet->seqno = htonl(ntohl(packet->seqno) + 1);
634 packet->entries = 0; 619 packet->entries = 0;
635 skb_trim(info->skb_packet, sizeof(struct vis_packet)); 620 skb_trim(info->skb_packet, sizeof(*packet));
636 621
637 if (packet->vis_type == VIS_TYPE_CLIENT_UPDATE) { 622 if (packet->vis_type == VIS_TYPE_CLIENT_UPDATE) {
638 best_tq = find_best_vis_server(bat_priv, info); 623 best_tq = find_best_vis_server(bat_priv, info);
@@ -680,11 +665,12 @@ next:
680 665
681 hash = bat_priv->tt_local_hash; 666 hash = bat_priv->tt_local_hash;
682 667
683 spin_lock_bh(&bat_priv->tt_lhash_lock);
684 for (i = 0; i < hash->size; i++) { 668 for (i = 0; i < hash->size; i++) {
685 head = &hash->table[i]; 669 head = &hash->table[i];
686 670
687 hlist_for_each_entry(tt_local_entry, node, head, hash_entry) { 671 rcu_read_lock();
672 hlist_for_each_entry_rcu(tt_local_entry, node, head,
673 hash_entry) {
688 entry = (struct vis_info_entry *) 674 entry = (struct vis_info_entry *)
689 skb_put(info->skb_packet, 675 skb_put(info->skb_packet,
690 sizeof(*entry)); 676 sizeof(*entry));
@@ -693,14 +679,12 @@ next:
693 entry->quality = 0; /* 0 means TT */ 679 entry->quality = 0; /* 0 means TT */
694 packet->entries++; 680 packet->entries++;
695 681
696 if (vis_packet_full(info)) { 682 if (vis_packet_full(info))
697 spin_unlock_bh(&bat_priv->tt_lhash_lock); 683 goto unlock;
698 return 0;
699 }
700 } 684 }
685 rcu_read_unlock();
701 } 686 }
702 687
703 spin_unlock_bh(&bat_priv->tt_lhash_lock);
704 return 0; 688 return 0;
705 689
706unlock: 690unlock:
@@ -908,17 +892,15 @@ int vis_init(struct bat_priv *bat_priv)
908 goto err; 892 goto err;
909 } 893 }
910 894
911 bat_priv->my_vis_info->skb_packet = dev_alloc_skb( 895 bat_priv->my_vis_info->skb_packet = dev_alloc_skb(sizeof(*packet) +
912 sizeof(struct vis_packet) + 896 MAX_VIS_PACKET_SIZE +
913 MAX_VIS_PACKET_SIZE + 897 sizeof(struct ethhdr));
914 sizeof(struct ethhdr));
915 if (!bat_priv->my_vis_info->skb_packet) 898 if (!bat_priv->my_vis_info->skb_packet)
916 goto free_info; 899 goto free_info;
917 900
918 skb_reserve(bat_priv->my_vis_info->skb_packet, sizeof(struct ethhdr)); 901 skb_reserve(bat_priv->my_vis_info->skb_packet, sizeof(struct ethhdr));
919 packet = (struct vis_packet *)skb_put( 902 packet = (struct vis_packet *)skb_put(bat_priv->my_vis_info->skb_packet,
920 bat_priv->my_vis_info->skb_packet, 903 sizeof(*packet));
921 sizeof(struct vis_packet));
922 904
923 /* prefill the vis info */ 905 /* prefill the vis info */
924 bat_priv->my_vis_info->first_seen = jiffies - 906 bat_priv->my_vis_info->first_seen = jiffies -