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 | } | ||
