diff options
Diffstat (limited to 'net/batman-adv/vis.c')
-rw-r--r-- | net/batman-adv/vis.c | 78 |
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 | ||
31 | static void batadv_start_vis_timer(struct batadv_priv *bat_priv); | 31 | /* hash class keys */ |
32 | static struct lock_class_key batadv_vis_hash_lock_class_key; | ||
32 | 33 | ||
33 | /* free the info */ | 34 | /* free the info */ |
34 | static void batadv_free_info(struct kref *ref) | 35 | static 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, | |||
146 | static void batadv_vis_data_read_prim_sec(struct seq_file *seq, | 145 | static 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, | |||
217 | static void batadv_vis_seq_print_text_bucket(struct seq_file *seq, | 214 | static 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) | |||
304 | static void batadv_recv_list_add(struct batadv_priv *bat_priv, | 300 | static 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) | |||
570 | static int batadv_generate_vis_packet(struct batadv_priv *bat_priv) | 565 | static 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 | ||
900 | free_info: | 902 | free_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 */ | ||
936 | static 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 | } | ||