aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/cfg.c2
-rw-r--r--net/mac80211/ieee80211.c2
-rw-r--r--net/mac80211/ieee80211_sta.c5
-rw-r--r--net/mac80211/mesh_plink.c6
-rw-r--r--net/mac80211/sta_info.c80
5 files changed, 64 insertions, 31 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 6b183a3526b0..fbd462c78e18 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -672,7 +672,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
672 672
673 err = sta_info_insert(sta); 673 err = sta_info_insert(sta);
674 if (err) { 674 if (err) {
675 sta_info_destroy(sta); 675 /* STA has been freed */
676 rcu_read_unlock(); 676 rcu_read_unlock();
677 return err; 677 return err;
678 } 678 }
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index 8c0f782d21e3..5ee431b6256c 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -268,7 +268,7 @@ static int ieee80211_open(struct net_device *dev)
268 268
269 res = sta_info_insert(sta); 269 res = sta_info_insert(sta);
270 if (res) { 270 if (res) {
271 sta_info_destroy(sta); 271 /* STA has been freed */
272 return res; 272 return res;
273 } 273 }
274 break; 274 break;
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index baa68575b98a..00fde111c268 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -1942,7 +1942,6 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1942 if (err) { 1942 if (err) {
1943 printk(KERN_DEBUG "%s: failed to insert STA entry for" 1943 printk(KERN_DEBUG "%s: failed to insert STA entry for"
1944 " the AP (error %d)\n", dev->name, err); 1944 " the AP (error %d)\n", dev->name, err);
1945 sta_info_destroy(sta);
1946 rcu_read_unlock(); 1945 rcu_read_unlock();
1947 return; 1946 return;
1948 } 1947 }
@@ -4172,10 +4171,8 @@ struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev,
4172 4171
4173 rate_control_rate_init(sta, local); 4172 rate_control_rate_init(sta, local);
4174 4173
4175 if (sta_info_insert(sta)) { 4174 if (sta_info_insert(sta))
4176 sta_info_destroy(sta);
4177 return NULL; 4175 return NULL;
4178 }
4179 4176
4180 return sta; 4177 return sta;
4181} 4178}
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 18fe52436c47..56c54e321b38 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -89,6 +89,10 @@ static inline void mesh_plink_fsm_restart(struct sta_info *sta)
89 sta->plink_retries = 0; 89 sta->plink_retries = 0;
90} 90}
91 91
92/*
93 * NOTE: This is just an alias for sta_info_alloc(), see notes
94 * on it in the lifecycle management section!
95 */
92static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, 96static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata,
93 u8 *hw_addr, u64 rates) 97 u8 *hw_addr, u64 rates)
94{ 98{
@@ -235,7 +239,6 @@ void mesh_neighbour_update(u8 *hw_addr, u64 rates, struct net_device *dev,
235 return; 239 return;
236 } 240 }
237 if (sta_info_insert(sta)) { 241 if (sta_info_insert(sta)) {
238 sta_info_destroy(sta);
239 rcu_read_unlock(); 242 rcu_read_unlock();
240 return; 243 return;
241 } 244 }
@@ -506,7 +509,6 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
506 return; 509 return;
507 } 510 }
508 if (sta_info_insert(sta)) { 511 if (sta_info_insert(sta)) {
509 sta_info_destroy(sta);
510 rcu_read_unlock(); 512 rcu_read_unlock();
511 return; 513 return;
512 } 514 }
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)