aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/sta_info.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/sta_info.c')
-rw-r--r--net/mac80211/sta_info.c80
1 files changed, 57 insertions, 23 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 2a5a2f067bae..5497ca1843fe 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -36,16 +36,23 @@
36 * (which is pretty useless) or insert it into the hash table using 36 * (which is pretty useless) or insert it into the hash table using
37 * sta_info_insert() which demotes the reference from ownership to a regular 37 * sta_info_insert() which demotes the reference from ownership to a regular
38 * RCU-protected reference; if the function is called without protection by an 38 * RCU-protected reference; if the function is called without protection by an
39 * RCU critical section the reference is instantly invalidated. 39 * RCU critical section the reference is instantly invalidated. Note that the
40 * caller may not do much with the STA info before inserting it, in particular,
41 * it may not start any mesh peer link management or add encryption keys.
42 *
43 * When the insertion fails (sta_info_insert()) returns non-zero), the
44 * structure will have been freed by sta_info_insert()!
40 * 45 *
41 * Because there are debugfs entries for each station, and adding those 46 * Because there are debugfs entries for each station, and adding those
42 * must be able to sleep, it is also possible to "pin" a station entry, 47 * must be able to sleep, it is also possible to "pin" a station entry,
43 * that means it can be removed from the hash table but not be freed. 48 * that means it can be removed from the hash table but not be freed.
44 * See the comment in __sta_info_unlink() for more information. 49 * See the comment in __sta_info_unlink() for more information, this is
50 * an internal capability only.
45 * 51 *
46 * In order to remove a STA info structure, the caller needs to first 52 * In order to remove a STA info structure, the caller needs to first
47 * unlink it (sta_info_unlink()) from the list and hash tables and 53 * unlink it (sta_info_unlink()) from the list and hash tables and
48 * then wait for an RCU synchronisation before it can be freed. Due to 54 * then destroy it while holding the RTNL; sta_info_destroy() will wait
55 * for an RCU grace period to elapse before actually freeing it. Due to
49 * the pinning and the possibility of multiple callers trying to remove 56 * the pinning and the possibility of multiple callers trying to remove
50 * the same STA info at the same time, sta_info_unlink() can clear the 57 * the same STA info at the same time, sta_info_unlink() can clear the
51 * STA info pointer it is passed to indicate that the STA info is owned 58 * STA info pointer it is passed to indicate that the STA info is owned
@@ -127,12 +134,35 @@ struct sta_info *sta_info_get_by_idx(struct ieee80211_local *local, int idx,
127 return NULL; 134 return NULL;
128} 135}
129 136
137/**
138 * __sta_info_free - internal STA free helper
139 *
140 * @sta: STA info to free
141 *
142 * This function must undo everything done by sta_info_alloc()
143 * that may happen before sta_info_insert().
144 */
145static void __sta_info_free(struct ieee80211_local *local,
146 struct sta_info *sta)
147{
148 DECLARE_MAC_BUF(mbuf);
149
150 rate_control_free_sta(sta->rate_ctrl, sta->rate_ctrl_priv);
151 rate_control_put(sta->rate_ctrl);
152
153#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
154 printk(KERN_DEBUG "%s: Destroyed STA %s\n",
155 wiphy_name(local->hw.wiphy), print_mac(mbuf, sta->addr));
156#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
157
158 kfree(sta);
159}
160
130void sta_info_destroy(struct sta_info *sta) 161void sta_info_destroy(struct sta_info *sta)
131{ 162{
132 struct ieee80211_local *local; 163 struct ieee80211_local *local;
133 struct sk_buff *skb; 164 struct sk_buff *skb;
134 int i; 165 int i;
135 DECLARE_MAC_BUF(mbuf);
136 166
137 ASSERT_RTNL(); 167 ASSERT_RTNL();
138 might_sleep(); 168 might_sleep();
@@ -182,15 +212,7 @@ void sta_info_destroy(struct sta_info *sta)
182 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 212 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
183 } 213 }
184 214
185 rate_control_free_sta(sta->rate_ctrl, sta->rate_ctrl_priv); 215 __sta_info_free(local, sta);
186 rate_control_put(sta->rate_ctrl);
187
188#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
189 printk(KERN_DEBUG "%s: Destroyed STA %s\n",
190 wiphy_name(local->hw.wiphy), print_mac(mbuf, sta->addr));
191#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
192
193 kfree(sta);
194} 216}
195 217
196 218
@@ -266,6 +288,7 @@ int sta_info_insert(struct sta_info *sta)
266 struct ieee80211_local *local = sta->local; 288 struct ieee80211_local *local = sta->local;
267 struct ieee80211_sub_if_data *sdata = sta->sdata; 289 struct ieee80211_sub_if_data *sdata = sta->sdata;
268 unsigned long flags; 290 unsigned long flags;
291 int err = 0;
269 DECLARE_MAC_BUF(mac); 292 DECLARE_MAC_BUF(mac);
270 293
271 /* 294 /*
@@ -273,20 +296,23 @@ int sta_info_insert(struct sta_info *sta)
273 * something inserts a STA (on one CPU) without holding the RTNL 296 * something inserts a STA (on one CPU) without holding the RTNL
274 * and another CPU turns off the net device. 297 * and another CPU turns off the net device.
275 */ 298 */
276 if (unlikely(!netif_running(sdata->dev))) 299 if (unlikely(!netif_running(sdata->dev))) {
277 return -ENETDOWN; 300 err = -ENETDOWN;
278 301 goto out_free;
279 if (WARN_ON(compare_ether_addr(sta->addr, sdata->dev->dev_addr) == 0)) 302 }
280 return -EINVAL;
281 303
282 if (WARN_ON(is_multicast_ether_addr(sta->addr))) 304 if (WARN_ON(compare_ether_addr(sta->addr, sdata->dev->dev_addr) == 0 ||
283 return -EINVAL; 305 is_multicast_ether_addr(sta->addr))) {
306 err = -EINVAL;
307 goto out_free;
308 }
284 309
285 spin_lock_irqsave(&local->sta_lock, flags); 310 spin_lock_irqsave(&local->sta_lock, flags);
286 /* check if STA exists already */ 311 /* check if STA exists already */
287 if (__sta_info_find(local, sta->addr)) { 312 if (__sta_info_find(local, sta->addr)) {
288 spin_unlock_irqrestore(&local->sta_lock, flags); 313 spin_unlock_irqrestore(&local->sta_lock, flags);
289 return -EEXIST; 314 err = -EEXIST;
315 goto out_free;
290 } 316 }
291 list_add(&sta->list, &local->sta_list); 317 list_add(&sta->list, &local->sta_list);
292 local->num_sta++; 318 local->num_sta++;
@@ -309,9 +335,13 @@ int sta_info_insert(struct sta_info *sta)
309 spin_unlock_irqrestore(&local->sta_lock, flags); 335 spin_unlock_irqrestore(&local->sta_lock, flags);
310 336
311#ifdef CONFIG_MAC80211_DEBUGFS 337#ifdef CONFIG_MAC80211_DEBUGFS
312 /* debugfs entry adding might sleep, so schedule process 338 /*
339 * Debugfs entry adding might sleep, so schedule process
313 * context task for adding entry for STAs that do not yet 340 * context task for adding entry for STAs that do not yet
314 * have one. */ 341 * have one.
342 * NOTE: due to auto-freeing semantics this may only be done
343 * if the insertion is successful!
344 */
315 queue_work(local->hw.workqueue, &local->sta_debugfs_add); 345 queue_work(local->hw.workqueue, &local->sta_debugfs_add);
316#endif 346#endif
317 347
@@ -319,6 +349,10 @@ int sta_info_insert(struct sta_info *sta)
319 mesh_accept_plinks_update(sdata); 349 mesh_accept_plinks_update(sdata);
320 350
321 return 0; 351 return 0;
352 out_free:
353 BUG_ON(!err);
354 __sta_info_free(local, sta);
355 return err;
322} 356}
323 357
324static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid) 358static inline void __bss_tim_set(struct ieee80211_if_ap *bss, u16 aid)