summaryrefslogtreecommitdiffstats
path: root/kernel/net/batman-adv/routing.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/net/batman-adv/routing.c')
-rw-r--r--kernel/net/batman-adv/routing.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/kernel/net/batman-adv/routing.c b/kernel/net/batman-adv/routing.c
index 3207667e6..d8a2f33e6 100644
--- a/kernel/net/batman-adv/routing.c
+++ b/kernel/net/batman-adv/routing.c
@@ -104,6 +104,15 @@ static void _batadv_update_route(struct batadv_priv *bat_priv,
neigh_node = NULL;
spin_lock_bh(&orig_node->neigh_list_lock);
+ /* curr_router used earlier may not be the current orig_ifinfo->router
+ * anymore because it was dereferenced outside of the neigh_list_lock
+ * protected region. After the new best neighbor has replace the current
+ * best neighbor the reference counter needs to decrease. Consequently,
+ * the code needs to ensure the curr_router variable contains a pointer
+ * to the replaced best neighbor.
+ */
+ curr_router = rcu_dereference_protected(orig_ifinfo->router, true);
+
rcu_assign_pointer(orig_ifinfo->router, neigh_node);
spin_unlock_bh(&orig_node->neigh_list_lock);
batadv_orig_ifinfo_free_ref(orig_ifinfo);