aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv
diff options
context:
space:
mode:
authorMarek Lindner <lindner_marek@yahoo.de>2011-02-18 07:28:11 -0500
committerMarek Lindner <lindner_marek@yahoo.de>2011-03-05 06:52:03 -0500
commit1605d0d60b66b9461cfcff86f8cfc80964f23430 (patch)
treed35ad73ad4ac6cc157383d611101d3dd66115745 /net/batman-adv
parent7b36e8eef989fc59535b4f1d3fc0f83afaf419d4 (diff)
batman-adv: increase refcount in create_neighbor to be consistent
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Diffstat (limited to 'net/batman-adv')
-rw-r--r--net/batman-adv/originator.c4
-rw-r--r--net/batman-adv/routing.c63
2 files changed, 30 insertions, 37 deletions
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index a70debebfc5b..69e27a243fd0 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -94,7 +94,9 @@ struct neigh_node *create_neighbor(struct orig_node *orig_node,
94 memcpy(neigh_node->addr, neigh, ETH_ALEN); 94 memcpy(neigh_node->addr, neigh, ETH_ALEN);
95 neigh_node->orig_node = orig_neigh_node; 95 neigh_node->orig_node = orig_neigh_node;
96 neigh_node->if_incoming = if_incoming; 96 neigh_node->if_incoming = if_incoming;
97 atomic_set(&neigh_node->refcount, 1); 97
98 /* extra reference for return */
99 atomic_set(&neigh_node->refcount, 2);
98 100
99 spin_lock_bh(&orig_node->neigh_list_lock); 101 spin_lock_bh(&orig_node->neigh_list_lock);
100 hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list); 102 hlist_add_head_rcu(&neigh_node->list, &orig_node->neigh_list);
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
index 9863c03a2137..c4b7ae9380ef 100644
--- a/net/batman-adv/routing.c
+++ b/net/batman-adv/routing.c
@@ -150,7 +150,7 @@ static int is_bidirectional_neigh(struct orig_node *orig_node,
150 struct batman_if *if_incoming) 150 struct batman_if *if_incoming)
151{ 151{
152 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 152 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
153 struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; 153 struct neigh_node *neigh_node = NULL, *tmp_neigh_node;
154 struct hlist_node *node; 154 struct hlist_node *node;
155 unsigned char total_count; 155 unsigned char total_count;
156 uint8_t orig_eq_count, neigh_rq_count, tq_own; 156 uint8_t orig_eq_count, neigh_rq_count, tq_own;
@@ -161,27 +161,27 @@ static int is_bidirectional_neigh(struct orig_node *orig_node,
161 hlist_for_each_entry_rcu(tmp_neigh_node, node, 161 hlist_for_each_entry_rcu(tmp_neigh_node, node,
162 &orig_node->neigh_list, list) { 162 &orig_node->neigh_list, list) {
163 163
164 if (compare_eth(tmp_neigh_node->addr, 164 if (!compare_eth(tmp_neigh_node->addr,
165 orig_neigh_node->orig) && 165 orig_neigh_node->orig))
166 (tmp_neigh_node->if_incoming == if_incoming)) 166 continue;
167 neigh_node = tmp_neigh_node; 167
168 if (tmp_neigh_node->if_incoming != if_incoming)
169 continue;
170
171 if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
172 continue;
173
174 neigh_node = tmp_neigh_node;
168 } 175 }
176 rcu_read_unlock();
169 177
170 if (!neigh_node) 178 if (!neigh_node)
171 neigh_node = create_neighbor(orig_node, 179 neigh_node = create_neighbor(orig_node,
172 orig_neigh_node, 180 orig_neigh_node,
173 orig_neigh_node->orig, 181 orig_neigh_node->orig,
174 if_incoming); 182 if_incoming);
175 /* create_neighbor failed, return 0 */
176 if (!neigh_node) 183 if (!neigh_node)
177 goto unlock; 184 goto out;
178
179 if (!atomic_inc_not_zero(&neigh_node->refcount)) {
180 neigh_node = NULL;
181 goto unlock;
182 }
183
184 rcu_read_unlock();
185 185
186 neigh_node->last_valid = jiffies; 186 neigh_node->last_valid = jiffies;
187 } else { 187 } else {
@@ -190,27 +190,27 @@ static int is_bidirectional_neigh(struct orig_node *orig_node,
190 hlist_for_each_entry_rcu(tmp_neigh_node, node, 190 hlist_for_each_entry_rcu(tmp_neigh_node, node,
191 &orig_neigh_node->neigh_list, list) { 191 &orig_neigh_node->neigh_list, list) {
192 192
193 if (compare_eth(tmp_neigh_node->addr, 193 if (!compare_eth(tmp_neigh_node->addr,
194 orig_neigh_node->orig) && 194 orig_neigh_node->orig))
195 (tmp_neigh_node->if_incoming == if_incoming)) 195 continue;
196 neigh_node = tmp_neigh_node; 196
197 if (tmp_neigh_node->if_incoming != if_incoming)
198 continue;
199
200 if (!atomic_inc_not_zero(&tmp_neigh_node->refcount))
201 continue;
202
203 neigh_node = tmp_neigh_node;
197 } 204 }
205 rcu_read_unlock();
198 206
199 if (!neigh_node) 207 if (!neigh_node)
200 neigh_node = create_neighbor(orig_neigh_node, 208 neigh_node = create_neighbor(orig_neigh_node,
201 orig_neigh_node, 209 orig_neigh_node,
202 orig_neigh_node->orig, 210 orig_neigh_node->orig,
203 if_incoming); 211 if_incoming);
204 /* create_neighbor failed, return 0 */
205 if (!neigh_node) 212 if (!neigh_node)
206 goto unlock; 213 goto out;
207
208 if (!atomic_inc_not_zero(&neigh_node->refcount)) {
209 neigh_node = NULL;
210 goto unlock;
211 }
212
213 rcu_read_unlock();
214 } 214 }
215 215
216 orig_node->last_valid = jiffies; 216 orig_node->last_valid = jiffies;
@@ -265,10 +265,6 @@ static int is_bidirectional_neigh(struct orig_node *orig_node,
265 if (batman_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT) 265 if (batman_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT)
266 ret = 1; 266 ret = 1;
267 267
268 goto out;
269
270unlock:
271 rcu_read_unlock();
272out: 268out:
273 if (neigh_node) 269 if (neigh_node)
274 neigh_node_free_ref(neigh_node); 270 neigh_node_free_ref(neigh_node);
@@ -423,11 +419,6 @@ static void update_orig(struct bat_priv *bat_priv,
423 orig_node_free_ref(orig_tmp); 419 orig_node_free_ref(orig_tmp);
424 if (!neigh_node) 420 if (!neigh_node)
425 goto unlock; 421 goto unlock;
426
427 if (!atomic_inc_not_zero(&neigh_node->refcount)) {
428 neigh_node = NULL;
429 goto unlock;
430 }
431 } else 422 } else
432 bat_dbg(DBG_BATMAN, bat_priv, 423 bat_dbg(DBG_BATMAN, bat_priv,
433 "Updating existing last-hop neighbor of originator\n"); 424 "Updating existing last-hop neighbor of originator\n");