|
@@ -511,6 +511,7 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
|
|
struct batadv_priv *bat_priv = netdev_priv(soft_iface);
|
|
struct batadv_priv *bat_priv = netdev_priv(soft_iface);
|
|
struct batadv_tt_local_entry *tt_local;
|
|
struct batadv_tt_local_entry *tt_local;
|
|
struct batadv_tt_global_entry *tt_global = NULL;
|
|
struct batadv_tt_global_entry *tt_global = NULL;
|
|
|
|
+ struct batadv_softif_vlan *vlan;
|
|
struct net_device *in_dev = NULL;
|
|
struct net_device *in_dev = NULL;
|
|
struct hlist_head *head;
|
|
struct hlist_head *head;
|
|
struct batadv_tt_orig_list_entry *orig_entry;
|
|
struct batadv_tt_orig_list_entry *orig_entry;
|
|
@@ -572,6 +573,9 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
|
|
if (!tt_local)
|
|
if (!tt_local)
|
|
goto out;
|
|
goto out;
|
|
|
|
|
|
|
|
+ /* increase the refcounter of the related vlan */
|
|
|
|
+ vlan = batadv_softif_vlan_get(bat_priv, vid);
|
|
|
|
+
|
|
batadv_dbg(BATADV_DBG_TT, bat_priv,
|
|
batadv_dbg(BATADV_DBG_TT, bat_priv,
|
|
"Creating new local tt entry: %pM (vid: %d, ttvn: %d)\n",
|
|
"Creating new local tt entry: %pM (vid: %d, ttvn: %d)\n",
|
|
addr, BATADV_PRINT_VID(vid),
|
|
addr, BATADV_PRINT_VID(vid),
|
|
@@ -604,6 +608,7 @@ bool batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
|
|
if (unlikely(hash_added != 0)) {
|
|
if (unlikely(hash_added != 0)) {
|
|
/* remove the reference for the hash */
|
|
/* remove the reference for the hash */
|
|
batadv_tt_local_entry_free_ref(tt_local);
|
|
batadv_tt_local_entry_free_ref(tt_local);
|
|
|
|
+ batadv_softif_vlan_free_ref(vlan);
|
|
goto out;
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1009,6 +1014,7 @@ uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
|
|
{
|
|
{
|
|
struct batadv_tt_local_entry *tt_local_entry;
|
|
struct batadv_tt_local_entry *tt_local_entry;
|
|
uint16_t flags, curr_flags = BATADV_NO_FLAGS;
|
|
uint16_t flags, curr_flags = BATADV_NO_FLAGS;
|
|
|
|
+ struct batadv_softif_vlan *vlan;
|
|
|
|
|
|
tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
|
|
tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
|
|
if (!tt_local_entry)
|
|
if (!tt_local_entry)
|
|
@@ -1039,6 +1045,11 @@ uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
|
|
hlist_del_rcu(&tt_local_entry->common.hash_entry);
|
|
hlist_del_rcu(&tt_local_entry->common.hash_entry);
|
|
batadv_tt_local_entry_free_ref(tt_local_entry);
|
|
batadv_tt_local_entry_free_ref(tt_local_entry);
|
|
|
|
|
|
|
|
+ /* decrease the reference held for this vlan */
|
|
|
|
+ vlan = batadv_softif_vlan_get(bat_priv, vid);
|
|
|
|
+ batadv_softif_vlan_free_ref(vlan);
|
|
|
|
+ batadv_softif_vlan_free_ref(vlan);
|
|
|
|
+
|
|
out:
|
|
out:
|
|
if (tt_local_entry)
|
|
if (tt_local_entry)
|
|
batadv_tt_local_entry_free_ref(tt_local_entry);
|
|
batadv_tt_local_entry_free_ref(tt_local_entry);
|
|
@@ -1111,6 +1122,7 @@ static void batadv_tt_local_table_free(struct batadv_priv *bat_priv)
|
|
spinlock_t *list_lock; /* protects write access to the hash lists */
|
|
spinlock_t *list_lock; /* protects write access to the hash lists */
|
|
struct batadv_tt_common_entry *tt_common_entry;
|
|
struct batadv_tt_common_entry *tt_common_entry;
|
|
struct batadv_tt_local_entry *tt_local;
|
|
struct batadv_tt_local_entry *tt_local;
|
|
|
|
+ struct batadv_softif_vlan *vlan;
|
|
struct hlist_node *node_tmp;
|
|
struct hlist_node *node_tmp;
|
|
struct hlist_head *head;
|
|
struct hlist_head *head;
|
|
uint32_t i;
|
|
uint32_t i;
|
|
@@ -1131,6 +1143,13 @@ static void batadv_tt_local_table_free(struct batadv_priv *bat_priv)
|
|
tt_local = container_of(tt_common_entry,
|
|
tt_local = container_of(tt_common_entry,
|
|
struct batadv_tt_local_entry,
|
|
struct batadv_tt_local_entry,
|
|
common);
|
|
common);
|
|
|
|
+
|
|
|
|
+ /* decrease the reference held for this vlan */
|
|
|
|
+ vlan = batadv_softif_vlan_get(bat_priv,
|
|
|
|
+ tt_common_entry->vid);
|
|
|
|
+ batadv_softif_vlan_free_ref(vlan);
|
|
|
|
+ batadv_softif_vlan_free_ref(vlan);
|
|
|
|
+
|
|
batadv_tt_local_entry_free_ref(tt_local);
|
|
batadv_tt_local_entry_free_ref(tt_local);
|
|
}
|
|
}
|
|
spin_unlock_bh(list_lock);
|
|
spin_unlock_bh(list_lock);
|
|
@@ -3139,6 +3158,7 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
|
|
struct batadv_hashtable *hash = bat_priv->tt.local_hash;
|
|
struct batadv_hashtable *hash = bat_priv->tt.local_hash;
|
|
struct batadv_tt_common_entry *tt_common;
|
|
struct batadv_tt_common_entry *tt_common;
|
|
struct batadv_tt_local_entry *tt_local;
|
|
struct batadv_tt_local_entry *tt_local;
|
|
|
|
+ struct batadv_softif_vlan *vlan;
|
|
struct hlist_node *node_tmp;
|
|
struct hlist_node *node_tmp;
|
|
struct hlist_head *head;
|
|
struct hlist_head *head;
|
|
spinlock_t *list_lock; /* protects write access to the hash lists */
|
|
spinlock_t *list_lock; /* protects write access to the hash lists */
|
|
@@ -3167,6 +3187,12 @@ static void batadv_tt_local_purge_pending_clients(struct batadv_priv *bat_priv)
|
|
tt_local = container_of(tt_common,
|
|
tt_local = container_of(tt_common,
|
|
struct batadv_tt_local_entry,
|
|
struct batadv_tt_local_entry,
|
|
common);
|
|
common);
|
|
|
|
+
|
|
|
|
+ /* decrease the reference held for this vlan */
|
|
|
|
+ vlan = batadv_softif_vlan_get(bat_priv, tt_common->vid);
|
|
|
|
+ batadv_softif_vlan_free_ref(vlan);
|
|
|
|
+ batadv_softif_vlan_free_ref(vlan);
|
|
|
|
+
|
|
batadv_tt_local_entry_free_ref(tt_local);
|
|
batadv_tt_local_entry_free_ref(tt_local);
|
|
}
|
|
}
|
|
spin_unlock_bh(list_lock);
|
|
spin_unlock_bh(list_lock);
|