Commit b5dcbad2 authored by Sven Eckelmann's avatar Sven Eckelmann Committed by Simon Wunderlich

batman-adv: Fix consistency of update route messages

The debug messages of _batadv_update_route were printed before the actual
route change is done. At this point it is not really known which
curr_router will be replaced. Thus the messages could print the wrong
operation.

Printing the debug messages after the operation was done avoids this
problem.
Signed-off-by: default avatarSven Eckelmann <sven@narfation.org>
Signed-off-by: default avatarMarek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: default avatarSimon Wunderlich <sw@simonwunderlich.de>
parent 4d7de48c
......@@ -74,11 +74,23 @@ static void _batadv_update_route(struct batadv_priv *bat_priv,
if (!orig_ifinfo)
return;
rcu_read_lock();
curr_router = rcu_dereference(orig_ifinfo->router);
if (curr_router && !kref_get_unless_zero(&curr_router->refcount))
curr_router = NULL;
rcu_read_unlock();
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);
/* increase refcount of new best neighbor */
if (neigh_node)
kref_get(&neigh_node->refcount);
rcu_assign_pointer(orig_ifinfo->router, neigh_node);
spin_unlock_bh(&orig_node->neigh_list_lock);
batadv_orig_ifinfo_put(orig_ifinfo);
/* route deleted */
if ((curr_router) && (!neigh_node)) {
......@@ -100,27 +112,6 @@ static void _batadv_update_route(struct batadv_priv *bat_priv,
curr_router->addr);
}
if (curr_router)
batadv_neigh_node_put(curr_router);
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);
/* increase refcount of new best neighbor */
if (neigh_node)
kref_get(&neigh_node->refcount);
rcu_assign_pointer(orig_ifinfo->router, neigh_node);
spin_unlock_bh(&orig_node->neigh_list_lock);
batadv_orig_ifinfo_put(orig_ifinfo);
/* decrease refcount of previous best neighbor */
if (curr_router)
batadv_neigh_node_put(curr_router);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment