neigh_node = NULL;
spin_lock_bh(&orig_node->neigh_list_lock);
+ /* curr_router used earlier may not be the current orig_node->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_node->router, true);
+
rcu_assign_pointer(orig_node->router, neigh_node);
spin_unlock_bh(&orig_node->neigh_list_lock);
/* packet needs to be linearized to access the TT changes */
if (skb_linearize(skb) < 0)
goto out;
+ /* skb_linearize() possibly changed skb->data */
+ tt_query = (struct tt_query_packet *)skb->data;
if (is_my_mac(tt_query->dst))
handle_tt_response(bat_priv, tt_query);