aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/ieee80211_sta.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/ieee80211_sta.c')
-rw-r--r--net/mac80211/ieee80211_sta.c123
1 files changed, 85 insertions, 38 deletions
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index 9f933aeca719..a3e96eb59eb0 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -24,6 +24,7 @@
24#include <linux/wireless.h> 24#include <linux/wireless.h>
25#include <linux/random.h> 25#include <linux/random.h>
26#include <linux/etherdevice.h> 26#include <linux/etherdevice.h>
27#include <linux/rtnetlink.h>
27#include <net/iw_handler.h> 28#include <net/iw_handler.h>
28#include <asm/types.h> 29#include <asm/types.h>
29 30
@@ -845,6 +846,8 @@ static void ieee80211_associated(struct net_device *dev,
845 846
846 ifsta->state = IEEE80211_ASSOCIATED; 847 ifsta->state = IEEE80211_ASSOCIATED;
847 848
849 rcu_read_lock();
850
848 sta = sta_info_get(local, ifsta->bssid); 851 sta = sta_info_get(local, ifsta->bssid);
849 if (!sta) { 852 if (!sta) {
850 printk(KERN_DEBUG "%s: No STA entry for own AP %s\n", 853 printk(KERN_DEBUG "%s: No STA entry for own AP %s\n",
@@ -860,7 +863,7 @@ static void ieee80211_associated(struct net_device *dev,
860 "range\n", 863 "range\n",
861 dev->name, print_mac(mac, ifsta->bssid)); 864 dev->name, print_mac(mac, ifsta->bssid));
862 disassoc = 1; 865 disassoc = 1;
863 sta_info_free(sta); 866 sta_info_unlink(&sta);
864 } else 867 } else
865 ieee80211_send_probe_req(dev, ifsta->bssid, 868 ieee80211_send_probe_req(dev, ifsta->bssid,
866 local->scan_ssid, 869 local->scan_ssid,
@@ -876,8 +879,17 @@ static void ieee80211_associated(struct net_device *dev,
876 ifsta->ssid_len); 879 ifsta->ssid_len);
877 } 880 }
878 } 881 }
879 sta_info_put(sta);
880 } 882 }
883
884 rcu_read_unlock();
885
886 if (disassoc && sta) {
887 synchronize_rcu();
888 rtnl_lock();
889 sta_info_destroy(sta);
890 rtnl_unlock();
891 }
892
881 if (disassoc) { 893 if (disassoc) {
882 ifsta->state = IEEE80211_DISABLED; 894 ifsta->state = IEEE80211_DISABLED;
883 ieee80211_set_associated(dev, ifsta, 0); 895 ieee80211_set_associated(dev, ifsta, 0);
@@ -1103,9 +1115,13 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev,
1103 int ret = -EOPNOTSUPP; 1115 int ret = -EOPNOTSUPP;
1104 DECLARE_MAC_BUF(mac); 1116 DECLARE_MAC_BUF(mac);
1105 1117
1118 rcu_read_lock();
1119
1106 sta = sta_info_get(local, mgmt->sa); 1120 sta = sta_info_get(local, mgmt->sa);
1107 if (!sta) 1121 if (!sta) {
1122 rcu_read_unlock();
1108 return; 1123 return;
1124 }
1109 1125
1110 /* extract session parameters from addba request frame */ 1126 /* extract session parameters from addba request frame */
1111 dialog_token = mgmt->u.action.u.addba_req.dialog_token; 1127 dialog_token = mgmt->u.action.u.addba_req.dialog_token;
@@ -1197,9 +1213,9 @@ end:
1197 spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); 1213 spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx);
1198 1214
1199end_no_lock: 1215end_no_lock:
1200 ieee80211_send_addba_resp(sta->dev, sta->addr, tid, dialog_token, 1216 ieee80211_send_addba_resp(sta->sdata->dev, sta->addr, tid,
1201 status, 1, buf_size, timeout); 1217 dialog_token, status, 1, buf_size, timeout);
1202 sta_info_put(sta); 1218 rcu_read_unlock();
1203} 1219}
1204 1220
1205static void ieee80211_sta_process_addba_resp(struct net_device *dev, 1221static void ieee80211_sta_process_addba_resp(struct net_device *dev,
@@ -1213,9 +1229,13 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev,
1213 u16 tid; 1229 u16 tid;
1214 u8 *state; 1230 u8 *state;
1215 1231
1232 rcu_read_lock();
1233
1216 sta = sta_info_get(local, mgmt->sa); 1234 sta = sta_info_get(local, mgmt->sa);
1217 if (!sta) 1235 if (!sta) {
1236 rcu_read_unlock();
1218 return; 1237 return;
1238 }
1219 1239
1220 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab); 1240 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
1221 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; 1241 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
@@ -1230,7 +1250,7 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev,
1230#ifdef CONFIG_MAC80211_HT_DEBUG 1250#ifdef CONFIG_MAC80211_HT_DEBUG
1231 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); 1251 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
1232#endif /* CONFIG_MAC80211_HT_DEBUG */ 1252#endif /* CONFIG_MAC80211_HT_DEBUG */
1233 sta_info_put(sta); 1253 rcu_read_unlock();
1234 return; 1254 return;
1235 } 1255 }
1236 1256
@@ -1244,7 +1264,7 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev,
1244 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); 1264 spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
1245 printk(KERN_DEBUG "state not HT_ADDBA_REQUESTED_MSK:" 1265 printk(KERN_DEBUG "state not HT_ADDBA_REQUESTED_MSK:"
1246 "%d\n", *state); 1266 "%d\n", *state);
1247 sta_info_put(sta); 1267 rcu_read_unlock();
1248 return; 1268 return;
1249 } 1269 }
1250 1270
@@ -1271,7 +1291,7 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev,
1271 ieee80211_stop_tx_ba_session(hw, sta->addr, tid, 1291 ieee80211_stop_tx_ba_session(hw, sta->addr, tid,
1272 WLAN_BACK_INITIATOR); 1292 WLAN_BACK_INITIATOR);
1273 } 1293 }
1274 sta_info_put(sta); 1294 rcu_read_unlock();
1275} 1295}
1276 1296
1277void ieee80211_send_delba(struct net_device *dev, const u8 *da, u16 tid, 1297void ieee80211_send_delba(struct net_device *dev, const u8 *da, u16 tid,
@@ -1326,16 +1346,20 @@ void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid,
1326 struct sta_info *sta; 1346 struct sta_info *sta;
1327 int ret, i; 1347 int ret, i;
1328 1348
1349 rcu_read_lock();
1350
1329 sta = sta_info_get(local, ra); 1351 sta = sta_info_get(local, ra);
1330 if (!sta) 1352 if (!sta) {
1353 rcu_read_unlock();
1331 return; 1354 return;
1355 }
1332 1356
1333 /* check if TID is in operational state */ 1357 /* check if TID is in operational state */
1334 spin_lock_bh(&sta->ampdu_mlme.ampdu_rx); 1358 spin_lock_bh(&sta->ampdu_mlme.ampdu_rx);
1335 if (sta->ampdu_mlme.tid_rx[tid].state 1359 if (sta->ampdu_mlme.tid_rx[tid].state
1336 != HT_AGG_STATE_OPERATIONAL) { 1360 != HT_AGG_STATE_OPERATIONAL) {
1337 spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); 1361 spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx);
1338 sta_info_put(sta); 1362 rcu_read_unlock();
1339 return; 1363 return;
1340 } 1364 }
1341 sta->ampdu_mlme.tid_rx[tid].state = 1365 sta->ampdu_mlme.tid_rx[tid].state =
@@ -1374,7 +1398,7 @@ void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid,
1374 kfree(sta->ampdu_mlme.tid_rx[tid].reorder_buf); 1398 kfree(sta->ampdu_mlme.tid_rx[tid].reorder_buf);
1375 1399
1376 sta->ampdu_mlme.tid_rx[tid].state = HT_AGG_STATE_IDLE; 1400 sta->ampdu_mlme.tid_rx[tid].state = HT_AGG_STATE_IDLE;
1377 sta_info_put(sta); 1401 rcu_read_unlock();
1378} 1402}
1379 1403
1380 1404
@@ -1387,9 +1411,13 @@ static void ieee80211_sta_process_delba(struct net_device *dev,
1387 u16 initiator; 1411 u16 initiator;
1388 DECLARE_MAC_BUF(mac); 1412 DECLARE_MAC_BUF(mac);
1389 1413
1414 rcu_read_lock();
1415
1390 sta = sta_info_get(local, mgmt->sa); 1416 sta = sta_info_get(local, mgmt->sa);
1391 if (!sta) 1417 if (!sta) {
1418 rcu_read_unlock();
1392 return; 1419 return;
1420 }
1393 1421
1394 params = le16_to_cpu(mgmt->u.action.u.delba.params); 1422 params = le16_to_cpu(mgmt->u.action.u.delba.params);
1395 tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12; 1423 tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12;
@@ -1414,7 +1442,7 @@ static void ieee80211_sta_process_delba(struct net_device *dev,
1414 ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid, 1442 ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid,
1415 WLAN_BACK_RECIPIENT); 1443 WLAN_BACK_RECIPIENT);
1416 } 1444 }
1417 sta_info_put(sta); 1445 rcu_read_unlock();
1418} 1446}
1419 1447
1420/* 1448/*
@@ -1437,9 +1465,13 @@ void sta_addba_resp_timer_expired(unsigned long data)
1437 struct sta_info *sta; 1465 struct sta_info *sta;
1438 u8 *state; 1466 u8 *state;
1439 1467
1468 rcu_read_lock();
1469
1440 sta = sta_info_get(local, temp_sta->addr); 1470 sta = sta_info_get(local, temp_sta->addr);
1441 if (!sta) 1471 if (!sta) {
1472 rcu_read_unlock();
1442 return; 1473 return;
1474 }
1443 1475
1444 state = &sta->ampdu_mlme.tid_tx[tid].state; 1476 state = &sta->ampdu_mlme.tid_tx[tid].state;
1445 /* check if the TID waits for addBA response */ 1477 /* check if the TID waits for addBA response */
@@ -1461,7 +1493,7 @@ void sta_addba_resp_timer_expired(unsigned long data)
1461 WLAN_BACK_INITIATOR); 1493 WLAN_BACK_INITIATOR);
1462 1494
1463timer_expired_exit: 1495timer_expired_exit:
1464 sta_info_put(sta); 1496 rcu_read_unlock();
1465} 1497}
1466 1498
1467/* 1499/*
@@ -1481,8 +1513,8 @@ void sta_rx_agg_session_timer_expired(unsigned long data)
1481 timer_to_tid[0]); 1513 timer_to_tid[0]);
1482 1514
1483 printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); 1515 printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid);
1484 ieee80211_sta_stop_rx_ba_session(sta->dev, sta->addr, (u16)*ptid, 1516 ieee80211_sta_stop_rx_ba_session(sta->sdata->dev, sta->addr,
1485 WLAN_BACK_TIMER, 1517 (u16)*ptid, WLAN_BACK_TIMER,
1486 WLAN_REASON_QSTA_TIMEOUT); 1518 WLAN_REASON_QSTA_TIMEOUT);
1487} 1519}
1488 1520
@@ -1791,14 +1823,18 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1791 if (ifsta->assocresp_ies) 1823 if (ifsta->assocresp_ies)
1792 memcpy(ifsta->assocresp_ies, pos, ifsta->assocresp_ies_len); 1824 memcpy(ifsta->assocresp_ies, pos, ifsta->assocresp_ies_len);
1793 1825
1826 rcu_read_lock();
1827
1794 /* Add STA entry for the AP */ 1828 /* Add STA entry for the AP */
1795 sta = sta_info_get(local, ifsta->bssid); 1829 sta = sta_info_get(local, ifsta->bssid);
1796 if (!sta) { 1830 if (!sta) {
1797 struct ieee80211_sta_bss *bss; 1831 struct ieee80211_sta_bss *bss;
1798 sta = sta_info_add(local, dev, ifsta->bssid, GFP_KERNEL); 1832
1833 sta = sta_info_add(sdata, ifsta->bssid);
1799 if (IS_ERR(sta)) { 1834 if (IS_ERR(sta)) {
1800 printk(KERN_DEBUG "%s: failed to add STA entry for the" 1835 printk(KERN_DEBUG "%s: failed to add STA entry for the"
1801 " AP (error %ld)\n", dev->name, PTR_ERR(sta)); 1836 " AP (error %ld)\n", dev->name, PTR_ERR(sta));
1837 rcu_read_unlock();
1802 return; 1838 return;
1803 } 1839 }
1804 bss = ieee80211_rx_bss_get(dev, ifsta->bssid, 1840 bss = ieee80211_rx_bss_get(dev, ifsta->bssid,
@@ -1812,7 +1848,6 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1812 } 1848 }
1813 } 1849 }
1814 1850
1815 sta->dev = dev;
1816 sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP | 1851 sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP |
1817 WLAN_STA_AUTHORIZED; 1852 WLAN_STA_AUTHORIZED;
1818 1853
@@ -1883,7 +1918,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1883 bss_conf->aid = aid; 1918 bss_conf->aid = aid;
1884 ieee80211_set_associated(dev, ifsta, 1); 1919 ieee80211_set_associated(dev, ifsta, 1);
1885 1920
1886 sta_info_put(sta); 1921 rcu_read_unlock();
1887 1922
1888 ieee80211_associated(dev, ifsta); 1923 ieee80211_associated(dev, ifsta);
1889} 1924}
@@ -2329,6 +2364,8 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
2329 mesh_peer_accepts_plinks(&elems, dev)); 2364 mesh_peer_accepts_plinks(&elems, dev));
2330 } 2365 }
2331 2366
2367 rcu_read_lock();
2368
2332 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates && 2369 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates &&
2333 memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && 2370 memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 &&
2334 (sta = sta_info_get(local, mgmt->sa))) { 2371 (sta = sta_info_get(local, mgmt->sa))) {
@@ -2354,9 +2391,10 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
2354 (unsigned long long) supp_rates, 2391 (unsigned long long) supp_rates,
2355 (unsigned long long) sta->supp_rates[rx_status->band]); 2392 (unsigned long long) sta->supp_rates[rx_status->band]);
2356 } 2393 }
2357 sta_info_put(sta);
2358 } 2394 }
2359 2395
2396 rcu_read_unlock();
2397
2360 if (elems.ds_params && elems.ds_params_len == 1) 2398 if (elems.ds_params && elems.ds_params_len == 1)
2361 freq = ieee80211_channel_to_frequency(elems.ds_params[0]); 2399 freq = ieee80211_channel_to_frequency(elems.ds_params[0]);
2362 else 2400 else
@@ -2550,8 +2588,10 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
2550 "local TSF - IBSS merge with BSSID %s\n", 2588 "local TSF - IBSS merge with BSSID %s\n",
2551 dev->name, print_mac(mac, mgmt->bssid)); 2589 dev->name, print_mac(mac, mgmt->bssid));
2552 ieee80211_sta_join_ibss(dev, &sdata->u.sta, bss); 2590 ieee80211_sta_join_ibss(dev, &sdata->u.sta, bss);
2591 rcu_read_lock();
2553 ieee80211_ibss_add_sta(dev, NULL, 2592 ieee80211_ibss_add_sta(dev, NULL,
2554 mgmt->bssid, mgmt->sa); 2593 mgmt->bssid, mgmt->sa);
2594 rcu_read_unlock();
2555 } 2595 }
2556 } 2596 }
2557 2597
@@ -2893,17 +2933,20 @@ static int ieee80211_sta_active_ibss(struct net_device *dev)
2893 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 2933 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
2894 int active = 0; 2934 int active = 0;
2895 struct sta_info *sta; 2935 struct sta_info *sta;
2936 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2896 2937
2897 read_lock_bh(&local->sta_lock); 2938 rcu_read_lock();
2898 list_for_each_entry(sta, &local->sta_list, list) { 2939
2899 if (sta->dev == dev && 2940 list_for_each_entry_rcu(sta, &local->sta_list, list) {
2941 if (sta->sdata == sdata &&
2900 time_after(sta->last_rx + IEEE80211_IBSS_MERGE_INTERVAL, 2942 time_after(sta->last_rx + IEEE80211_IBSS_MERGE_INTERVAL,
2901 jiffies)) { 2943 jiffies)) {
2902 active++; 2944 active++;
2903 break; 2945 break;
2904 } 2946 }
2905 } 2947 }
2906 read_unlock_bh(&local->sta_lock); 2948
2949 rcu_read_unlock();
2907 2950
2908 return active; 2951 return active;
2909} 2952}
@@ -2915,22 +2958,25 @@ static void ieee80211_sta_expire(struct net_device *dev, unsigned long exp_time)
2915 struct sta_info *sta, *tmp; 2958 struct sta_info *sta, *tmp;
2916 LIST_HEAD(tmp_list); 2959 LIST_HEAD(tmp_list);
2917 DECLARE_MAC_BUF(mac); 2960 DECLARE_MAC_BUF(mac);
2961 unsigned long flags;
2918 2962
2919 write_lock_bh(&local->sta_lock); 2963 spin_lock_irqsave(&local->sta_lock, flags);
2920 list_for_each_entry_safe(sta, tmp, &local->sta_list, list) 2964 list_for_each_entry_safe(sta, tmp, &local->sta_list, list)
2921 if (time_after(jiffies, sta->last_rx + exp_time)) { 2965 if (time_after(jiffies, sta->last_rx + exp_time)) {
2922 printk(KERN_DEBUG "%s: expiring inactive STA %s\n", 2966 printk(KERN_DEBUG "%s: expiring inactive STA %s\n",
2923 dev->name, print_mac(mac, sta->addr)); 2967 dev->name, print_mac(mac, sta->addr));
2924 __sta_info_get(sta); 2968 sta_info_unlink(&sta);
2925 sta_info_remove(sta); 2969 if (sta)
2926 list_add(&sta->list, &tmp_list); 2970 list_add(&sta->list, &tmp_list);
2927 } 2971 }
2928 write_unlock_bh(&local->sta_lock); 2972 spin_unlock_irqrestore(&local->sta_lock, flags);
2929 2973
2930 list_for_each_entry_safe(sta, tmp, &tmp_list, list) { 2974 synchronize_rcu();
2931 sta_info_free(sta); 2975
2932 sta_info_put(sta); 2976 rtnl_lock();
2933 } 2977 list_for_each_entry_safe(sta, tmp, &tmp_list, list)
2978 sta_info_destroy(sta);
2979 rtnl_unlock();
2934} 2980}
2935 2981
2936 2982
@@ -3977,6 +4023,7 @@ int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len)
3977} 4023}
3978 4024
3979 4025
4026/* must be called under RCU read lock */
3980struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev, 4027struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev,
3981 struct sk_buff *skb, u8 *bssid, 4028 struct sk_buff *skb, u8 *bssid,
3982 u8 *addr) 4029 u8 *addr)
@@ -3999,7 +4046,7 @@ struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev,
3999 printk(KERN_DEBUG "%s: Adding new IBSS station %s (dev=%s)\n", 4046 printk(KERN_DEBUG "%s: Adding new IBSS station %s (dev=%s)\n",
4000 wiphy_name(local->hw.wiphy), print_mac(mac, addr), dev->name); 4047 wiphy_name(local->hw.wiphy), print_mac(mac, addr), dev->name);
4001 4048
4002 sta = sta_info_add(local, dev, addr, GFP_ATOMIC); 4049 sta = sta_info_add(sdata, addr);
4003 if (IS_ERR(sta)) 4050 if (IS_ERR(sta))
4004 return NULL; 4051 return NULL;
4005 4052
@@ -4010,7 +4057,7 @@ struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev,
4010 4057
4011 rate_control_rate_init(sta, local); 4058 rate_control_rate_init(sta, local);
4012 4059
4013 return sta; /* caller will call sta_info_put() */ 4060 return sta;
4014} 4061}
4015 4062
4016 4063