|
@@ -469,6 +469,29 @@ static int batadv_check_unicast_packet(struct batadv_priv *bat_priv,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * batadv_last_bonding_get - Get last_bonding_candidate of orig_node
|
|
|
+ * @orig_node: originator node whose last bonding candidate should be retrieved
|
|
|
+ *
|
|
|
+ * Return: last bonding candidate of router or NULL if not found
|
|
|
+ *
|
|
|
+ * The object is returned with refcounter increased by 1.
|
|
|
+ */
|
|
|
+static struct batadv_orig_ifinfo *
|
|
|
+batadv_last_bonding_get(struct batadv_orig_node *orig_node)
|
|
|
+{
|
|
|
+ struct batadv_orig_ifinfo *last_bonding_candidate;
|
|
|
+
|
|
|
+ spin_lock_bh(&orig_node->neigh_list_lock);
|
|
|
+ last_bonding_candidate = orig_node->last_bonding_candidate;
|
|
|
+
|
|
|
+ if (last_bonding_candidate)
|
|
|
+ kref_get(&last_bonding_candidate->refcount);
|
|
|
+ spin_unlock_bh(&orig_node->neigh_list_lock);
|
|
|
+
|
|
|
+ return last_bonding_candidate;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* batadv_last_bonding_replace - Replace last_bonding_candidate of orig_node
|
|
|
* @orig_node: originator node whose bonding candidates should be replaced
|
|
@@ -539,7 +562,7 @@ batadv_find_router(struct batadv_priv *bat_priv,
|
|
|
* router - obviously there are no other candidates.
|
|
|
*/
|
|
|
rcu_read_lock();
|
|
|
- last_candidate = orig_node->last_bonding_candidate;
|
|
|
+ last_candidate = batadv_last_bonding_get(orig_node);
|
|
|
if (last_candidate)
|
|
|
last_cand_router = rcu_dereference(last_candidate->router);
|
|
|
|
|
@@ -631,6 +654,9 @@ next:
|
|
|
batadv_orig_ifinfo_put(next_candidate);
|
|
|
}
|
|
|
|
|
|
+ if (last_candidate)
|
|
|
+ batadv_orig_ifinfo_put(last_candidate);
|
|
|
+
|
|
|
return router;
|
|
|
}
|
|
|
|