Commit 923a0e7d authored by Johannes Berg's avatar Johannes Berg Committed by Johannes Berg

cfg80211: fix bugs in new SME implementation

When splitting the SME implementation from the MLME code,
I introduced a few bugs:
 * association failures no longer sent a connect-failure event
 * getting disassociated from the AP caused deauth to be sent
   but state wasn't cleaned up, leading to warnings
 * authentication failures weren't cleaned up properly, causing
   new connection attempts to warn and fail

Fix these bugs.
Signed-off-by: default avatarJohannes Berg <johannes@sipsolutions.net>
parent a0ec570f
...@@ -34,8 +34,10 @@ struct cfg80211_conn { ...@@ -34,8 +34,10 @@ struct cfg80211_conn {
CFG80211_CONN_SCAN_AGAIN, CFG80211_CONN_SCAN_AGAIN,
CFG80211_CONN_AUTHENTICATE_NEXT, CFG80211_CONN_AUTHENTICATE_NEXT,
CFG80211_CONN_AUTHENTICATING, CFG80211_CONN_AUTHENTICATING,
CFG80211_CONN_AUTH_FAILED,
CFG80211_CONN_ASSOCIATE_NEXT, CFG80211_CONN_ASSOCIATE_NEXT,
CFG80211_CONN_ASSOCIATING, CFG80211_CONN_ASSOCIATING,
CFG80211_CONN_ASSOC_FAILED,
CFG80211_CONN_DEAUTH, CFG80211_CONN_DEAUTH,
CFG80211_CONN_CONNECTED, CFG80211_CONN_CONNECTED,
} state; } state;
...@@ -164,6 +166,8 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev) ...@@ -164,6 +166,8 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
NULL, 0, NULL, 0,
params->key, params->key_len, params->key, params->key_len,
params->key_idx, NULL, 0); params->key_idx, NULL, 0);
case CFG80211_CONN_AUTH_FAILED:
return -ENOTCONN;
case CFG80211_CONN_ASSOCIATE_NEXT: case CFG80211_CONN_ASSOCIATE_NEXT:
BUG_ON(!rdev->ops->assoc); BUG_ON(!rdev->ops->assoc);
wdev->conn->state = CFG80211_CONN_ASSOCIATING; wdev->conn->state = CFG80211_CONN_ASSOCIATING;
...@@ -188,10 +192,17 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev) ...@@ -188,10 +192,17 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
WLAN_REASON_DEAUTH_LEAVING, WLAN_REASON_DEAUTH_LEAVING,
false); false);
return err; return err;
case CFG80211_CONN_ASSOC_FAILED:
cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
NULL, 0,
WLAN_REASON_DEAUTH_LEAVING, false);
return -ENOTCONN;
case CFG80211_CONN_DEAUTH: case CFG80211_CONN_DEAUTH:
cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
NULL, 0, NULL, 0,
WLAN_REASON_DEAUTH_LEAVING, false); WLAN_REASON_DEAUTH_LEAVING, false);
/* free directly, disconnected event already sent */
cfg80211_sme_free(wdev);
return 0; return 0;
default: default:
return 0; return 0;
...@@ -371,7 +382,7 @@ bool cfg80211_sme_rx_assoc_resp(struct wireless_dev *wdev, u16 status) ...@@ -371,7 +382,7 @@ bool cfg80211_sme_rx_assoc_resp(struct wireless_dev *wdev, u16 status)
return true; return true;
} }
wdev->conn->state = CFG80211_CONN_DEAUTH; wdev->conn->state = CFG80211_CONN_ASSOC_FAILED;
schedule_work(&rdev->conn_work); schedule_work(&rdev->conn_work);
return false; return false;
} }
...@@ -383,7 +394,13 @@ void cfg80211_sme_deauth(struct wireless_dev *wdev) ...@@ -383,7 +394,13 @@ void cfg80211_sme_deauth(struct wireless_dev *wdev)
void cfg80211_sme_auth_timeout(struct wireless_dev *wdev) void cfg80211_sme_auth_timeout(struct wireless_dev *wdev)
{ {
cfg80211_sme_free(wdev); struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
if (!wdev->conn)
return;
wdev->conn->state = CFG80211_CONN_AUTH_FAILED;
schedule_work(&rdev->conn_work);
} }
void cfg80211_sme_disassoc(struct wireless_dev *wdev) void cfg80211_sme_disassoc(struct wireless_dev *wdev)
...@@ -399,7 +416,13 @@ void cfg80211_sme_disassoc(struct wireless_dev *wdev) ...@@ -399,7 +416,13 @@ void cfg80211_sme_disassoc(struct wireless_dev *wdev)
void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev) void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev)
{ {
cfg80211_sme_disassoc(wdev); struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
if (!wdev->conn)
return;
wdev->conn->state = CFG80211_CONN_ASSOC_FAILED;
schedule_work(&rdev->conn_work);
} }
static int cfg80211_sme_connect(struct wireless_dev *wdev, static int cfg80211_sme_connect(struct wireless_dev *wdev,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment