From ece1a2e7e86078c8379937b546e32cb7f25fcb6c Mon Sep 17 00:00:00 2001 From: Javier Cardona Date: Mon, 29 Aug 2011 13:23:04 -0700 Subject: mac80211: Remove mesh paths when an interface is removed When an interface is removed, the mesh paths associated with it should also be removed. This fixes a bug we observed when reloading a device driver module without reloading mac80211s. Signed-off-by: Javier Cardona Signed-off-by: John W. Linville --- net/mac80211/mesh_pathtbl.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'net/mac80211/mesh_pathtbl.c') diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 2218eaf48bcb..d07279911a0c 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -821,7 +821,7 @@ void mesh_path_flush_by_nexthop(struct sta_info *sta) rcu_read_unlock(); } -void mesh_path_flush(struct ieee80211_sub_if_data *sdata) +static void mesh_path_flush(struct ieee80211_sub_if_data *sdata) { struct mesh_table *tbl; struct mesh_path *mpath; @@ -850,6 +850,44 @@ static void mesh_path_node_reclaim(struct rcu_head *rp) kfree(node); } +static void mpp_path_flush(struct ieee80211_sub_if_data *sdata) +{ + struct mesh_table *tbl; + struct mesh_path *mpath; + struct mpath_node *node; + struct hlist_node *p; + int i; + + read_lock_bh(&pathtbl_resize_lock); + tbl = rcu_dereference_protected(mpp_paths, + lockdep_is_held(pathtbl_resize_lock)); + for_each_mesh_entry(tbl, p, node, i) { + mpath = node->mpath; + if (mpath->sdata != sdata) + continue; + spin_lock_bh(&tbl->hashwlock[i]); + spin_lock_bh(&mpath->state_lock); + call_rcu(&node->rcu, mesh_path_node_reclaim); + atomic_dec(&tbl->entries); + spin_unlock_bh(&tbl->hashwlock[i]); + } + read_unlock_bh(&pathtbl_resize_lock); +} + +/** + * mesh_path_flush_by_iface - Deletes all mesh paths associated with a given iface + * + * This function deletes both mesh paths as well as mesh portal paths. + * + * @sdata - interface data to match + * + */ +void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata) +{ + mesh_path_flush(sdata); + mpp_path_flush(sdata); +} + /** * mesh_path_del - delete a mesh path from the table * -- cgit