aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJavier Cardona <javier@cozybit.com>2011-08-29 16:23:09 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-09-13 15:42:33 -0400
commit239289e446d4e86ae94b1ca57e358b106cc4bee6 (patch)
treed0fe60443519912a7af5730e7e09dd0e89271721 /net/mac80211
parentcd72e817480bd3a1d2cdf03b65a1f3920c1c88a0 (diff)
mac80211: Consolidate mesh path duplicated functions
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/mesh_pathtbl.c70
1 files changed, 28 insertions, 42 deletions
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 7797f55eec46..a66a2cab8d34 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -48,10 +48,10 @@ static struct mesh_table __rcu *mpp_paths; /* Store paths for MPP&MAP */
48int mesh_paths_generation; 48int mesh_paths_generation;
49 49
50/* This lock will have the grow table function as writer and add / delete nodes 50/* This lock will have the grow table function as writer and add / delete nodes
51 * as readers. When reading the table (i.e. doing lookups) we are well protected 51 * as readers. RCU provides sufficient protection only when reading the table
52 * by RCU. We need to take this lock when modying the number of buckets 52 * (i.e. doing lookups). Adding or adding or removing nodes requires we take
53 * on one of the path tables but we don't need to if adding or removing mpaths 53 * the read lock or we risk operating on an old table. The write lock is only
54 * from hash buckets. 54 * needed when modifying the number of buckets a table.
55 */ 55 */
56static DEFINE_RWLOCK(pathtbl_resize_lock); 56static DEFINE_RWLOCK(pathtbl_resize_lock);
57 57
@@ -335,25 +335,14 @@ static void mesh_path_move_to_queue(struct mesh_path *gate_mpath,
335} 335}
336 336
337 337
338/** 338static struct mesh_path *path_lookup(struct mesh_table *tbl, u8 *dst,
339 * mesh_path_lookup - look up a path in the mesh path table 339 struct ieee80211_sub_if_data *sdata)
340 * @dst: hardware address (ETH_ALEN length) of destination
341 * @sdata: local subif
342 *
343 * Returns: pointer to the mesh path structure, or NULL if not found
344 *
345 * Locking: must be called within a read rcu section.
346 */
347struct mesh_path *mesh_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata)
348{ 340{
349 struct mesh_path *mpath; 341 struct mesh_path *mpath;
350 struct hlist_node *n; 342 struct hlist_node *n;
351 struct hlist_head *bucket; 343 struct hlist_head *bucket;
352 struct mesh_table *tbl;
353 struct mpath_node *node; 344 struct mpath_node *node;
354 345
355 tbl = rcu_dereference(mesh_paths);
356
357 bucket = &tbl->hash_buckets[mesh_table_hash(dst, sdata, tbl)]; 346 bucket = &tbl->hash_buckets[mesh_table_hash(dst, sdata, tbl)];
358 hlist_for_each_entry_rcu(node, n, bucket, list) { 347 hlist_for_each_entry_rcu(node, n, bucket, list) {
359 mpath = node->mpath; 348 mpath = node->mpath;
@@ -370,30 +359,23 @@ struct mesh_path *mesh_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata)
370 return NULL; 359 return NULL;
371} 360}
372 361
373struct mesh_path *mpp_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata) 362/**
363 * mesh_path_lookup - look up a path in the mesh path table
364 * @dst: hardware address (ETH_ALEN length) of destination
365 * @sdata: local subif
366 *
367 * Returns: pointer to the mesh path structure, or NULL if not found
368 *
369 * Locking: must be called within a read rcu section.
370 */
371struct mesh_path *mesh_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata)
374{ 372{
375 struct mesh_path *mpath; 373 return path_lookup(rcu_dereference(mesh_paths), dst, sdata);
376 struct hlist_node *n; 374}
377 struct hlist_head *bucket;
378 struct mesh_table *tbl;
379 struct mpath_node *node;
380
381 tbl = rcu_dereference(mpp_paths);
382 375
383 bucket = &tbl->hash_buckets[mesh_table_hash(dst, sdata, tbl)]; 376struct mesh_path *mpp_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata)
384 hlist_for_each_entry_rcu(node, n, bucket, list) { 377{
385 mpath = node->mpath; 378 return path_lookup(rcu_dereference(mpp_paths), dst, sdata);
386 if (mpath->sdata == sdata &&
387 memcmp(dst, mpath->dst, ETH_ALEN) == 0) {
388 if (MPATH_EXPIRED(mpath)) {
389 spin_lock_bh(&mpath->state_lock);
390 mpath->flags &= ~MESH_PATH_ACTIVE;
391 spin_unlock_bh(&mpath->state_lock);
392 }
393 return mpath;
394 }
395 }
396 return NULL;
397} 379}
398 380
399 381
@@ -836,7 +818,8 @@ void mesh_path_flush_by_nexthop(struct sta_info *sta)
836 int i; 818 int i;
837 819
838 rcu_read_lock(); 820 rcu_read_lock();
839 tbl = rcu_dereference(mesh_paths); 821 read_lock_bh(&pathtbl_resize_lock);
822 tbl = resize_dereference_mesh_paths();
840 for_each_mesh_entry(tbl, p, node, i) { 823 for_each_mesh_entry(tbl, p, node, i) {
841 mpath = node->mpath; 824 mpath = node->mpath;
842 if (rcu_dereference(mpath->next_hop) == sta) { 825 if (rcu_dereference(mpath->next_hop) == sta) {
@@ -845,6 +828,7 @@ void mesh_path_flush_by_nexthop(struct sta_info *sta)
845 spin_unlock_bh(&tbl->hashwlock[i]); 828 spin_unlock_bh(&tbl->hashwlock[i]);
846 } 829 }
847 } 830 }
831 read_unlock_bh(&pathtbl_resize_lock);
848 rcu_read_unlock(); 832 rcu_read_unlock();
849} 833}
850 834
@@ -880,10 +864,12 @@ void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata)
880 struct mesh_table *tbl; 864 struct mesh_table *tbl;
881 865
882 rcu_read_lock(); 866 rcu_read_lock();
883 tbl = rcu_dereference(mesh_paths); 867 read_lock_bh(&pathtbl_resize_lock);
868 tbl = resize_dereference_mesh_paths();
884 table_flush_by_iface(tbl, sdata); 869 table_flush_by_iface(tbl, sdata);
885 tbl = rcu_dereference(mpp_paths); 870 tbl = resize_dereference_mpp_paths();
886 table_flush_by_iface(tbl, sdata); 871 table_flush_by_iface(tbl, sdata);
872 read_unlock_bh(&pathtbl_resize_lock);
887 rcu_read_unlock(); 873 rcu_read_unlock();
888} 874}
889 875