Commit 4cc955de authored by Henning Rogge's avatar Henning Rogge Committed by Johannes Berg

mac80211: Unify mesh and mpp path removal function

mpp_path_del() and mesh_path_del() are mostly the same function.
Move common code into a new static function.
Acked-by: default avatarBob Copeland <me@bobcopeland.com>
Signed-off-by: default avatarHenning Rogge <henning.rogge@fkie.fraunhofer.de>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent ab1c7906
...@@ -55,16 +55,21 @@ int mpp_paths_generation; ...@@ -55,16 +55,21 @@ int mpp_paths_generation;
static DEFINE_RWLOCK(pathtbl_resize_lock); static DEFINE_RWLOCK(pathtbl_resize_lock);
static inline struct mesh_table *resize_dereference_paths(
struct mesh_table __rcu *table)
{
return rcu_dereference_protected(table,
lockdep_is_held(&pathtbl_resize_lock));
}
static inline struct mesh_table *resize_dereference_mesh_paths(void) static inline struct mesh_table *resize_dereference_mesh_paths(void)
{ {
return rcu_dereference_protected(mesh_paths, return resize_dereference_paths(mesh_paths);
lockdep_is_held(&pathtbl_resize_lock));
} }
static inline struct mesh_table *resize_dereference_mpp_paths(void) static inline struct mesh_table *resize_dereference_mpp_paths(void)
{ {
return rcu_dereference_protected(mpp_paths, return resize_dereference_paths(mpp_paths);
lockdep_is_held(&pathtbl_resize_lock));
} }
/* /*
...@@ -898,14 +903,17 @@ void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata) ...@@ -898,14 +903,17 @@ void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata)
} }
/** /**
* mesh_path_del - delete a mesh path from the table * table_path_del - delete a path from the mesh or mpp table
* *
* @addr: dst address (ETH_ALEN length) * @tbl: mesh or mpp path table
* @sdata: local subif * @sdata: local subif
* @addr: dst address (ETH_ALEN length)
* *
* Returns: 0 if successful * Returns: 0 if successful
*/ */
int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr) static int table_path_del(struct mesh_table __rcu *rcu_tbl,
struct ieee80211_sub_if_data *sdata,
const u8 *addr)
{ {
struct mesh_table *tbl; struct mesh_table *tbl;
struct mesh_path *mpath; struct mesh_path *mpath;
...@@ -914,11 +922,7 @@ int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr) ...@@ -914,11 +922,7 @@ int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr)
int hash_idx; int hash_idx;
int err = 0; int err = 0;
/* flush relevant mpp entries first */ tbl = resize_dereference_paths(rcu_tbl);
mpp_flush_by_proxy(sdata, addr);
read_lock_bh(&pathtbl_resize_lock);
tbl = resize_dereference_mesh_paths();
hash_idx = mesh_table_hash(addr, sdata, tbl); hash_idx = mesh_table_hash(addr, sdata, tbl);
bucket = &tbl->hash_buckets[hash_idx]; bucket = &tbl->hash_buckets[hash_idx];
...@@ -934,9 +938,30 @@ int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr) ...@@ -934,9 +938,30 @@ int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr)
err = -ENXIO; err = -ENXIO;
enddel: enddel:
mesh_paths_generation++;
spin_unlock(&tbl->hashwlock[hash_idx]); spin_unlock(&tbl->hashwlock[hash_idx]);
return err;
}
/**
* mesh_path_del - delete a mesh path from the table
*
* @addr: dst address (ETH_ALEN length)
* @sdata: local subif
*
* Returns: 0 if successful
*/
int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr)
{
int err = 0;
/* flush relevant mpp entries first */
mpp_flush_by_proxy(sdata, addr);
read_lock_bh(&pathtbl_resize_lock);
err = table_path_del(mesh_paths, sdata, addr);
mesh_paths_generation++;
read_unlock_bh(&pathtbl_resize_lock); read_unlock_bh(&pathtbl_resize_lock);
return err; return err;
} }
...@@ -950,33 +975,13 @@ int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr) ...@@ -950,33 +975,13 @@ int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr)
*/ */
static int mpp_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr) static int mpp_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr)
{ {
struct mesh_table *tbl;
struct mesh_path *mpath;
struct mpath_node *node;
struct hlist_head *bucket;
int hash_idx;
int err = 0; int err = 0;
read_lock_bh(&pathtbl_resize_lock); read_lock_bh(&pathtbl_resize_lock);
tbl = resize_dereference_mpp_paths(); err = table_path_del(mpp_paths, sdata, addr);
hash_idx = mesh_table_hash(addr, sdata, tbl); mpp_paths_generation++;
bucket = &tbl->hash_buckets[hash_idx];
spin_lock(&tbl->hashwlock[hash_idx]);
hlist_for_each_entry(node, bucket, list) {
mpath = node->mpath;
if (mpath->sdata == sdata &&
ether_addr_equal(addr, mpath->dst)) {
__mesh_path_del(tbl, node);
goto enddel;
}
}
err = -ENXIO;
enddel:
mesh_paths_generation++;
spin_unlock(&tbl->hashwlock[hash_idx]);
read_unlock_bh(&pathtbl_resize_lock); read_unlock_bh(&pathtbl_resize_lock);
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment