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: Bob Copeland <me@bobcopeland.com> Signed-off-by: Henning Rogge <henning.rogge@fkie.fraunhofer.de> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Родитель
ab1c7906b0
Коммит
4cc955de7c
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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)
|
||||||
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)
|
||||||
|
|
||||||
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 @@ enddel:
|
||||||
*/
|
*/
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче