aboutsummaryrefslogtreecommitdiffstats
path: root/net/batman-adv/send.c
diff options
context:
space:
mode:
authorLinus Lüssing <linus.luessing@web.de>2011-03-14 18:43:37 -0400
committerSven Eckelmann <sven@narfation.org>2011-04-17 15:11:01 -0400
commite1a5382f978b67b5cc36eec65e6046730ce07714 (patch)
treef7ca07cde3a49858d0cfa33e0189a659a1fcc95d /net/batman-adv/send.c
parent57f0c07c4d0da8bcc23e21c330fe9c7c5cf776b5 (diff)
batman-adv: Make orig_node->router an rcu protected pointer
The rcu protected macros rcu_dereference() and rcu_assign_pointer() for the orig_node->router need to be used, as well as spin/rcu locking. Otherwise we might end up using a router pointer pointing to already freed memory. Therefore this commit introduces the safe getter method orig_node_get_router(). Signed-off-by: Linus Lüssing <linus.luessing@web.de> Signed-off-by: Marek Lindner <lindner_marek@yahoo.de> Signed-off-by: Sven Eckelmann <sven@narfation.org>
Diffstat (limited to 'net/batman-adv/send.c')
-rw-r--r--net/batman-adv/send.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index d49e54d932af..e78670c3c4b7 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -308,6 +308,7 @@ void schedule_forward_packet(struct orig_node *orig_node,
308 struct hard_iface *if_incoming) 308 struct hard_iface *if_incoming)
309{ 309{
310 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); 310 struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface);
311 struct neigh_node *router;
311 unsigned char in_tq, in_ttl, tq_avg = 0; 312 unsigned char in_tq, in_ttl, tq_avg = 0;
312 unsigned long send_time; 313 unsigned long send_time;
313 314
@@ -316,6 +317,8 @@ void schedule_forward_packet(struct orig_node *orig_node,
316 return; 317 return;
317 } 318 }
318 319
320 router = orig_node_get_router(orig_node);
321
319 in_tq = batman_packet->tq; 322 in_tq = batman_packet->tq;
320 in_ttl = batman_packet->ttl; 323 in_ttl = batman_packet->ttl;
321 324
@@ -324,20 +327,22 @@ void schedule_forward_packet(struct orig_node *orig_node,
324 327
325 /* rebroadcast tq of our best ranking neighbor to ensure the rebroadcast 328 /* rebroadcast tq of our best ranking neighbor to ensure the rebroadcast
326 * of our best tq value */ 329 * of our best tq value */
327 if ((orig_node->router) && (orig_node->router->tq_avg != 0)) { 330 if (router && router->tq_avg != 0) {
328 331
329 /* rebroadcast ogm of best ranking neighbor as is */ 332 /* rebroadcast ogm of best ranking neighbor as is */
330 if (!compare_eth(orig_node->router->addr, ethhdr->h_source)) { 333 if (!compare_eth(router->addr, ethhdr->h_source)) {
331 batman_packet->tq = orig_node->router->tq_avg; 334 batman_packet->tq = router->tq_avg;
332 335
333 if (orig_node->router->last_ttl) 336 if (router->last_ttl)
334 batman_packet->ttl = orig_node->router->last_ttl 337 batman_packet->ttl = router->last_ttl - 1;
335 - 1;
336 } 338 }
337 339
338 tq_avg = orig_node->router->tq_avg; 340 tq_avg = router->tq_avg;
339 } 341 }
340 342
343 if (router)
344 neigh_node_free_ref(router);
345
341 /* apply hop penalty */ 346 /* apply hop penalty */
342 batman_packet->tq = hop_penalty(batman_packet->tq, bat_priv); 347 batman_packet->tq = hop_penalty(batman_packet->tq, bat_priv);
343 348