|
@@ -2521,6 +2521,34 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
|
|
|
sdata->u.mgd.auth_data = NULL;
|
|
|
}
|
|
|
|
|
|
+static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
|
|
|
+ bool assoc)
|
|
|
+{
|
|
|
+ struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data;
|
|
|
+
|
|
|
+ sdata_assert_lock(sdata);
|
|
|
+
|
|
|
+ if (!assoc) {
|
|
|
+ /*
|
|
|
+ * we are not associated yet, the only timer that could be
|
|
|
+ * running is the timeout for the association response which
|
|
|
+ * which is not relevant anymore.
|
|
|
+ */
|
|
|
+ del_timer_sync(&sdata->u.mgd.timer);
|
|
|
+ sta_info_destroy_addr(sdata, assoc_data->bss->bssid);
|
|
|
+
|
|
|
+ eth_zero_addr(sdata->u.mgd.bssid);
|
|
|
+ ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
|
|
|
+ sdata->u.mgd.flags = 0;
|
|
|
+ mutex_lock(&sdata->local->mtx);
|
|
|
+ ieee80211_vif_release_channel(sdata);
|
|
|
+ mutex_unlock(&sdata->local->mtx);
|
|
|
+ }
|
|
|
+
|
|
|
+ kfree(assoc_data);
|
|
|
+ sdata->u.mgd.assoc_data = NULL;
|
|
|
+}
|
|
|
+
|
|
|
static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
|
|
|
struct ieee80211_mgmt *mgmt, size_t len)
|
|
|
{
|
|
@@ -2713,28 +2741,42 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
|
|
|
struct ieee80211_mgmt *mgmt, size_t len)
|
|
|
{
|
|
|
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
|
|
- const u8 *bssid = NULL;
|
|
|
- u16 reason_code;
|
|
|
+ u16 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
|
|
|
|
|
|
sdata_assert_lock(sdata);
|
|
|
|
|
|
if (len < 24 + 2)
|
|
|
return;
|
|
|
|
|
|
- if (!ifmgd->associated ||
|
|
|
- !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid))
|
|
|
- return;
|
|
|
+ if (ifmgd->associated &&
|
|
|
+ ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid)) {
|
|
|
+ const u8 *bssid = ifmgd->associated->bssid;
|
|
|
|
|
|
- bssid = ifmgd->associated->bssid;
|
|
|
+ sdata_info(sdata, "deauthenticated from %pM (Reason: %u=%s)\n",
|
|
|
+ bssid, reason_code,
|
|
|
+ ieee80211_get_reason_code_string(reason_code));
|
|
|
|
|
|
- reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
|
|
|
+ ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
|
|
|
|
|
|
- sdata_info(sdata, "deauthenticated from %pM (Reason: %u=%s)\n",
|
|
|
- bssid, reason_code, ieee80211_get_reason_code_string(reason_code));
|
|
|
+ ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false,
|
|
|
+ reason_code);
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
|
|
|
+ if (ifmgd->assoc_data &&
|
|
|
+ ether_addr_equal(mgmt->bssid, ifmgd->assoc_data->bss->bssid)) {
|
|
|
+ const u8 *bssid = ifmgd->assoc_data->bss->bssid;
|
|
|
|
|
|
- ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false, reason_code);
|
|
|
+ sdata_info(sdata,
|
|
|
+ "deauthenticated from %pM while associating (Reason: %u=%s)\n",
|
|
|
+ bssid, reason_code,
|
|
|
+ ieee80211_get_reason_code_string(reason_code));
|
|
|
+
|
|
|
+ ieee80211_destroy_assoc_data(sdata, false);
|
|
|
+
|
|
|
+ cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
|
|
|
+ return;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|
|
@@ -2814,34 +2856,6 @@ static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
|
|
|
- bool assoc)
|
|
|
-{
|
|
|
- struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data;
|
|
|
-
|
|
|
- sdata_assert_lock(sdata);
|
|
|
-
|
|
|
- if (!assoc) {
|
|
|
- /*
|
|
|
- * we are not associated yet, the only timer that could be
|
|
|
- * running is the timeout for the association response which
|
|
|
- * which is not relevant anymore.
|
|
|
- */
|
|
|
- del_timer_sync(&sdata->u.mgd.timer);
|
|
|
- sta_info_destroy_addr(sdata, assoc_data->bss->bssid);
|
|
|
-
|
|
|
- eth_zero_addr(sdata->u.mgd.bssid);
|
|
|
- ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
|
|
|
- sdata->u.mgd.flags = 0;
|
|
|
- mutex_lock(&sdata->local->mtx);
|
|
|
- ieee80211_vif_release_channel(sdata);
|
|
|
- mutex_unlock(&sdata->local->mtx);
|
|
|
- }
|
|
|
-
|
|
|
- kfree(assoc_data);
|
|
|
- sdata->u.mgd.assoc_data = NULL;
|
|
|
-}
|
|
|
-
|
|
|
static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
|
|
struct cfg80211_bss *cbss,
|
|
|
struct ieee80211_mgmt *mgmt, size_t len)
|