|
|
@@ -706,6 +706,47 @@ struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv,
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * batadv_purge_neigh_ifinfo - purge obsolete ifinfo entries from neighbor
|
|
|
+ * @bat_priv: the bat priv with all the soft interface information
|
|
|
+ * @neigh: orig node which is to be checked
|
|
|
+ */
|
|
|
+static void
|
|
|
+batadv_purge_neigh_ifinfo(struct batadv_priv *bat_priv,
|
|
|
+ struct batadv_neigh_node *neigh)
|
|
|
+{
|
|
|
+ struct batadv_neigh_ifinfo *neigh_ifinfo;
|
|
|
+ struct batadv_hard_iface *if_outgoing;
|
|
|
+ struct hlist_node *node_tmp;
|
|
|
+
|
|
|
+ spin_lock_bh(&neigh->ifinfo_lock);
|
|
|
+
|
|
|
+ /* for all ifinfo objects for this neighinator */
|
|
|
+ hlist_for_each_entry_safe(neigh_ifinfo, node_tmp,
|
|
|
+ &neigh->ifinfo_list, list) {
|
|
|
+ if_outgoing = neigh_ifinfo->if_outgoing;
|
|
|
+
|
|
|
+ /* always keep the default interface */
|
|
|
+ if (if_outgoing == BATADV_IF_DEFAULT)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ /* don't purge if the interface is not (going) down */
|
|
|
+ if ((if_outgoing->if_status != BATADV_IF_INACTIVE) &&
|
|
|
+ (if_outgoing->if_status != BATADV_IF_NOT_IN_USE) &&
|
|
|
+ (if_outgoing->if_status != BATADV_IF_TO_BE_REMOVED))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
|
|
|
+ "neighbor/ifinfo purge: neighbor %pM, iface: %s\n",
|
|
|
+ neigh->addr, if_outgoing->net_dev->name);
|
|
|
+
|
|
|
+ hlist_del_rcu(&neigh_ifinfo->list);
|
|
|
+ batadv_neigh_ifinfo_free_ref(neigh_ifinfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ spin_unlock_bh(&neigh->ifinfo_lock);
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* batadv_purge_orig_ifinfo - purge obsolete ifinfo entries from originator
|
|
|
* @bat_priv: the bat priv with all the soft interface information
|
|
|
@@ -805,6 +846,11 @@ batadv_purge_orig_neighbors(struct batadv_priv *bat_priv,
|
|
|
|
|
|
hlist_del_rcu(&neigh_node->list);
|
|
|
batadv_neigh_node_free_ref(neigh_node);
|
|
|
+ } else {
|
|
|
+ /* only necessary if not the whole neighbor is to be
|
|
|
+ * deleted, but some interface has been removed.
|
|
|
+ */
|
|
|
+ batadv_purge_neigh_ifinfo(bat_priv, neigh_node);
|
|
|
}
|
|
|
}
|
|
|
|