diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-08-07 10:17:38 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-08-14 09:13:43 -0400 |
commit | f5ea9120be2e5d5c846243416cfdce01d02f5836 (patch) | |
tree | cade27e47a90dde79a523598b96a2ebb50770d2f /net/mac80211 | |
parent | f401a6f7ede753e56b84025e7d2db0d5ef560ce6 (diff) |
nl80211: add generation number to all dumps
In order for userspace to be able to figure out whether
it obtained a consistent snapshot of data or not when
using netlink dumps, we need to have a generation number
in each dump message that indicates whether the list has
changed or not -- its value is arbitrary.
This patch adds such a number to all dumps, this needs
some mac80211 involvement to keep track of a generation
number to start with when adding/removing mesh paths or
stations.
The wiphy and netdev lists can be fully handled within
cfg80211, of course, but generation numbers need to be
stored there as well.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/cfg.c | 4 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 1 | ||||
-rw-r--r-- | net/mac80211/mesh.h | 2 | ||||
-rw-r--r-- | net/mac80211/mesh_pathtbl.c | 5 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 2 |
5 files changed, 14 insertions, 0 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 4bbf5007799b..5608f6c68413 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -323,6 +323,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
323 | { | 323 | { |
324 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 324 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
325 | 325 | ||
326 | sinfo->generation = sdata->local->sta_generation; | ||
327 | |||
326 | sinfo->filled = STATION_INFO_INACTIVE_TIME | | 328 | sinfo->filled = STATION_INFO_INACTIVE_TIME | |
327 | STATION_INFO_RX_BYTES | | 329 | STATION_INFO_RX_BYTES | |
328 | STATION_INFO_TX_BYTES | | 330 | STATION_INFO_TX_BYTES | |
@@ -909,6 +911,8 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop, | |||
909 | else | 911 | else |
910 | memset(next_hop, 0, ETH_ALEN); | 912 | memset(next_hop, 0, ETH_ALEN); |
911 | 913 | ||
914 | pinfo->generation = mesh_paths_generation; | ||
915 | |||
912 | pinfo->filled = MPATH_INFO_FRAME_QLEN | | 916 | pinfo->filled = MPATH_INFO_FRAME_QLEN | |
913 | MPATH_INFO_DSN | | 917 | MPATH_INFO_DSN | |
914 | MPATH_INFO_METRIC | | 918 | MPATH_INFO_METRIC | |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 989591787aee..99433222bc5c 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -678,6 +678,7 @@ struct ieee80211_local { | |||
678 | struct list_head sta_list; | 678 | struct list_head sta_list; |
679 | struct sta_info *sta_hash[STA_HASH_SIZE]; | 679 | struct sta_info *sta_hash[STA_HASH_SIZE]; |
680 | struct timer_list sta_cleanup; | 680 | struct timer_list sta_cleanup; |
681 | int sta_generation; | ||
681 | 682 | ||
682 | struct sk_buff_head pending[IEEE80211_MAX_QUEUES]; | 683 | struct sk_buff_head pending[IEEE80211_MAX_QUEUES]; |
683 | struct tasklet_struct tx_pending_tasklet; | 684 | struct tasklet_struct tx_pending_tasklet; |
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 2a2ed182cb7e..ce538814b9bd 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h | |||
@@ -265,6 +265,8 @@ void mesh_path_discard_frame(struct sk_buff *skb, | |||
265 | void mesh_path_quiesce(struct ieee80211_sub_if_data *sdata); | 265 | void mesh_path_quiesce(struct ieee80211_sub_if_data *sdata); |
266 | void mesh_path_restart(struct ieee80211_sub_if_data *sdata); | 266 | void mesh_path_restart(struct ieee80211_sub_if_data *sdata); |
267 | 267 | ||
268 | extern int mesh_paths_generation; | ||
269 | |||
268 | #ifdef CONFIG_MAC80211_MESH | 270 | #ifdef CONFIG_MAC80211_MESH |
269 | extern int mesh_allocated; | 271 | extern int mesh_allocated; |
270 | 272 | ||
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 04b9e4d61b8e..431865a58622 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c | |||
@@ -38,6 +38,8 @@ struct mpath_node { | |||
38 | static struct mesh_table *mesh_paths; | 38 | static struct mesh_table *mesh_paths; |
39 | static struct mesh_table *mpp_paths; /* Store paths for MPP&MAP */ | 39 | static struct mesh_table *mpp_paths; /* Store paths for MPP&MAP */ |
40 | 40 | ||
41 | int mesh_paths_generation; | ||
42 | |||
41 | /* This lock will have the grow table function as writer and add / delete nodes | 43 | /* This lock will have the grow table function as writer and add / delete nodes |
42 | * as readers. When reading the table (i.e. doing lookups) we are well protected | 44 | * as readers. When reading the table (i.e. doing lookups) we are well protected |
43 | * by RCU | 45 | * by RCU |
@@ -243,6 +245,8 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata) | |||
243 | mesh_paths->mean_chain_len * (mesh_paths->hash_mask + 1)) | 245 | mesh_paths->mean_chain_len * (mesh_paths->hash_mask + 1)) |
244 | grow = 1; | 246 | grow = 1; |
245 | 247 | ||
248 | mesh_paths_generation++; | ||
249 | |||
246 | spin_unlock(&mesh_paths->hashwlock[hash_idx]); | 250 | spin_unlock(&mesh_paths->hashwlock[hash_idx]); |
247 | read_unlock(&pathtbl_resize_lock); | 251 | read_unlock(&pathtbl_resize_lock); |
248 | if (grow) { | 252 | if (grow) { |
@@ -484,6 +488,7 @@ int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata) | |||
484 | 488 | ||
485 | err = -ENXIO; | 489 | err = -ENXIO; |
486 | enddel: | 490 | enddel: |
491 | mesh_paths_generation++; | ||
487 | spin_unlock(&mesh_paths->hashwlock[hash_idx]); | 492 | spin_unlock(&mesh_paths->hashwlock[hash_idx]); |
488 | read_unlock(&pathtbl_resize_lock); | 493 | read_unlock(&pathtbl_resize_lock); |
489 | return err; | 494 | return err; |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index a360bceeba59..eec001491e66 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -349,6 +349,7 @@ int sta_info_insert(struct sta_info *sta) | |||
349 | goto out_free; | 349 | goto out_free; |
350 | } | 350 | } |
351 | list_add(&sta->list, &local->sta_list); | 351 | list_add(&sta->list, &local->sta_list); |
352 | local->sta_generation++; | ||
352 | local->num_sta++; | 353 | local->num_sta++; |
353 | sta_info_hash_add(local, sta); | 354 | sta_info_hash_add(local, sta); |
354 | 355 | ||
@@ -485,6 +486,7 @@ static void __sta_info_unlink(struct sta_info **sta) | |||
485 | } | 486 | } |
486 | 487 | ||
487 | local->num_sta--; | 488 | local->num_sta--; |
489 | local->sta_generation++; | ||
488 | 490 | ||
489 | if (local->ops->sta_notify) { | 491 | if (local->ops->sta_notify) { |
490 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 492 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) |