diff options
-rw-r--r-- | net/mac80211/mlme.c | 85 |
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 | ||
442 | static 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 | |||
454 | void ieee80211_sta_tx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, | 440 | void 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 | ||
833 | static 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 | ||
848 | static int ieee80211_privacy_mismatch(struct ieee80211_sub_if_data *sdata, | 878 | static 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 | ||