aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2008-09-08 17:32:12 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-09-11 15:53:35 -0400
commitaa458d1737c3cc9a7c90ea9c5ef1ee6d663fba71 (patch)
treeb3331d3f864f9ff00def1280bd19bfbe3df9f5c8 /net/mac80211/mlme.c
parent79636a5fbbdfb303dbf2bfe7a7fa396f40bfac31 (diff)
mac80211: restructure disassoc/deauth flows
This patch restructure the flow of disassociation and deauthentication flows to be consistent under all circumstances. It ensures that BA session is treated down before deauthentication or disassociation, adds the removal of the obsolete sta form station table and fixes a related bug (sta_info_destroy without sta_info_unlink) in ieee80211_associated() and reduce some code duplication Signed-off-by: Ron Rindjunsky <ron.rindjunsky@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c85
1 files changed, 54 insertions, 31 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index b03f1f3ef2ed..f7a390ff9679 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -415,8 +415,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
415 memcpy(wrqu.ap_addr.sa_data, sdata->u.sta.bssid, ETH_ALEN); 415 memcpy(wrqu.ap_addr.sa_data, sdata->u.sta.bssid, ETH_ALEN);
416 ieee80211_sta_send_associnfo(sdata, ifsta); 416 ieee80211_sta_send_associnfo(sdata, ifsta);
417 } else { 417 } else {
418 netif_carrier_off(sdata->dev);
419 ieee80211_sta_tear_down_BA_sessions(sdata, ifsta->bssid);
420 ifsta->flags &= ~IEEE80211_STA_ASSOCIATED; 418 ifsta->flags &= ~IEEE80211_STA_ASSOCIATED;
421 changed |= ieee80211_reset_erp_info(sdata); 419 changed |= ieee80211_reset_erp_info(sdata);
422 420
@@ -439,18 +437,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
439 wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL); 437 wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL);
440} 438}
441 439
442static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
443 struct ieee80211_if_sta *ifsta, int deauth)
444{
445 if (deauth) {
446 ifsta->direct_probe_tries = 0;
447 ifsta->auth_tries = 0;
448 }
449 ifsta->assoc_scan_tries = 0;
450 ifsta->assoc_tries = 0;
451 ieee80211_set_associated(sdata, ifsta, 0);
452}
453
454void ieee80211_sta_tx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, 440void ieee80211_sta_tx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
455 int encrypt) 441 int encrypt)
456{ 442{
@@ -844,6 +830,50 @@ static void ieee80211_send_disassoc(struct ieee80211_sub_if_data *sdata,
844 ieee80211_sta_tx(sdata, skb, 0); 830 ieee80211_sta_tx(sdata, skb, 0);
845} 831}
846 832
833static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
834 struct ieee80211_if_sta *ifsta, bool deauth,
835 bool self_disconnected, u16 reason)
836{
837 struct ieee80211_local *local = sdata->local;
838 struct sta_info *sta;
839
840 rcu_read_lock();
841
842 sta = sta_info_get(local, ifsta->bssid);
843 if (!sta) {
844 rcu_read_unlock();
845 return;
846 }
847
848 if (deauth) {
849 ifsta->direct_probe_tries = 0;
850 ifsta->auth_tries = 0;
851 }
852 ifsta->assoc_scan_tries = 0;
853 ifsta->assoc_tries = 0;
854
855 netif_carrier_off(sdata->dev);
856
857 ieee80211_sta_tear_down_BA_sessions(sdata, sta->addr);
858
859 if (self_disconnected) {
860 if (deauth)
861 ieee80211_send_deauth(sdata, ifsta, reason);
862 else
863 ieee80211_send_disassoc(sdata, ifsta, reason);
864 }
865
866 ieee80211_set_associated(sdata, ifsta, 0);
867
868 if (self_disconnected)
869 ifsta->state = IEEE80211_STA_MLME_DISABLED;
870
871 sta_info_unlink(&sta);
872
873 rcu_read_unlock();
874
875 sta_info_destroy(sta);
876}
847 877
848static int ieee80211_privacy_mismatch(struct ieee80211_sub_if_data *sdata, 878static int ieee80211_privacy_mismatch(struct ieee80211_sub_if_data *sdata,
849 struct ieee80211_if_sta *ifsta) 879 struct ieee80211_if_sta *ifsta)
@@ -938,7 +968,6 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata,
938 "range\n", 968 "range\n",
939 sdata->dev->name, print_mac(mac, ifsta->bssid)); 969 sdata->dev->name, print_mac(mac, ifsta->bssid));
940 disassoc = 1; 970 disassoc = 1;
941 sta_info_unlink(&sta);
942 } else 971 } else
943 ieee80211_send_probe_req(sdata, ifsta->bssid, 972 ieee80211_send_probe_req(sdata, ifsta->bssid,
944 local->scan_ssid, 973 local->scan_ssid,
@@ -958,16 +987,12 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata,
958 987
959 rcu_read_unlock(); 988 rcu_read_unlock();
960 989
961 if (disassoc && sta) 990 if (disassoc)
962 sta_info_destroy(sta); 991 ieee80211_set_disassoc(sdata, ifsta, true, true,
963 992 WLAN_REASON_PREV_AUTH_NOT_VALID);
964 if (disassoc) { 993 else
965 ifsta->state = IEEE80211_STA_MLME_DISABLED;
966 ieee80211_set_associated(sdata, ifsta, 0);
967 } else {
968 mod_timer(&ifsta->timer, jiffies + 994 mod_timer(&ifsta->timer, jiffies +
969 IEEE80211_MONITORING_INTERVAL); 995 IEEE80211_MONITORING_INTERVAL);
970 }
971} 996}
972 997
973 998
@@ -1832,7 +1857,7 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1832 IEEE80211_RETRY_AUTH_INTERVAL); 1857 IEEE80211_RETRY_AUTH_INTERVAL);
1833 } 1858 }
1834 1859
1835 ieee80211_set_disassoc(sdata, ifsta, 1); 1860 ieee80211_set_disassoc(sdata, ifsta, true, false, 0);
1836 ifsta->flags &= ~IEEE80211_STA_AUTHENTICATED; 1861 ifsta->flags &= ~IEEE80211_STA_AUTHENTICATED;
1837} 1862}
1838 1863
@@ -1862,7 +1887,7 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1862 IEEE80211_RETRY_AUTH_INTERVAL); 1887 IEEE80211_RETRY_AUTH_INTERVAL);
1863 } 1888 }
1864 1889
1865 ieee80211_set_disassoc(sdata, ifsta, 0); 1890 ieee80211_set_disassoc(sdata, ifsta, false, false, 0);
1866} 1891}
1867 1892
1868 1893
@@ -3200,8 +3225,8 @@ void ieee80211_sta_work(struct work_struct *work)
3200 printk(KERN_DEBUG "%s: privacy configuration mismatch and " 3225 printk(KERN_DEBUG "%s: privacy configuration mismatch and "
3201 "mixed-cell disabled - disassociate\n", sdata->dev->name); 3226 "mixed-cell disabled - disassociate\n", sdata->dev->name);
3202 3227
3203 ieee80211_send_disassoc(sdata, ifsta, WLAN_REASON_UNSPECIFIED); 3228 ieee80211_set_disassoc(sdata, ifsta, false, true,
3204 ieee80211_set_disassoc(sdata, ifsta, 0); 3229 WLAN_REASON_UNSPECIFIED);
3205 } 3230 }
3206} 3231}
3207 3232
@@ -4236,8 +4261,7 @@ int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason
4236 sdata->vif.type != IEEE80211_IF_TYPE_IBSS) 4261 sdata->vif.type != IEEE80211_IF_TYPE_IBSS)
4237 return -EINVAL; 4262 return -EINVAL;
4238 4263
4239 ieee80211_send_deauth(sdata, ifsta, reason); 4264 ieee80211_set_disassoc(sdata, ifsta, true, true, reason);
4240 ieee80211_set_disassoc(sdata, ifsta, 1);
4241 return 0; 4265 return 0;
4242} 4266}
4243 4267
@@ -4255,8 +4279,7 @@ int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason)
4255 if (!(ifsta->flags & IEEE80211_STA_ASSOCIATED)) 4279 if (!(ifsta->flags & IEEE80211_STA_ASSOCIATED))
4256 return -1; 4280 return -1;
4257 4281
4258 ieee80211_send_disassoc(sdata, ifsta, reason); 4282 ieee80211_set_disassoc(sdata, ifsta, false, true, reason);
4259 ieee80211_set_disassoc(sdata, ifsta, 0);
4260 return 0; 4283 return 0;
4261} 4284}
4262 4285