summaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2015-03-01 02:10:03 -0500
committerJohannes Berg <johannes.berg@intel.com>2015-03-03 09:56:08 -0500
commitbe72afe0a43825ea357bf61f01ff8fe9938fe7d4 (patch)
treefc09a4fe3aab5d79b7529a239ccab3d1fe4d39f1 /net/mac80211/mlme.c
parentfb28ec0ce4acd54cb1972d224e2caf287b60d9c9 (diff)
mac80211: fix another suspend vs. association race
Since cfg80211 disconnects, but has no insight into the association process, it can happen that it disconnects while association is in progress. We then try to abort association in mac80211, but this is only later so the association can complete between the two. This results in removing an interface from the driver while bound to the channel context, obviously causing confusion and issues. Solve this by also checking if we're associated during quiesce and if so deauthenticating. The frame will no longer go out to the AP which is a bit unfortunate, but it'll resolve the crash (and before we would have suspended without telling the AP as well.) I'm working on a better, but more complex solution as well, which should avoid that problem. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index cf3ae9348a9d..c5f3bd6ac99e 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3985,6 +3985,34 @@ void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata)
3985 IEEE80211_DEAUTH_FRAME_LEN); 3985 IEEE80211_DEAUTH_FRAME_LEN);
3986 } 3986 }
3987 3987
3988 /* This is a bit of a hack - we should find a better and more generic
3989 * solution to this. Normally when suspending, cfg80211 will in fact
3990 * deauthenticate. However, it doesn't (and cannot) stop an ongoing
3991 * auth (not so important) or assoc (this is the problem) process.
3992 *
3993 * As a consequence, it can happen that we are in the process of both
3994 * associating and suspending, and receive an association response
3995 * after cfg80211 has checked if it needs to disconnect, but before
3996 * we actually set the flag to drop incoming frames. This will then
3997 * cause the workqueue flush to process the association response in
3998 * the suspend, resulting in a successful association just before it
3999 * tries to remove the interface from the driver, which now though
4000 * has a channel context assigned ... this results in issues.
4001 *
4002 * To work around this (for now) simply deauth here again if we're
4003 * now connected.
4004 */
4005 if (ifmgd->associated && !sdata->local->wowlan) {
4006 u8 bssid[ETH_ALEN];
4007 struct cfg80211_deauth_request req = {
4008 .reason_code = WLAN_REASON_DEAUTH_LEAVING,
4009 .bssid = bssid,
4010 };
4011
4012 memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
4013 ieee80211_mgd_deauth(sdata, &req);
4014 }
4015
3988 sdata_unlock(sdata); 4016 sdata_unlock(sdata);
3989} 4017}
3990 4018