diff options
author | Linus Lüssing <linus.luessing@web.de> | 2011-03-14 18:43:37 -0400 |
---|---|---|
committer | Sven Eckelmann <sven@narfation.org> | 2011-04-17 15:11:01 -0400 |
commit | e1a5382f978b67b5cc36eec65e6046730ce07714 (patch) | |
tree | f7ca07cde3a49858d0cfa33e0189a659a1fcc95d /net/batman-adv/send.c | |
parent | 57f0c07c4d0da8bcc23e21c330fe9c7c5cf776b5 (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.c | 19 |
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 | ||