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.c78
1 files changed, 36 insertions, 42 deletions
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c
index 0f65a9de5f74..c053244b97bd 100644
--- a/net/batman-adv/vis.c
+++ b/net/batman-adv/vis.c
@@ -1,4 +1,4 @@
1/* Copyright (C) 2008-2012 B.A.T.M.A.N. contributors: 1/* Copyright (C) 2008-2013 B.A.T.M.A.N. contributors:
2 * 2 *
3 * Simon Wunderlich 3 * Simon Wunderlich
4 * 4 *
@@ -28,14 +28,15 @@
28 28
29#define BATADV_MAX_VIS_PACKET_SIZE 1000 29#define BATADV_MAX_VIS_PACKET_SIZE 1000
30 30
31static void batadv_start_vis_timer(struct batadv_priv *bat_priv); 31/* hash class keys */
32static struct lock_class_key batadv_vis_hash_lock_class_key;
32 33
33/* free the info */ 34/* free the info */
34static void batadv_free_info(struct kref *ref) 35static void batadv_free_info(struct kref *ref)
35{ 36{
36 struct batadv_vis_info *info; 37 struct batadv_vis_info *info;
37 struct batadv_priv *bat_priv; 38 struct batadv_priv *bat_priv;
38 struct batadv_recvlist_node *entry, *tmp; 39 struct batadv_vis_recvlist_node *entry, *tmp;
39 40
40 info = container_of(ref, struct batadv_vis_info, refcount); 41 info = container_of(ref, struct batadv_vis_info, refcount);
41 bat_priv = info->bat_priv; 42 bat_priv = info->bat_priv;
@@ -96,7 +97,6 @@ batadv_vis_hash_find(struct batadv_priv *bat_priv, const void *data)
96{ 97{
97 struct batadv_hashtable *hash = bat_priv->vis.hash; 98 struct batadv_hashtable *hash = bat_priv->vis.hash;
98 struct hlist_head *head; 99 struct hlist_head *head;
99 struct hlist_node *node;
100 struct batadv_vis_info *vis_info, *vis_info_tmp = NULL; 100 struct batadv_vis_info *vis_info, *vis_info_tmp = NULL;
101 uint32_t index; 101 uint32_t index;
102 102
@@ -107,8 +107,8 @@ batadv_vis_hash_find(struct batadv_priv *bat_priv, const void *data)
107 head = &hash->table[index]; 107 head = &hash->table[index];
108 108
109 rcu_read_lock(); 109 rcu_read_lock();
110 hlist_for_each_entry_rcu(vis_info, node, head, hash_entry) { 110 hlist_for_each_entry_rcu(vis_info, head, hash_entry) {
111 if (!batadv_vis_info_cmp(node, data)) 111 if (!batadv_vis_info_cmp(&vis_info->hash_entry, data))
112 continue; 112 continue;
113 113
114 vis_info_tmp = vis_info; 114 vis_info_tmp = vis_info;
@@ -126,10 +126,9 @@ static void batadv_vis_data_insert_interface(const uint8_t *interface,
126 struct hlist_head *if_list, 126 struct hlist_head *if_list,
127 bool primary) 127 bool primary)
128{ 128{
129 struct batadv_if_list_entry *entry; 129 struct batadv_vis_if_list_entry *entry;
130 struct hlist_node *pos;
131 130
132 hlist_for_each_entry(entry, pos, if_list, list) { 131 hlist_for_each_entry(entry, if_list, list) {
133 if (batadv_compare_eth(entry->addr, interface)) 132 if (batadv_compare_eth(entry->addr, interface))
134 return; 133 return;
135 } 134 }
@@ -146,10 +145,9 @@ static void batadv_vis_data_insert_interface(const uint8_t *interface,
146static void batadv_vis_data_read_prim_sec(struct seq_file *seq, 145static void batadv_vis_data_read_prim_sec(struct seq_file *seq,
147 const struct hlist_head *if_list) 146 const struct hlist_head *if_list)
148{ 147{
149 struct batadv_if_list_entry *entry; 148 struct batadv_vis_if_list_entry *entry;
150 struct hlist_node *pos;
151 149
152 hlist_for_each_entry(entry, pos, if_list, list) { 150 hlist_for_each_entry(entry, if_list, list) {
153 if (entry->primary) 151 if (entry->primary)
154 seq_printf(seq, "PRIMARY, "); 152 seq_printf(seq, "PRIMARY, ");
155 else 153 else
@@ -196,10 +194,9 @@ static void batadv_vis_data_read_entries(struct seq_file *seq,
196 struct batadv_vis_info_entry *entries) 194 struct batadv_vis_info_entry *entries)
197{ 195{
198 int i; 196 int i;
199 struct batadv_if_list_entry *entry; 197 struct batadv_vis_if_list_entry *entry;
200 struct hlist_node *pos;
201 198
202 hlist_for_each_entry(entry, pos, list, list) { 199 hlist_for_each_entry(entry, list, list) {
203 seq_printf(seq, "%pM,", entry->addr); 200 seq_printf(seq, "%pM,", entry->addr);
204 201
205 for (i = 0; i < packet->entries; i++) 202 for (i = 0; i < packet->entries; i++)
@@ -217,17 +214,16 @@ static void batadv_vis_data_read_entries(struct seq_file *seq,
217static void batadv_vis_seq_print_text_bucket(struct seq_file *seq, 214static void batadv_vis_seq_print_text_bucket(struct seq_file *seq,
218 const struct hlist_head *head) 215 const struct hlist_head *head)
219{ 216{
220 struct hlist_node *node;
221 struct batadv_vis_info *info; 217 struct batadv_vis_info *info;
222 struct batadv_vis_packet *packet; 218 struct batadv_vis_packet *packet;
223 uint8_t *entries_pos; 219 uint8_t *entries_pos;
224 struct batadv_vis_info_entry *entries; 220 struct batadv_vis_info_entry *entries;
225 struct batadv_if_list_entry *entry; 221 struct batadv_vis_if_list_entry *entry;
226 struct hlist_node *pos, *n; 222 struct hlist_node *n;
227 223
228 HLIST_HEAD(vis_if_list); 224 HLIST_HEAD(vis_if_list);
229 225
230 hlist_for_each_entry_rcu(info, node, head, hash_entry) { 226 hlist_for_each_entry_rcu(info, head, hash_entry) {
231 packet = (struct batadv_vis_packet *)info->skb_packet->data; 227 packet = (struct batadv_vis_packet *)info->skb_packet->data;
232 entries_pos = (uint8_t *)packet + sizeof(*packet); 228 entries_pos = (uint8_t *)packet + sizeof(*packet);
233 entries = (struct batadv_vis_info_entry *)entries_pos; 229 entries = (struct batadv_vis_info_entry *)entries_pos;
@@ -239,7 +235,7 @@ static void batadv_vis_seq_print_text_bucket(struct seq_file *seq,
239 batadv_vis_data_read_entries(seq, &vis_if_list, packet, 235 batadv_vis_data_read_entries(seq, &vis_if_list, packet,
240 entries); 236 entries);
241 237
242 hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) { 238 hlist_for_each_entry_safe(entry, n, &vis_if_list, list) {
243 hlist_del(&entry->list); 239 hlist_del(&entry->list);
244 kfree(entry); 240 kfree(entry);
245 } 241 }
@@ -304,7 +300,7 @@ static void batadv_send_list_del(struct batadv_vis_info *info)
304static void batadv_recv_list_add(struct batadv_priv *bat_priv, 300static void batadv_recv_list_add(struct batadv_priv *bat_priv,
305 struct list_head *recv_list, const char *mac) 301 struct list_head *recv_list, const char *mac)
306{ 302{
307 struct batadv_recvlist_node *entry; 303 struct batadv_vis_recvlist_node *entry;
308 304
309 entry = kmalloc(sizeof(*entry), GFP_ATOMIC); 305 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
310 if (!entry) 306 if (!entry)
@@ -321,7 +317,7 @@ static int batadv_recv_list_is_in(struct batadv_priv *bat_priv,
321 const struct list_head *recv_list, 317 const struct list_head *recv_list,
322 const char *mac) 318 const char *mac)
323{ 319{
324 const struct batadv_recvlist_node *entry; 320 const struct batadv_vis_recvlist_node *entry;
325 321
326 spin_lock_bh(&bat_priv->vis.list_lock); 322 spin_lock_bh(&bat_priv->vis.list_lock);
327 list_for_each_entry(entry, recv_list, list) { 323 list_for_each_entry(entry, recv_list, list) {
@@ -518,7 +514,6 @@ static int batadv_find_best_vis_server(struct batadv_priv *bat_priv,
518{ 514{
519 struct batadv_hashtable *hash = bat_priv->orig_hash; 515 struct batadv_hashtable *hash = bat_priv->orig_hash;
520 struct batadv_neigh_node *router; 516 struct batadv_neigh_node *router;
521 struct hlist_node *node;
522 struct hlist_head *head; 517 struct hlist_head *head;
523 struct batadv_orig_node *orig_node; 518 struct batadv_orig_node *orig_node;
524 struct batadv_vis_packet *packet; 519 struct batadv_vis_packet *packet;
@@ -531,7 +526,7 @@ static int batadv_find_best_vis_server(struct batadv_priv *bat_priv,
531 head = &hash->table[i]; 526 head = &hash->table[i];
532 527
533 rcu_read_lock(); 528 rcu_read_lock();
534 hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { 529 hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
535 router = batadv_orig_node_get_router(orig_node); 530 router = batadv_orig_node_get_router(orig_node);
536 if (!router) 531 if (!router)
537 continue; 532 continue;
@@ -570,7 +565,6 @@ static bool batadv_vis_packet_full(const struct batadv_vis_info *info)
570static int batadv_generate_vis_packet(struct batadv_priv *bat_priv) 565static int batadv_generate_vis_packet(struct batadv_priv *bat_priv)
571{ 566{
572 struct batadv_hashtable *hash = bat_priv->orig_hash; 567 struct batadv_hashtable *hash = bat_priv->orig_hash;
573 struct hlist_node *node;
574 struct hlist_head *head; 568 struct hlist_head *head;
575 struct batadv_orig_node *orig_node; 569 struct batadv_orig_node *orig_node;
576 struct batadv_neigh_node *router; 570 struct batadv_neigh_node *router;
@@ -604,7 +598,7 @@ static int batadv_generate_vis_packet(struct batadv_priv *bat_priv)
604 head = &hash->table[i]; 598 head = &hash->table[i];
605 599
606 rcu_read_lock(); 600 rcu_read_lock();
607 hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { 601 hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
608 router = batadv_orig_node_get_router(orig_node); 602 router = batadv_orig_node_get_router(orig_node);
609 if (!router) 603 if (!router)
610 continue; 604 continue;
@@ -643,7 +637,7 @@ next:
643 head = &hash->table[i]; 637 head = &hash->table[i];
644 638
645 rcu_read_lock(); 639 rcu_read_lock();
646 hlist_for_each_entry_rcu(tt_common_entry, node, head, 640 hlist_for_each_entry_rcu(tt_common_entry, head,
647 hash_entry) { 641 hash_entry) {
648 packet_pos = skb_put(info->skb_packet, sizeof(*entry)); 642 packet_pos = skb_put(info->skb_packet, sizeof(*entry));
649 entry = (struct batadv_vis_info_entry *)packet_pos; 643 entry = (struct batadv_vis_info_entry *)packet_pos;
@@ -672,14 +666,14 @@ static void batadv_purge_vis_packets(struct batadv_priv *bat_priv)
672{ 666{
673 uint32_t i; 667 uint32_t i;
674 struct batadv_hashtable *hash = bat_priv->vis.hash; 668 struct batadv_hashtable *hash = bat_priv->vis.hash;
675 struct hlist_node *node, *node_tmp; 669 struct hlist_node *node_tmp;
676 struct hlist_head *head; 670 struct hlist_head *head;
677 struct batadv_vis_info *info; 671 struct batadv_vis_info *info;
678 672
679 for (i = 0; i < hash->size; i++) { 673 for (i = 0; i < hash->size; i++) {
680 head = &hash->table[i]; 674 head = &hash->table[i];
681 675
682 hlist_for_each_entry_safe(info, node, node_tmp, 676 hlist_for_each_entry_safe(info, node_tmp,
683 head, hash_entry) { 677 head, hash_entry) {
684 /* never purge own data. */ 678 /* never purge own data. */
685 if (info == bat_priv->vis.my_info) 679 if (info == bat_priv->vis.my_info)
@@ -687,7 +681,7 @@ static void batadv_purge_vis_packets(struct batadv_priv *bat_priv)
687 681
688 if (batadv_has_timed_out(info->first_seen, 682 if (batadv_has_timed_out(info->first_seen,
689 BATADV_VIS_TIMEOUT)) { 683 BATADV_VIS_TIMEOUT)) {
690 hlist_del(node); 684 hlist_del(&info->hash_entry);
691 batadv_send_list_del(info); 685 batadv_send_list_del(info);
692 kref_put(&info->refcount, batadv_free_info); 686 kref_put(&info->refcount, batadv_free_info);
693 } 687 }
@@ -699,7 +693,6 @@ static void batadv_broadcast_vis_packet(struct batadv_priv *bat_priv,
699 struct batadv_vis_info *info) 693 struct batadv_vis_info *info)
700{ 694{
701 struct batadv_hashtable *hash = bat_priv->orig_hash; 695 struct batadv_hashtable *hash = bat_priv->orig_hash;
702 struct hlist_node *node;
703 struct hlist_head *head; 696 struct hlist_head *head;
704 struct batadv_orig_node *orig_node; 697 struct batadv_orig_node *orig_node;
705 struct batadv_vis_packet *packet; 698 struct batadv_vis_packet *packet;
@@ -714,7 +707,7 @@ static void batadv_broadcast_vis_packet(struct batadv_priv *bat_priv,
714 head = &hash->table[i]; 707 head = &hash->table[i];
715 708
716 rcu_read_lock(); 709 rcu_read_lock();
717 hlist_for_each_entry_rcu(orig_node, node, head, hash_entry) { 710 hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
718 /* if it's a vis server and reachable, send it. */ 711 /* if it's a vis server and reachable, send it. */
719 if (!(orig_node->flags & BATADV_VIS_SERVER)) 712 if (!(orig_node->flags & BATADV_VIS_SERVER))
720 continue; 713 continue;
@@ -827,7 +820,9 @@ static void batadv_send_vis_packets(struct work_struct *work)
827 kref_put(&info->refcount, batadv_free_info); 820 kref_put(&info->refcount, batadv_free_info);
828 } 821 }
829 spin_unlock_bh(&bat_priv->vis.hash_lock); 822 spin_unlock_bh(&bat_priv->vis.hash_lock);
830 batadv_start_vis_timer(bat_priv); 823
824 queue_delayed_work(batadv_event_workqueue, &bat_priv->vis.work,
825 msecs_to_jiffies(BATADV_VIS_INTERVAL));
831} 826}
832 827
833/* init the vis server. this may only be called when if_list is already 828/* init the vis server. this may only be called when if_list is already
@@ -852,6 +847,9 @@ int batadv_vis_init(struct batadv_priv *bat_priv)
852 goto err; 847 goto err;
853 } 848 }
854 849
850 batadv_hash_set_lock_class(bat_priv->vis.hash,
851 &batadv_vis_hash_lock_class_key);
852
855 bat_priv->vis.my_info = kmalloc(BATADV_MAX_VIS_PACKET_SIZE, GFP_ATOMIC); 853 bat_priv->vis.my_info = kmalloc(BATADV_MAX_VIS_PACKET_SIZE, GFP_ATOMIC);
856 if (!bat_priv->vis.my_info) 854 if (!bat_priv->vis.my_info)
857 goto err; 855 goto err;
@@ -894,7 +892,11 @@ int batadv_vis_init(struct batadv_priv *bat_priv)
894 } 892 }
895 893
896 spin_unlock_bh(&bat_priv->vis.hash_lock); 894 spin_unlock_bh(&bat_priv->vis.hash_lock);
897 batadv_start_vis_timer(bat_priv); 895
896 INIT_DELAYED_WORK(&bat_priv->vis.work, batadv_send_vis_packets);
897 queue_delayed_work(batadv_event_workqueue, &bat_priv->vis.work,
898 msecs_to_jiffies(BATADV_VIS_INTERVAL));
899
898 return 0; 900 return 0;
899 901
900free_info: 902free_info:
@@ -931,11 +933,3 @@ void batadv_vis_quit(struct batadv_priv *bat_priv)
931 bat_priv->vis.my_info = NULL; 933 bat_priv->vis.my_info = NULL;
932 spin_unlock_bh(&bat_priv->vis.hash_lock); 934 spin_unlock_bh(&bat_priv->vis.hash_lock);
933} 935}
934
935/* schedule packets for (re)transmission */
936static void batadv_start_vis_timer(struct batadv_priv *bat_priv)
937{
938 INIT_DELAYED_WORK(&bat_priv->vis.work, batadv_send_vis_packets);
939 queue_delayed_work(batadv_event_workqueue, &bat_priv->vis.work,
940 msecs_to_jiffies(BATADV_VIS_INTERVAL));
941}