aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mesh.h
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-02-25 10:27:46 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-03-06 15:30:46 -0500
commitd0709a65181beb787ef3f58cfe45536a2bb254c8 (patch)
tree29e5f36583b0e0a3f11b291347e57672eab41dad /net/mac80211/mesh.h
parent5cf121c3cdb955583bf0c5d28c992b7968a4aa1a (diff)
mac80211: RCU-ify STA info structure access
This makes access to the STA hash table/list use RCU to protect against freeing of items. However, it's not a true RCU, the copy step is missing: whenever somebody changes a STA item it is simply updated. This is an existing race condition that is now somewhat understandable. This patch also fixes the race key freeing vs. STA destruction by making sure that sta_info_destroy() is always called under RTNL and frees the key. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/mesh.h')
-rw-r--r--net/mac80211/mesh.h16
1 files changed, 9 insertions, 7 deletions
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index d565b3fb9e6a..576eee83d859 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -65,9 +65,10 @@ enum mesh_path_flags {
65 * @state_lock: mesh pat state lock 65 * @state_lock: mesh pat state lock
66 * 66 *
67 * 67 *
68 * The combination of dst and dev is unique in the mesh path table. A reference 68 * The combination of dst and dev is unique in the mesh path table. Since the
69 * to the next_hop sta will be kept and in case this sta is removed, the 69 * next_hop STA is only protected by RCU as well, deleting the STA must also
70 * mesh_path structure must be also removed or substitued in a rcu safe way 70 * remove/substitute the mesh_path structure and wait until that is no longer
71 * reachable before destroying the STA completely.
71 */ 72 */
72struct mesh_path { 73struct mesh_path {
73 u8 dst[ETH_ALEN]; 74 u8 dst[ETH_ALEN];
@@ -230,8 +231,9 @@ void mesh_neighbour_update(u8 *hw_addr, u64 rates, struct net_device *dev,
230 bool add); 231 bool add);
231bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie, 232bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie,
232 struct net_device *dev); 233 struct net_device *dev);
233void mesh_accept_plinks_update(struct net_device *dev); 234void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);
234struct sta_info *mesh_plink_add(u8 *hw_addr, u64 rates, struct net_device *dev); 235struct sta_info *mesh_plink_add(u8 *hw_addr, u64 rates,
236 struct ieee80211_sub_if_data *sdata);
235void mesh_plink_broken(struct sta_info *sta); 237void mesh_plink_broken(struct sta_info *sta);
236void mesh_plink_deactivate(struct sta_info *sta); 238void mesh_plink_deactivate(struct sta_info *sta);
237int mesh_plink_open(struct sta_info *sta); 239int mesh_plink_open(struct sta_info *sta);
@@ -254,7 +256,7 @@ void mesh_path_flush_pending(struct mesh_path *mpath);
254void mesh_path_tx_pending(struct mesh_path *mpath); 256void mesh_path_tx_pending(struct mesh_path *mpath);
255int mesh_pathtbl_init(void); 257int mesh_pathtbl_init(void);
256void mesh_pathtbl_unregister(void); 258void mesh_pathtbl_unregister(void);
257int mesh_path_del(u8 *addr, struct net_device *dev); 259int mesh_path_del(u8 *addr, struct net_device *dev, bool force);
258void mesh_path_timer(unsigned long data); 260void mesh_path_timer(unsigned long data);
259void mesh_path_flush_by_nexthop(struct sta_info *sta); 261void mesh_path_flush_by_nexthop(struct sta_info *sta);
260void mesh_path_discard_frame(struct sk_buff *skb, struct net_device *dev); 262void mesh_path_discard_frame(struct sk_buff *skb, struct net_device *dev);
@@ -270,7 +272,7 @@ static inline int mesh_plink_free_count(struct ieee80211_sub_if_data *sdata)
270 272
271static inline bool mesh_plink_availables(struct ieee80211_sub_if_data *sdata) 273static inline bool mesh_plink_availables(struct ieee80211_sub_if_data *sdata)
272{ 274{
273 return (min(mesh_plink_free_count(sdata), 275 return (min_t(long, mesh_plink_free_count(sdata),
274 MESH_MAX_PLINKS - sdata->local->num_sta)) > 0; 276 MESH_MAX_PLINKS - sdata->local->num_sta)) > 0;
275} 277}
276 278