aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv
diff options
context:
space:
mode:
authorMarek Lindner <lindner_marek@yahoo.de>2011-01-19 15:01:42 -0500
committerMarek Lindner <lindner_marek@yahoo.de>2011-03-05 06:50:00 -0500
commit2ae2daf6c3f23364862a7d4f2ca79eab041b701b (patch)
tree8b4c15f4c7733d9d1d3aa58fd80b6f998b9eca2c /net/batman-adv
parent16b1aba849eeb45d51a5de731cf103143439ffe1 (diff)
batman-adv: protect ogm counter arrays with spinlock
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Diffstat (limited to 'net/batman-adv')
-rw-r--r--net/batman-adv/originator.c11
-rw-r--r--net/batman-adv/routing.c27
-rw-r--r--net/batman-adv/types.h1
3 files changed, 33 insertions, 6 deletions
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index fcdb0b7fe586..71dfc24e961b 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -207,6 +207,7 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr)
207 return NULL; 207 return NULL;
208 208
209 INIT_HLIST_HEAD(&orig_node->neigh_list); 209 INIT_HLIST_HEAD(&orig_node->neigh_list);
210 spin_lock_init(&orig_node->ogm_cnt_lock);
210 spin_lock_init(&orig_node->neigh_list_lock); 211 spin_lock_init(&orig_node->neigh_list_lock);
211 kref_init(&orig_node->refcount); 212 kref_init(&orig_node->refcount);
212 213
@@ -517,7 +518,7 @@ int orig_hash_add_if(struct batman_if *batman_if, int max_if_num)
517 struct hlist_head *head; 518 struct hlist_head *head;
518 struct element_t *bucket; 519 struct element_t *bucket;
519 struct orig_node *orig_node; 520 struct orig_node *orig_node;
520 int i; 521 int i, ret;
521 522
522 /* resize all orig nodes because orig_node->bcast_own(_sum) depend on 523 /* resize all orig nodes because orig_node->bcast_own(_sum) depend on
523 * if_num */ 524 * if_num */
@@ -530,7 +531,11 @@ int orig_hash_add_if(struct batman_if *batman_if, int max_if_num)
530 hlist_for_each_entry_rcu(bucket, walk, head, hlist) { 531 hlist_for_each_entry_rcu(bucket, walk, head, hlist) {
531 orig_node = bucket->data; 532 orig_node = bucket->data;
532 533
533 if (orig_node_add_if(orig_node, max_if_num) == -1) 534 spin_lock_bh(&orig_node->ogm_cnt_lock);
535 ret = orig_node_add_if(orig_node, max_if_num);
536 spin_unlock_bh(&orig_node->ogm_cnt_lock);
537
538 if (ret == -1)
534 goto err; 539 goto err;
535 } 540 }
536 rcu_read_unlock(); 541 rcu_read_unlock();
@@ -619,8 +624,10 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num)
619 hlist_for_each_entry_rcu(bucket, walk, head, hlist) { 624 hlist_for_each_entry_rcu(bucket, walk, head, hlist) {
620 orig_node = bucket->data; 625 orig_node = bucket->data;
621 626
627 spin_lock_bh(&orig_node->ogm_cnt_lock);
622 ret = orig_node_del_if(orig_node, max_if_num, 628 ret = orig_node_del_if(orig_node, max_if_num,
623 batman_if->if_num); 629 batman_if->if_num);
630 spin_unlock_bh(&orig_node->ogm_cnt_lock);
624 631
625 if (ret == -1) 632 if (ret == -1)
626 goto err; 633 goto err;
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 1c31a0e9f90a..7627ebe50c4b 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -55,12 +55,14 @@ void slide_own_bcast_window(struct batman_if *batman_if)
55 rcu_read_lock(); 55 rcu_read_lock();
56 hlist_for_each_entry_rcu(bucket, walk, head, hlist) { 56 hlist_for_each_entry_rcu(bucket, walk, head, hlist) {
57 orig_node = bucket->data; 57 orig_node = bucket->data;
58 spin_lock_bh(&orig_node->ogm_cnt_lock);
58 word_index = batman_if->if_num * NUM_WORDS; 59 word_index = batman_if->if_num * NUM_WORDS;
59 word = &(orig_node->bcast_own[word_index]); 60 word = &(orig_node->bcast_own[word_index]);
60 61
61 bit_get_packet(bat_priv, word, 1, 0); 62 bit_get_packet(bat_priv, word, 1, 0);
62 orig_node->bcast_own_sum[batman_if->if_num] = 63 orig_node->bcast_own_sum[batman_if->if_num] =
63 bit_packet_count(word); 64 bit_packet_count(word);
65 spin_unlock_bh(&orig_node->ogm_cnt_lock);
64 } 66 }
65 rcu_read_unlock(); 67 rcu_read_unlock();
66 } 68 }
@@ -278,8 +280,10 @@ static void update_orig(struct bat_priv *bat_priv,
278 char is_duplicate) 280 char is_duplicate)
279{ 281{
280 struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; 282 struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL;
283 struct orig_node *orig_node_tmp;
281 struct hlist_node *node; 284 struct hlist_node *node;
282 int tmp_hna_buff_len; 285 int tmp_hna_buff_len;
286 uint8_t bcast_own_sum_orig, bcast_own_sum_neigh;
283 287
284 bat_dbg(DBG_BATMAN, bat_priv, "update_originator(): " 288 bat_dbg(DBG_BATMAN, bat_priv, "update_originator(): "
285 "Searching and updating originator entry of received packet\n"); 289 "Searching and updating originator entry of received packet\n");
@@ -351,10 +355,22 @@ static void update_orig(struct bat_priv *bat_priv,
351 /* if the TQ is the same and the link not more symetric we 355 /* if the TQ is the same and the link not more symetric we
352 * won't consider it either */ 356 * won't consider it either */
353 if ((orig_node->router) && 357 if ((orig_node->router) &&
354 ((neigh_node->tq_avg == orig_node->router->tq_avg) && 358 (neigh_node->tq_avg == orig_node->router->tq_avg)) {
355 (orig_node->router->orig_node->bcast_own_sum[if_incoming->if_num] 359 orig_node_tmp = orig_node->router->orig_node;
356 >= neigh_node->orig_node->bcast_own_sum[if_incoming->if_num]))) 360 spin_lock_bh(&orig_node_tmp->ogm_cnt_lock);
357 goto update_hna; 361 bcast_own_sum_orig =
362 orig_node_tmp->bcast_own_sum[if_incoming->if_num];
363 spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock);
364
365 orig_node_tmp = neigh_node->orig_node;
366 spin_lock_bh(&orig_node_tmp->ogm_cnt_lock);
367 bcast_own_sum_neigh =
368 orig_node_tmp->bcast_own_sum[if_incoming->if_num];
369 spin_unlock_bh(&orig_node_tmp->ogm_cnt_lock);
370
371 if (bcast_own_sum_orig >= bcast_own_sum_neigh)
372 goto update_hna;
373 }
358 374
359 update_routes(bat_priv, orig_node, neigh_node, 375 update_routes(bat_priv, orig_node, neigh_node,
360 hna_buff, tmp_hna_buff_len); 376 hna_buff, tmp_hna_buff_len);
@@ -705,10 +721,13 @@ void receive_bat_packet(struct ethhdr *ethhdr,
705 batman_packet->orig) && 721 batman_packet->orig) &&
706 (batman_packet->seqno - if_incoming_seqno + 2 == 0)) { 722 (batman_packet->seqno - if_incoming_seqno + 2 == 0)) {
707 offset = if_incoming->if_num * NUM_WORDS; 723 offset = if_incoming->if_num * NUM_WORDS;
724
725 spin_lock_bh(&orig_neigh_node->ogm_cnt_lock);
708 word = &(orig_neigh_node->bcast_own[offset]); 726 word = &(orig_neigh_node->bcast_own[offset]);
709 bit_mark(word, 0); 727 bit_mark(word, 0);
710 orig_neigh_node->bcast_own_sum[if_incoming->if_num] = 728 orig_neigh_node->bcast_own_sum[if_incoming->if_num] =
711 bit_packet_count(word); 729 bit_packet_count(word);
730 spin_unlock_bh(&orig_neigh_node->ogm_cnt_lock);
712 } 731 }
713 732
714 bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: " 733 bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: "
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index ca4d42d05912..ff70afc376da 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -89,6 +89,7 @@ struct orig_node {
89 struct kref refcount; 89 struct kref refcount;
90 struct bat_priv *bat_priv; 90 struct bat_priv *bat_priv;
91 unsigned long last_frag_packet; 91 unsigned long last_frag_packet;
92 spinlock_t ogm_cnt_lock; /* protects ogm counter */
92 struct { 93 struct {
93 uint8_t candidates; 94 uint8_t candidates;
94 struct neigh_node *selected; 95 struct neigh_node *selected;