+static struct softif_neigh *softif_neigh_get_selected(struct bat_priv *bat_priv)
+{
+ struct softif_neigh *neigh;
+
+ rcu_read_lock();
+ neigh = rcu_dereference(bat_priv->softif_neigh);
+
+ if (neigh && !atomic_inc_not_zero(&neigh->refcount))
+ neigh = NULL;
+
+ rcu_read_unlock();
+ return neigh;
+}
+
+static void softif_neigh_select(struct bat_priv *bat_priv,
+ struct softif_neigh *new_neigh)
+{
+ struct softif_neigh *curr_neigh;
+
+ spin_lock_bh(&bat_priv->softif_neigh_lock);
+
+ if (new_neigh && !atomic_inc_not_zero(&new_neigh->refcount))
+ new_neigh = NULL;
+
+ curr_neigh = bat_priv->softif_neigh;
+ rcu_assign_pointer(bat_priv->softif_neigh, new_neigh);
+
+ if (curr_neigh)
+ softif_neigh_free_ref(curr_neigh);
+
+ spin_unlock_bh(&bat_priv->softif_neigh_lock);
+}
+
+static void softif_neigh_deselect(struct bat_priv *bat_priv)
+{
+ softif_neigh_select(bat_priv, NULL);
+}
+