aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2010-03-30 02:29:31 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-03-31 14:46:42 -0400
commite69e95dbecfb73f76765cdd16dadc6219a9068e3 (patch)
tree9af5a6e3c3fbf70f9451b23e5c2f471b44672067 /net
parent17e4ec147f4939ca8c81b41b4261ec7974531381 (diff)
mac80211: Send deauth/disassoc prior to dropping STA entry
When management frame protection (IEEE 802.11w) is used, the deauthentication and disassociation frames must be protected whenever the encryption keys are configured. We were removing the STA entry and with it, the keys, just before actually sending out these frames which meant that the frames went out unprotected. The AP will drop them in such a case. Fix this by reordering the operations a bit so that sta_info_destroy_addr() gets called only after ieee80211_send_deauth_disassoc(). Signed-off-by: Jouni Malinen <j@w1.fi> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/mlme.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index de7519eb2b5d..57a3c62139e2 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -782,7 +782,8 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
782 netif_carrier_on(sdata->dev); 782 netif_carrier_on(sdata->dev);
783} 783}
784 784
785static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata) 785static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
786 bool remove_sta)
786{ 787{
787 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 788 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
788 struct ieee80211_local *local = sdata->local; 789 struct ieee80211_local *local = sdata->local;
@@ -855,7 +856,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata)
855 changed |= BSS_CHANGED_BSSID; 856 changed |= BSS_CHANGED_BSSID;
856 ieee80211_bss_info_change_notify(sdata, changed); 857 ieee80211_bss_info_change_notify(sdata, changed);
857 858
858 sta_info_destroy_addr(sdata, bssid); 859 if (remove_sta)
860 sta_info_destroy_addr(sdata, bssid);
859} 861}
860 862
861void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, 863void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
@@ -968,7 +970,7 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata)
968 970
969 printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid); 971 printk(KERN_DEBUG "Connection to AP %pM lost.\n", bssid);
970 972
971 ieee80211_set_disassoc(sdata); 973 ieee80211_set_disassoc(sdata, true);
972 ieee80211_recalc_idle(local); 974 ieee80211_recalc_idle(local);
973 mutex_unlock(&ifmgd->mtx); 975 mutex_unlock(&ifmgd->mtx);
974 /* 976 /*
@@ -1034,7 +1036,7 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1034 printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n", 1036 printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n",
1035 sdata->name, bssid, reason_code); 1037 sdata->name, bssid, reason_code);
1036 1038
1037 ieee80211_set_disassoc(sdata); 1039 ieee80211_set_disassoc(sdata, true);
1038 ieee80211_recalc_idle(sdata->local); 1040 ieee80211_recalc_idle(sdata->local);
1039 1041
1040 return RX_MGMT_CFG80211_DEAUTH; 1042 return RX_MGMT_CFG80211_DEAUTH;
@@ -1064,7 +1066,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1064 printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n", 1066 printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n",
1065 sdata->name, mgmt->sa, reason_code); 1067 sdata->name, mgmt->sa, reason_code);
1066 1068
1067 ieee80211_set_disassoc(sdata); 1069 ieee80211_set_disassoc(sdata, true);
1068 ieee80211_recalc_idle(sdata->local); 1070 ieee80211_recalc_idle(sdata->local);
1069 return RX_MGMT_CFG80211_DISASSOC; 1071 return RX_MGMT_CFG80211_DISASSOC;
1070} 1072}
@@ -1712,7 +1714,7 @@ static void ieee80211_sta_work(struct work_struct *work)
1712 printk(KERN_DEBUG "No probe response from AP %pM" 1714 printk(KERN_DEBUG "No probe response from AP %pM"
1713 " after %dms, disconnecting.\n", 1715 " after %dms, disconnecting.\n",
1714 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); 1716 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
1715 ieee80211_set_disassoc(sdata); 1717 ieee80211_set_disassoc(sdata, true);
1716 ieee80211_recalc_idle(local); 1718 ieee80211_recalc_idle(local);
1717 mutex_unlock(&ifmgd->mtx); 1719 mutex_unlock(&ifmgd->mtx);
1718 /* 1720 /*
@@ -2014,7 +2016,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2014 } 2016 }
2015 2017
2016 /* Trying to reassociate - clear previous association state */ 2018 /* Trying to reassociate - clear previous association state */
2017 ieee80211_set_disassoc(sdata); 2019 ieee80211_set_disassoc(sdata, true);
2018 } 2020 }
2019 mutex_unlock(&ifmgd->mtx); 2021 mutex_unlock(&ifmgd->mtx);
2020 2022
@@ -2118,7 +2120,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2118 2120
2119 if (ifmgd->associated == req->bss) { 2121 if (ifmgd->associated == req->bss) {
2120 bssid = req->bss->bssid; 2122 bssid = req->bss->bssid;
2121 ieee80211_set_disassoc(sdata); 2123 ieee80211_set_disassoc(sdata, true);
2122 mutex_unlock(&ifmgd->mtx); 2124 mutex_unlock(&ifmgd->mtx);
2123 } else { 2125 } else {
2124 bool not_auth_yet = false; 2126 bool not_auth_yet = false;
@@ -2175,6 +2177,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
2175 void *cookie) 2177 void *cookie)
2176{ 2178{
2177 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2179 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2180 u8 bssid[ETH_ALEN];
2178 2181
2179 mutex_lock(&ifmgd->mtx); 2182 mutex_lock(&ifmgd->mtx);
2180 2183
@@ -2192,13 +2195,15 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
2192 printk(KERN_DEBUG "%s: disassociating from %pM by local choice (reason=%d)\n", 2195 printk(KERN_DEBUG "%s: disassociating from %pM by local choice (reason=%d)\n",
2193 sdata->name, req->bss->bssid, req->reason_code); 2196 sdata->name, req->bss->bssid, req->reason_code);
2194 2197
2195 ieee80211_set_disassoc(sdata); 2198 memcpy(bssid, req->bss->bssid, ETH_ALEN);
2199 ieee80211_set_disassoc(sdata, false);
2196 2200
2197 mutex_unlock(&ifmgd->mtx); 2201 mutex_unlock(&ifmgd->mtx);
2198 2202
2199 ieee80211_send_deauth_disassoc(sdata, req->bss->bssid, 2203 ieee80211_send_deauth_disassoc(sdata, req->bss->bssid,
2200 IEEE80211_STYPE_DISASSOC, req->reason_code, 2204 IEEE80211_STYPE_DISASSOC, req->reason_code,
2201 cookie); 2205 cookie);
2206 sta_info_destroy_addr(sdata, bssid);
2202 2207
2203 ieee80211_recalc_idle(sdata->local); 2208 ieee80211_recalc_idle(sdata->local);
2204 2209