aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv
diff options
context:
space:
mode:
authorMarek Lindner <lindner_marek@yahoo.de>2011-01-19 15:01:44 -0500
committerMarek Lindner <lindner_marek@yahoo.de>2011-03-05 06:52:04 -0500
commitd0072609baebaffb522083d367f4f195187f60f8 (patch)
tree44e014264e2a2815d63f09c6ba9283d2866cbf48 /net/batman-adv
parent1605d0d60b66b9461cfcff86f8cfc80964f23430 (diff)
batman-adv: remove orig_hash spinlock
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Diffstat (limited to 'net/batman-adv')
-rw-r--r--net/batman-adv/icmp_socket.c16
-rw-r--r--net/batman-adv/main.c1
-rw-r--r--net/batman-adv/originator.c21
-rw-r--r--net/batman-adv/routing.c75
-rw-r--r--net/batman-adv/types.h1
-rw-r--r--net/batman-adv/unicast.c36
-rw-r--r--net/batman-adv/vis.c36
7 files changed, 38 insertions, 148 deletions
diff --git a/net/batman-adv/icmp_socket.c b/net/batman-adv/icmp_socket.c
index a0a35b1af167..34ce56c358e5 100644
--- a/net/batman-adv/icmp_socket.c
+++ b/net/batman-adv/icmp_socket.c
@@ -158,9 +158,7 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
158 158
159 struct orig_node *orig_node = NULL; 159 struct orig_node *orig_node = NULL;
160 struct neigh_node *neigh_node = NULL; 160 struct neigh_node *neigh_node = NULL;
161 struct batman_if *batman_if;
162 size_t packet_len = sizeof(struct icmp_packet); 161 size_t packet_len = sizeof(struct icmp_packet);
163 uint8_t dstaddr[ETH_ALEN];
164 162
165 if (len < sizeof(struct icmp_packet)) { 163 if (len < sizeof(struct icmp_packet)) {
166 bat_dbg(DBG_BATMAN, bat_priv, 164 bat_dbg(DBG_BATMAN, bat_priv,
@@ -220,7 +218,6 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
220 if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) 218 if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE)
221 goto dst_unreach; 219 goto dst_unreach;
222 220
223 spin_lock_bh(&bat_priv->orig_hash_lock);
224 rcu_read_lock(); 221 rcu_read_lock();
225 orig_node = orig_hash_find(bat_priv, icmp_packet->dst); 222 orig_node = orig_hash_find(bat_priv, icmp_packet->dst);
226 223
@@ -239,14 +236,10 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
239 236
240 rcu_read_unlock(); 237 rcu_read_unlock();
241 238
242 batman_if = orig_node->router->if_incoming; 239 if (!neigh_node->if_incoming)
243 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
244 spin_unlock_bh(&bat_priv->orig_hash_lock);
245
246 if (!batman_if)
247 goto dst_unreach; 240 goto dst_unreach;
248 241
249 if (batman_if->if_status != IF_ACTIVE) 242 if (neigh_node->if_incoming->if_status != IF_ACTIVE)
250 goto dst_unreach; 243 goto dst_unreach;
251 244
252 memcpy(icmp_packet->orig, 245 memcpy(icmp_packet->orig,
@@ -254,14 +247,13 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff,
254 247
255 if (packet_len == sizeof(struct icmp_packet_rr)) 248 if (packet_len == sizeof(struct icmp_packet_rr))
256 memcpy(icmp_packet->rr, 249 memcpy(icmp_packet->rr,
257 batman_if->net_dev->dev_addr, ETH_ALEN); 250 neigh_node->if_incoming->net_dev->dev_addr, ETH_ALEN);
258 251
259 send_skb_packet(skb, batman_if, dstaddr); 252 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
260 goto out; 253 goto out;
261 254
262unlock: 255unlock:
263 rcu_read_unlock(); 256 rcu_read_unlock();
264 spin_unlock_bh(&bat_priv->orig_hash_lock);
265dst_unreach: 257dst_unreach:
266 icmp_packet->msg_type = DESTINATION_UNREACHABLE; 258 icmp_packet->msg_type = DESTINATION_UNREACHABLE;
267 bat_socket_add_packet(socket_client, icmp_packet, packet_len); 259 bat_socket_add_packet(socket_client, icmp_packet, packet_len);
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index 3f977eab2987..09c21f26156c 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -79,7 +79,6 @@ int mesh_init(struct net_device *soft_iface)
79{ 79{
80 struct bat_priv *bat_priv = netdev_priv(soft_iface); 80 struct bat_priv *bat_priv = netdev_priv(soft_iface);
81 81
82 spin_lock_init(&bat_priv->orig_hash_lock);
83 spin_lock_init(&bat_priv->forw_bat_list_lock); 82 spin_lock_init(&bat_priv->forw_bat_list_lock);
84 spin_lock_init(&bat_priv->forw_bcast_list_lock); 83 spin_lock_init(&bat_priv->forw_bcast_list_lock);
85 spin_lock_init(&bat_priv->hna_lhash_lock); 84 spin_lock_init(&bat_priv->hna_lhash_lock);
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index 69e27a243fd0..a8d0262e9d90 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -44,18 +44,15 @@ int originator_init(struct bat_priv *bat_priv)
44 if (bat_priv->orig_hash) 44 if (bat_priv->orig_hash)
45 return 1; 45 return 1;
46 46
47 spin_lock_bh(&bat_priv->orig_hash_lock);
48 bat_priv->orig_hash = hash_new(1024); 47 bat_priv->orig_hash = hash_new(1024);
49 48
50 if (!bat_priv->orig_hash) 49 if (!bat_priv->orig_hash)
51 goto err; 50 goto err;
52 51
53 spin_unlock_bh(&bat_priv->orig_hash_lock);
54 start_purge_timer(bat_priv); 52 start_purge_timer(bat_priv);
55 return 1; 53 return 1;
56 54
57err: 55err:
58 spin_unlock_bh(&bat_priv->orig_hash_lock);
59 return 0; 56 return 0;
60} 57}
61 58
@@ -159,7 +156,6 @@ void originator_free(struct bat_priv *bat_priv)
159 156
160 cancel_delayed_work_sync(&bat_priv->orig_work); 157 cancel_delayed_work_sync(&bat_priv->orig_work);
161 158
162 spin_lock_bh(&bat_priv->orig_hash_lock);
163 bat_priv->orig_hash = NULL; 159 bat_priv->orig_hash = NULL;
164 160
165 for (i = 0; i < hash->size; i++) { 161 for (i = 0; i < hash->size; i++) {
@@ -177,7 +173,6 @@ void originator_free(struct bat_priv *bat_priv)
177 } 173 }
178 174
179 hash_destroy(hash); 175 hash_destroy(hash);
180 spin_unlock_bh(&bat_priv->orig_hash_lock);
181} 176}
182 177
183/* this function finds or creates an originator entry for the given 178/* this function finds or creates an originator entry for the given
@@ -342,8 +337,6 @@ static void _purge_orig(struct bat_priv *bat_priv)
342 if (!hash) 337 if (!hash)
343 return; 338 return;
344 339
345 spin_lock_bh(&bat_priv->orig_hash_lock);
346
347 /* for all origins... */ 340 /* for all origins... */
348 for (i = 0; i < hash->size; i++) { 341 for (i = 0; i < hash->size; i++) {
349 head = &hash->table[i]; 342 head = &hash->table[i];
@@ -367,8 +360,6 @@ static void _purge_orig(struct bat_priv *bat_priv)
367 spin_unlock_bh(list_lock); 360 spin_unlock_bh(list_lock);
368 } 361 }
369 362
370 spin_unlock_bh(&bat_priv->orig_hash_lock);
371
372 gw_node_purge(bat_priv); 363 gw_node_purge(bat_priv);
373 gw_election(bat_priv); 364 gw_election(bat_priv);
374 365
@@ -425,8 +416,6 @@ int orig_seq_print_text(struct seq_file *seq, void *offset)
425 "Originator", "last-seen", "#", TQ_MAX_VALUE, "Nexthop", 416 "Originator", "last-seen", "#", TQ_MAX_VALUE, "Nexthop",
426 "outgoingIF", "Potential nexthops"); 417 "outgoingIF", "Potential nexthops");
427 418
428 spin_lock_bh(&bat_priv->orig_hash_lock);
429
430 for (i = 0; i < hash->size; i++) { 419 for (i = 0; i < hash->size; i++) {
431 head = &hash->table[i]; 420 head = &hash->table[i];
432 421
@@ -462,8 +451,6 @@ int orig_seq_print_text(struct seq_file *seq, void *offset)
462 rcu_read_unlock(); 451 rcu_read_unlock();
463 } 452 }
464 453
465 spin_unlock_bh(&bat_priv->orig_hash_lock);
466
467 if ((batman_count == 0)) 454 if ((batman_count == 0))
468 seq_printf(seq, "No batman nodes in range ...\n"); 455 seq_printf(seq, "No batman nodes in range ...\n");
469 456
@@ -511,8 +498,6 @@ int orig_hash_add_if(struct batman_if *batman_if, int max_if_num)
511 498
512 /* resize all orig nodes because orig_node->bcast_own(_sum) depend on 499 /* resize all orig nodes because orig_node->bcast_own(_sum) depend on
513 * if_num */ 500 * if_num */
514 spin_lock_bh(&bat_priv->orig_hash_lock);
515
516 for (i = 0; i < hash->size; i++) { 501 for (i = 0; i < hash->size; i++) {
517 head = &hash->table[i]; 502 head = &hash->table[i];
518 503
@@ -528,12 +513,10 @@ int orig_hash_add_if(struct batman_if *batman_if, int max_if_num)
528 rcu_read_unlock(); 513 rcu_read_unlock();
529 } 514 }
530 515
531 spin_unlock_bh(&bat_priv->orig_hash_lock);
532 return 0; 516 return 0;
533 517
534err: 518err:
535 rcu_read_unlock(); 519 rcu_read_unlock();
536 spin_unlock_bh(&bat_priv->orig_hash_lock);
537 return -ENOMEM; 520 return -ENOMEM;
538} 521}
539 522
@@ -601,8 +584,6 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num)
601 584
602 /* resize all orig nodes because orig_node->bcast_own(_sum) depend on 585 /* resize all orig nodes because orig_node->bcast_own(_sum) depend on
603 * if_num */ 586 * if_num */
604 spin_lock_bh(&bat_priv->orig_hash_lock);
605
606 for (i = 0; i < hash->size; i++) { 587 for (i = 0; i < hash->size; i++) {
607 head = &hash->table[i]; 588 head = &hash->table[i];
608 589
@@ -637,11 +618,9 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num)
637 rcu_read_unlock(); 618 rcu_read_unlock();
638 619
639 batman_if->if_num = -1; 620 batman_if->if_num = -1;
640 spin_unlock_bh(&bat_priv->orig_hash_lock);
641 return 0; 621 return 0;
642 622
643err: 623err:
644 rcu_read_unlock(); 624 rcu_read_unlock();
645 spin_unlock_bh(&bat_priv->orig_hash_lock);
646 return -ENOMEM; 625 return -ENOMEM;
647} 626}
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index c4b7ae9380ef..3cfa2c74c94f 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -46,8 +46,6 @@ void slide_own_bcast_window(struct batman_if *batman_if)
46 int i; 46 int i;
47 size_t word_index; 47 size_t word_index;
48 48
49 spin_lock_bh(&bat_priv->orig_hash_lock);
50
51 for (i = 0; i < hash->size; i++) { 49 for (i = 0; i < hash->size; i++) {
52 head = &hash->table[i]; 50 head = &hash->table[i];
53 51
@@ -64,8 +62,6 @@ void slide_own_bcast_window(struct batman_if *batman_if)
64 } 62 }
65 rcu_read_unlock(); 63 rcu_read_unlock();
66 } 64 }
67
68 spin_unlock_bh(&bat_priv->orig_hash_lock);
69} 65}
70 66
71static void update_HNA(struct bat_priv *bat_priv, struct orig_node *orig_node, 67static void update_HNA(struct bat_priv *bat_priv, struct orig_node *orig_node,
@@ -771,7 +767,7 @@ void receive_bat_packet(struct ethhdr *ethhdr,
771 orig_node : 767 orig_node :
772 get_orig_node(bat_priv, ethhdr->h_source)); 768 get_orig_node(bat_priv, ethhdr->h_source));
773 if (!orig_neigh_node) 769 if (!orig_neigh_node)
774 goto out_neigh; 770 goto out;
775 771
776 /* drop packet if sender is not a direct neighbor and if we 772 /* drop packet if sender is not a direct neighbor and if we
777 * don't route towards it */ 773 * don't route towards it */
@@ -834,7 +830,6 @@ out:
834 830
835int recv_bat_packet(struct sk_buff *skb, struct batman_if *batman_if) 831int recv_bat_packet(struct sk_buff *skb, struct batman_if *batman_if)
836{ 832{
837 struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface);
838 struct ethhdr *ethhdr; 833 struct ethhdr *ethhdr;
839 834
840 /* drop packet if it has not necessary minimum size */ 835 /* drop packet if it has not necessary minimum size */
@@ -861,12 +856,10 @@ int recv_bat_packet(struct sk_buff *skb, struct batman_if *batman_if)
861 856
862 ethhdr = (struct ethhdr *)skb_mac_header(skb); 857 ethhdr = (struct ethhdr *)skb_mac_header(skb);
863 858
864 spin_lock_bh(&bat_priv->orig_hash_lock);
865 receive_aggr_bat_packet(ethhdr, 859 receive_aggr_bat_packet(ethhdr,
866 skb->data, 860 skb->data,
867 skb_headlen(skb), 861 skb_headlen(skb),
868 batman_if); 862 batman_if);
869 spin_unlock_bh(&bat_priv->orig_hash_lock);
870 863
871 kfree_skb(skb); 864 kfree_skb(skb);
872 return NET_RX_SUCCESS; 865 return NET_RX_SUCCESS;
@@ -878,8 +871,6 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv,
878 struct orig_node *orig_node = NULL; 871 struct orig_node *orig_node = NULL;
879 struct neigh_node *neigh_node = NULL; 872 struct neigh_node *neigh_node = NULL;
880 struct icmp_packet_rr *icmp_packet; 873 struct icmp_packet_rr *icmp_packet;
881 struct batman_if *batman_if;
882 uint8_t dstaddr[ETH_ALEN];
883 int ret = NET_RX_DROP; 874 int ret = NET_RX_DROP;
884 875
885 icmp_packet = (struct icmp_packet_rr *)skb->data; 876 icmp_packet = (struct icmp_packet_rr *)skb->data;
@@ -895,7 +886,6 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv,
895 886
896 /* answer echo request (ping) */ 887 /* answer echo request (ping) */
897 /* get routing information */ 888 /* get routing information */
898 spin_lock_bh(&bat_priv->orig_hash_lock);
899 rcu_read_lock(); 889 rcu_read_lock();
900 orig_node = orig_hash_find(bat_priv, icmp_packet->orig); 890 orig_node = orig_hash_find(bat_priv, icmp_packet->orig);
901 891
@@ -914,12 +904,6 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv,
914 904
915 rcu_read_unlock(); 905 rcu_read_unlock();
916 906
917 /* don't lock while sending the packets ... we therefore
918 * copy the required data before sending */
919 batman_if = orig_node->router->if_incoming;
920 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
921 spin_unlock_bh(&bat_priv->orig_hash_lock);
922
923 /* create a copy of the skb, if needed, to modify it. */ 907 /* create a copy of the skb, if needed, to modify it. */
924 if (skb_cow(skb, sizeof(struct ethhdr)) < 0) 908 if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
925 goto out; 909 goto out;
@@ -932,13 +916,12 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv,
932 icmp_packet->msg_type = ECHO_REPLY; 916 icmp_packet->msg_type = ECHO_REPLY;
933 icmp_packet->ttl = TTL; 917 icmp_packet->ttl = TTL;
934 918
935 send_skb_packet(skb, batman_if, dstaddr); 919 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
936 ret = NET_RX_SUCCESS; 920 ret = NET_RX_SUCCESS;
937 goto out; 921 goto out;
938 922
939unlock: 923unlock:
940 rcu_read_unlock(); 924 rcu_read_unlock();
941 spin_unlock_bh(&bat_priv->orig_hash_lock);
942out: 925out:
943 if (neigh_node) 926 if (neigh_node)
944 neigh_node_free_ref(neigh_node); 927 neigh_node_free_ref(neigh_node);
@@ -953,8 +936,6 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
953 struct orig_node *orig_node = NULL; 936 struct orig_node *orig_node = NULL;
954 struct neigh_node *neigh_node = NULL; 937 struct neigh_node *neigh_node = NULL;
955 struct icmp_packet *icmp_packet; 938 struct icmp_packet *icmp_packet;
956 struct batman_if *batman_if;
957 uint8_t dstaddr[ETH_ALEN];
958 int ret = NET_RX_DROP; 939 int ret = NET_RX_DROP;
959 940
960 icmp_packet = (struct icmp_packet *)skb->data; 941 icmp_packet = (struct icmp_packet *)skb->data;
@@ -971,7 +952,6 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
971 goto out; 952 goto out;
972 953
973 /* get routing information */ 954 /* get routing information */
974 spin_lock_bh(&bat_priv->orig_hash_lock);
975 rcu_read_lock(); 955 rcu_read_lock();
976 orig_node = orig_hash_find(bat_priv, icmp_packet->orig); 956 orig_node = orig_hash_find(bat_priv, icmp_packet->orig);
977 957
@@ -990,12 +970,6 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
990 970
991 rcu_read_unlock(); 971 rcu_read_unlock();
992 972
993 /* don't lock while sending the packets ... we therefore
994 * copy the required data before sending */
995 batman_if = orig_node->router->if_incoming;
996 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
997 spin_unlock_bh(&bat_priv->orig_hash_lock);
998
999 /* create a copy of the skb, if needed, to modify it. */ 973 /* create a copy of the skb, if needed, to modify it. */
1000 if (skb_cow(skb, sizeof(struct ethhdr)) < 0) 974 if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
1001 goto out; 975 goto out;
@@ -1008,13 +982,12 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv,
1008 icmp_packet->msg_type = TTL_EXCEEDED; 982 icmp_packet->msg_type = TTL_EXCEEDED;
1009 icmp_packet->ttl = TTL; 983 icmp_packet->ttl = TTL;
1010 984
1011 send_skb_packet(skb, batman_if, dstaddr); 985 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1012 ret = NET_RX_SUCCESS; 986 ret = NET_RX_SUCCESS;
1013 goto out; 987 goto out;
1014 988
1015unlock: 989unlock:
1016 rcu_read_unlock(); 990 rcu_read_unlock();
1017 spin_unlock_bh(&bat_priv->orig_hash_lock);
1018out: 991out:
1019 if (neigh_node) 992 if (neigh_node)
1020 neigh_node_free_ref(neigh_node); 993 neigh_node_free_ref(neigh_node);
@@ -1031,9 +1004,7 @@ int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if)
1031 struct ethhdr *ethhdr; 1004 struct ethhdr *ethhdr;
1032 struct orig_node *orig_node = NULL; 1005 struct orig_node *orig_node = NULL;
1033 struct neigh_node *neigh_node = NULL; 1006 struct neigh_node *neigh_node = NULL;
1034 struct batman_if *batman_if;
1035 int hdr_size = sizeof(struct icmp_packet); 1007 int hdr_size = sizeof(struct icmp_packet);
1036 uint8_t dstaddr[ETH_ALEN];
1037 int ret = NET_RX_DROP; 1008 int ret = NET_RX_DROP;
1038 1009
1039 /** 1010 /**
@@ -1079,7 +1050,6 @@ int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if)
1079 return recv_icmp_ttl_exceeded(bat_priv, skb); 1050 return recv_icmp_ttl_exceeded(bat_priv, skb);
1080 1051
1081 /* get routing information */ 1052 /* get routing information */
1082 spin_lock_bh(&bat_priv->orig_hash_lock);
1083 rcu_read_lock(); 1053 rcu_read_lock();
1084 orig_node = orig_hash_find(bat_priv, icmp_packet->dst); 1054 orig_node = orig_hash_find(bat_priv, icmp_packet->dst);
1085 1055
@@ -1098,12 +1068,6 @@ int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if)
1098 1068
1099 rcu_read_unlock(); 1069 rcu_read_unlock();
1100 1070
1101 /* don't lock while sending the packets ... we therefore
1102 * copy the required data before sending */
1103 batman_if = orig_node->router->if_incoming;
1104 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
1105 spin_unlock_bh(&bat_priv->orig_hash_lock);
1106
1107 /* create a copy of the skb, if needed, to modify it. */ 1071 /* create a copy of the skb, if needed, to modify it. */
1108 if (skb_cow(skb, sizeof(struct ethhdr)) < 0) 1072 if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
1109 goto out; 1073 goto out;
@@ -1114,13 +1078,12 @@ int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if)
1114 icmp_packet->ttl--; 1078 icmp_packet->ttl--;
1115 1079
1116 /* route it */ 1080 /* route it */
1117 send_skb_packet(skb, batman_if, dstaddr); 1081 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1118 ret = NET_RX_SUCCESS; 1082 ret = NET_RX_SUCCESS;
1119 goto out; 1083 goto out;
1120 1084
1121unlock: 1085unlock:
1122 rcu_read_unlock(); 1086 rcu_read_unlock();
1123 spin_unlock_bh(&bat_priv->orig_hash_lock);
1124out: 1087out:
1125 if (neigh_node) 1088 if (neigh_node)
1126 neigh_node_free_ref(neigh_node); 1089 neigh_node_free_ref(neigh_node);
@@ -1306,8 +1269,6 @@ int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if,
1306 struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); 1269 struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface);
1307 struct orig_node *orig_node = NULL; 1270 struct orig_node *orig_node = NULL;
1308 struct neigh_node *neigh_node = NULL; 1271 struct neigh_node *neigh_node = NULL;
1309 struct batman_if *batman_if;
1310 uint8_t dstaddr[ETH_ALEN];
1311 struct unicast_packet *unicast_packet; 1272 struct unicast_packet *unicast_packet;
1312 struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb); 1273 struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb);
1313 int ret = NET_RX_DROP; 1274 int ret = NET_RX_DROP;
@@ -1324,7 +1285,6 @@ int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if,
1324 } 1285 }
1325 1286
1326 /* get routing information */ 1287 /* get routing information */
1327 spin_lock_bh(&bat_priv->orig_hash_lock);
1328 rcu_read_lock(); 1288 rcu_read_lock();
1329 orig_node = orig_hash_find(bat_priv, unicast_packet->dest); 1289 orig_node = orig_hash_find(bat_priv, unicast_packet->dest);
1330 1290
@@ -1336,16 +1296,8 @@ int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if,
1336 /* find_router() increases neigh_nodes refcount if found. */ 1296 /* find_router() increases neigh_nodes refcount if found. */
1337 neigh_node = find_router(bat_priv, orig_node, recv_if); 1297 neigh_node = find_router(bat_priv, orig_node, recv_if);
1338 1298
1339 if (!neigh_node) { 1299 if (!neigh_node)
1340 spin_unlock_bh(&bat_priv->orig_hash_lock);
1341 goto out; 1300 goto out;
1342 }
1343
1344 /* don't lock while sending the packets ... we therefore
1345 * copy the required data before sending */
1346 batman_if = neigh_node->if_incoming;
1347 memcpy(dstaddr, neigh_node->addr, ETH_ALEN);
1348 spin_unlock_bh(&bat_priv->orig_hash_lock);
1349 1301
1350 /* create a copy of the skb, if needed, to modify it. */ 1302 /* create a copy of the skb, if needed, to modify it. */
1351 if (skb_cow(skb, sizeof(struct ethhdr)) < 0) 1303 if (skb_cow(skb, sizeof(struct ethhdr)) < 0)
@@ -1355,12 +1307,14 @@ int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if,
1355 1307
1356 if (unicast_packet->packet_type == BAT_UNICAST && 1308 if (unicast_packet->packet_type == BAT_UNICAST &&
1357 atomic_read(&bat_priv->fragmentation) && 1309 atomic_read(&bat_priv->fragmentation) &&
1358 skb->len > batman_if->net_dev->mtu) 1310 skb->len > neigh_node->if_incoming->net_dev->mtu) {
1359 return frag_send_skb(skb, bat_priv, batman_if, 1311 ret = frag_send_skb(skb, bat_priv,
1360 dstaddr); 1312 neigh_node->if_incoming, neigh_node->addr);
1313 goto out;
1314 }
1361 1315
1362 if (unicast_packet->packet_type == BAT_UNICAST_FRAG && 1316 if (unicast_packet->packet_type == BAT_UNICAST_FRAG &&
1363 frag_can_reassemble(skb, batman_if->net_dev->mtu)) { 1317 frag_can_reassemble(skb, neigh_node->if_incoming->net_dev->mtu)) {
1364 1318
1365 ret = frag_reassemble_skb(skb, bat_priv, &new_skb); 1319 ret = frag_reassemble_skb(skb, bat_priv, &new_skb);
1366 1320
@@ -1381,13 +1335,12 @@ int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if,
1381 unicast_packet->ttl--; 1335 unicast_packet->ttl--;
1382 1336
1383 /* route it */ 1337 /* route it */
1384 send_skb_packet(skb, batman_if, dstaddr); 1338 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
1385 ret = NET_RX_SUCCESS; 1339 ret = NET_RX_SUCCESS;
1386 goto out; 1340 goto out;
1387 1341
1388unlock: 1342unlock:
1389 rcu_read_unlock(); 1343 rcu_read_unlock();
1390 spin_unlock_bh(&bat_priv->orig_hash_lock);
1391out: 1344out:
1392 if (neigh_node) 1345 if (neigh_node)
1393 neigh_node_free_ref(neigh_node); 1346 neigh_node_free_ref(neigh_node);
@@ -1486,7 +1439,6 @@ int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if)
1486 if (bcast_packet->ttl < 2) 1439 if (bcast_packet->ttl < 2)
1487 goto out; 1440 goto out;
1488 1441
1489 spin_lock_bh(&bat_priv->orig_hash_lock);
1490 rcu_read_lock(); 1442 rcu_read_lock();
1491 orig_node = orig_hash_find(bat_priv, bcast_packet->orig); 1443 orig_node = orig_hash_find(bat_priv, bcast_packet->orig);
1492 1444
@@ -1515,7 +1467,6 @@ int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if)
1515 orig_node->last_bcast_seqno = ntohl(bcast_packet->seqno); 1467 orig_node->last_bcast_seqno = ntohl(bcast_packet->seqno);
1516 1468
1517 spin_unlock_bh(&orig_node->bcast_seqno_lock); 1469 spin_unlock_bh(&orig_node->bcast_seqno_lock);
1518 spin_unlock_bh(&bat_priv->orig_hash_lock);
1519 1470
1520 /* rebroadcast packet */ 1471 /* rebroadcast packet */
1521 add_bcast_packet_to_list(bat_priv, skb); 1472 add_bcast_packet_to_list(bat_priv, skb);
@@ -1527,11 +1478,9 @@ int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if)
1527 1478
1528rcu_unlock: 1479rcu_unlock:
1529 rcu_read_unlock(); 1480 rcu_read_unlock();
1530 spin_unlock_bh(&bat_priv->orig_hash_lock);
1531 goto out; 1481 goto out;
1532spin_unlock: 1482spin_unlock:
1533 spin_unlock_bh(&orig_node->bcast_seqno_lock); 1483 spin_unlock_bh(&orig_node->bcast_seqno_lock);
1534 spin_unlock_bh(&bat_priv->orig_hash_lock);
1535out: 1484out:
1536 if (orig_node) 1485 if (orig_node)
1537 orig_node_free_ref(orig_node); 1486 orig_node_free_ref(orig_node);
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 1be76feddee1..a9bf1860819d 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -159,7 +159,6 @@ struct bat_priv {
159 struct hashtable_t *hna_local_hash; 159 struct hashtable_t *hna_local_hash;
160 struct hashtable_t *hna_global_hash; 160 struct hashtable_t *hna_global_hash;
161 struct hashtable_t *vis_hash; 161 struct hashtable_t *vis_hash;
162 spinlock_t orig_hash_lock; /* protects orig_hash */
163 spinlock_t forw_bat_list_lock; /* protects forw_bat_list */ 162 spinlock_t forw_bat_list_lock; /* protects forw_bat_list */
164 spinlock_t forw_bcast_list_lock; /* protects */ 163 spinlock_t forw_bcast_list_lock; /* protects */
165 spinlock_t hna_lhash_lock; /* protects hna_local_hash */ 164 spinlock_t hna_lhash_lock; /* protects hna_local_hash */
diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c
index 2ab819841231..b4114385dc56 100644
--- a/net/batman-adv/unicast.c
+++ b/net/batman-adv/unicast.c
@@ -179,10 +179,9 @@ int frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
179 179
180 *new_skb = NULL; 180 *new_skb = NULL;
181 181
182 spin_lock_bh(&bat_priv->orig_hash_lock);
183 orig_node = orig_hash_find(bat_priv, unicast_packet->orig); 182 orig_node = orig_hash_find(bat_priv, unicast_packet->orig);
184 if (!orig_node) 183 if (!orig_node)
185 goto unlock; 184 goto out;
186 185
187 orig_node->last_frag_packet = jiffies; 186 orig_node->last_frag_packet = jiffies;
188 187
@@ -207,8 +206,6 @@ int frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv,
207 if (*new_skb) 206 if (*new_skb)
208 ret = NET_RX_SUCCESS; 207 ret = NET_RX_SUCCESS;
209 208
210unlock:
211 spin_unlock_bh(&bat_priv->orig_hash_lock);
212out: 209out:
213 if (orig_node) 210 if (orig_node)
214 orig_node_free_ref(orig_node); 211 orig_node_free_ref(orig_node);
@@ -281,14 +278,10 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv)
281 struct ethhdr *ethhdr = (struct ethhdr *)skb->data; 278 struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
282 struct unicast_packet *unicast_packet; 279 struct unicast_packet *unicast_packet;
283 struct orig_node *orig_node; 280 struct orig_node *orig_node;
284 struct batman_if *batman_if;
285 struct neigh_node *neigh_node; 281 struct neigh_node *neigh_node;
286 int data_len = skb->len; 282 int data_len = skb->len;
287 uint8_t dstaddr[6];
288 int ret = 1; 283 int ret = 1;
289 284
290 spin_lock_bh(&bat_priv->orig_hash_lock);
291
292 /* get routing information */ 285 /* get routing information */
293 if (is_multicast_ether_addr(ethhdr->h_dest)) { 286 if (is_multicast_ether_addr(ethhdr->h_dest)) {
294 orig_node = (struct orig_node *)gw_get_selected(bat_priv); 287 orig_node = (struct orig_node *)gw_get_selected(bat_priv);
@@ -300,23 +293,21 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv)
300 orig_node = transtable_search(bat_priv, ethhdr->h_dest); 293 orig_node = transtable_search(bat_priv, ethhdr->h_dest);
301 294
302find_router: 295find_router:
303 /* find_router() increases neigh_nodes refcount if found. */ 296 /**
297 * find_router():
298 * - if orig_node is NULL it returns NULL
299 * - increases neigh_nodes refcount if found.
300 */
304 neigh_node = find_router(bat_priv, orig_node, NULL); 301 neigh_node = find_router(bat_priv, orig_node, NULL);
305 302
306 if (!neigh_node) 303 if (!neigh_node)
307 goto unlock; 304 goto out;
308 305
309 if (neigh_node->if_incoming->if_status != IF_ACTIVE) 306 if (neigh_node->if_incoming->if_status != IF_ACTIVE)
310 goto unlock; 307 goto out;
311 308
312 if (my_skb_head_push(skb, sizeof(struct unicast_packet)) < 0) 309 if (my_skb_head_push(skb, sizeof(struct unicast_packet)) < 0)
313 goto unlock; 310 goto out;
314
315 /* don't lock while sending the packets ... we therefore
316 * copy the required data before sending */
317 batman_if = neigh_node->if_incoming;
318 memcpy(dstaddr, neigh_node->addr, ETH_ALEN);
319 spin_unlock_bh(&bat_priv->orig_hash_lock);
320 311
321 unicast_packet = (struct unicast_packet *)skb->data; 312 unicast_packet = (struct unicast_packet *)skb->data;
322 313
@@ -330,19 +321,18 @@ find_router:
330 321
331 if (atomic_read(&bat_priv->fragmentation) && 322 if (atomic_read(&bat_priv->fragmentation) &&
332 data_len + sizeof(struct unicast_packet) > 323 data_len + sizeof(struct unicast_packet) >
333 batman_if->net_dev->mtu) { 324 neigh_node->if_incoming->net_dev->mtu) {
334 /* send frag skb decreases ttl */ 325 /* send frag skb decreases ttl */
335 unicast_packet->ttl++; 326 unicast_packet->ttl++;
336 ret = frag_send_skb(skb, bat_priv, batman_if, dstaddr); 327 ret = frag_send_skb(skb, bat_priv,
328 neigh_node->if_incoming, neigh_node->addr);
337 goto out; 329 goto out;
338 } 330 }
339 331
340 send_skb_packet(skb, batman_if, dstaddr); 332 send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr);
341 ret = 0; 333 ret = 0;
342 goto out; 334 goto out;
343 335
344unlock:
345 spin_unlock_bh(&bat_priv->orig_hash_lock);
346out: 336out:
347 if (neigh_node) 337 if (neigh_node)
348 neigh_node_free_ref(neigh_node); 338 neigh_node_free_ref(neigh_node);
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c
index 89722425dcb2..e8911cbb8699 100644
--- a/net/batman-adv/vis.c
+++ b/net/batman-adv/vis.c
@@ -614,7 +614,6 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
614 info->first_seen = jiffies; 614 info->first_seen = jiffies;
615 packet->vis_type = atomic_read(&bat_priv->vis_mode); 615 packet->vis_type = atomic_read(&bat_priv->vis_mode);
616 616
617 spin_lock_bh(&bat_priv->orig_hash_lock);
618 memcpy(packet->target_orig, broadcast_addr, ETH_ALEN); 617 memcpy(packet->target_orig, broadcast_addr, ETH_ALEN);
619 packet->ttl = TTL; 618 packet->ttl = TTL;
620 packet->seqno = htonl(ntohl(packet->seqno) + 1); 619 packet->seqno = htonl(ntohl(packet->seqno) + 1);
@@ -624,10 +623,8 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
624 if (packet->vis_type == VIS_TYPE_CLIENT_UPDATE) { 623 if (packet->vis_type == VIS_TYPE_CLIENT_UPDATE) {
625 best_tq = find_best_vis_server(bat_priv, info); 624 best_tq = find_best_vis_server(bat_priv, info);
626 625
627 if (best_tq < 0) { 626 if (best_tq < 0)
628 spin_unlock_bh(&bat_priv->orig_hash_lock);
629 return -1; 627 return -1;
630 }
631 } 628 }
632 629
633 for (i = 0; i < hash->size; i++) { 630 for (i = 0; i < hash->size; i++) {
@@ -659,17 +656,12 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
659 entry->quality = neigh_node->tq_avg; 656 entry->quality = neigh_node->tq_avg;
660 packet->entries++; 657 packet->entries++;
661 658
662 if (vis_packet_full(info)) { 659 if (vis_packet_full(info))
663 rcu_read_unlock(); 660 goto unlock;
664 spin_unlock_bh(&bat_priv->orig_hash_lock);
665 return 0;
666 }
667 } 661 }
668 rcu_read_unlock(); 662 rcu_read_unlock();
669 } 663 }
670 664
671 spin_unlock_bh(&bat_priv->orig_hash_lock);
672
673 hash = bat_priv->hna_local_hash; 665 hash = bat_priv->hna_local_hash;
674 666
675 spin_lock_bh(&bat_priv->hna_lhash_lock); 667 spin_lock_bh(&bat_priv->hna_lhash_lock);
@@ -694,6 +686,10 @@ static int generate_vis_packet(struct bat_priv *bat_priv)
694 686
695 spin_unlock_bh(&bat_priv->hna_lhash_lock); 687 spin_unlock_bh(&bat_priv->hna_lhash_lock);
696 return 0; 688 return 0;
689
690unlock:
691 rcu_read_unlock();
692 return 0;
697} 693}
698 694
699/* free old vis packets. Must be called with this vis_hash_lock 695/* free old vis packets. Must be called with this vis_hash_lock
@@ -739,7 +735,6 @@ static void broadcast_vis_packet(struct bat_priv *bat_priv,
739 int i; 735 int i;
740 736
741 737
742 spin_lock_bh(&bat_priv->orig_hash_lock);
743 packet = (struct vis_packet *)info->skb_packet->data; 738 packet = (struct vis_packet *)info->skb_packet->data;
744 739
745 /* send to all routers in range. */ 740 /* send to all routers in range. */
@@ -762,18 +757,14 @@ static void broadcast_vis_packet(struct bat_priv *bat_priv,
762 memcpy(packet->target_orig, orig_node->orig, ETH_ALEN); 757 memcpy(packet->target_orig, orig_node->orig, ETH_ALEN);
763 batman_if = orig_node->router->if_incoming; 758 batman_if = orig_node->router->if_incoming;
764 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); 759 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
765 spin_unlock_bh(&bat_priv->orig_hash_lock);
766 760
767 skb = skb_clone(info->skb_packet, GFP_ATOMIC); 761 skb = skb_clone(info->skb_packet, GFP_ATOMIC);
768 if (skb) 762 if (skb)
769 send_skb_packet(skb, batman_if, dstaddr); 763 send_skb_packet(skb, batman_if, dstaddr);
770 764
771 spin_lock_bh(&bat_priv->orig_hash_lock);
772 } 765 }
773 rcu_read_unlock(); 766 rcu_read_unlock();
774 } 767 }
775
776 spin_unlock_bh(&bat_priv->orig_hash_lock);
777} 768}
778 769
779static void unicast_vis_packet(struct bat_priv *bat_priv, 770static void unicast_vis_packet(struct bat_priv *bat_priv,
@@ -783,12 +774,9 @@ static void unicast_vis_packet(struct bat_priv *bat_priv,
783 struct neigh_node *neigh_node = NULL; 774 struct neigh_node *neigh_node = NULL;
784 struct sk_buff *skb; 775 struct sk_buff *skb;
785 struct vis_packet *packet; 776 struct vis_packet *packet;
786 struct batman_if *batman_if;
787 uint8_t dstaddr[ETH_ALEN];
788 777
789 packet = (struct vis_packet *)info->skb_packet->data; 778 packet = (struct vis_packet *)info->skb_packet->data;
790 779
791 spin_lock_bh(&bat_priv->orig_hash_lock);
792 rcu_read_lock(); 780 rcu_read_lock();
793 orig_node = orig_hash_find(bat_priv, packet->target_orig); 781 orig_node = orig_hash_find(bat_priv, packet->target_orig);
794 782
@@ -807,21 +795,15 @@ static void unicast_vis_packet(struct bat_priv *bat_priv,
807 795
808 rcu_read_unlock(); 796 rcu_read_unlock();
809 797
810 /* don't lock while sending the packets ... we therefore
811 * copy the required data before sending */
812 batman_if = orig_node->router->if_incoming;
813 memcpy(dstaddr, orig_node->router->addr, ETH_ALEN);
814 spin_unlock_bh(&bat_priv->orig_hash_lock);
815
816 skb = skb_clone(info->skb_packet, GFP_ATOMIC); 798 skb = skb_clone(info->skb_packet, GFP_ATOMIC);
817 if (skb) 799 if (skb)
818 send_skb_packet(skb, batman_if, dstaddr); 800 send_skb_packet(skb, neigh_node->if_incoming,
801 neigh_node->addr);
819 802
820 goto out; 803 goto out;
821 804
822unlock: 805unlock:
823 rcu_read_unlock(); 806 rcu_read_unlock();
824 spin_unlock_bh(&bat_priv->orig_hash_lock);
825out: 807out:
826 if (neigh_node) 808 if (neigh_node)
827 neigh_node_free_ref(neigh_node); 809 neigh_node_free_ref(neigh_node);