|
|
|
@ -2750,7 +2750,6 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, |
|
|
|
|
{ |
|
|
|
|
struct ieee80211_local *local = sdata->local; |
|
|
|
|
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
|
|
|
|
struct ieee80211_work *wk; |
|
|
|
|
u8 bssid[ETH_ALEN]; |
|
|
|
|
bool assoc_bss = false; |
|
|
|
|
|
|
|
|
@ -2763,30 +2762,47 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, |
|
|
|
|
assoc_bss = true; |
|
|
|
|
} else { |
|
|
|
|
bool not_auth_yet = false; |
|
|
|
|
struct ieee80211_work *tmp, *wk = NULL; |
|
|
|
|
|
|
|
|
|
mutex_unlock(&ifmgd->mtx); |
|
|
|
|
|
|
|
|
|
mutex_lock(&local->mtx); |
|
|
|
|
list_for_each_entry(wk, &local->work_list, list) { |
|
|
|
|
if (wk->sdata != sdata) |
|
|
|
|
list_for_each_entry(tmp, &local->work_list, list) { |
|
|
|
|
if (tmp->sdata != sdata) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
if (wk->type != IEEE80211_WORK_DIRECT_PROBE && |
|
|
|
|
wk->type != IEEE80211_WORK_AUTH && |
|
|
|
|
wk->type != IEEE80211_WORK_ASSOC && |
|
|
|
|
wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT) |
|
|
|
|
if (tmp->type != IEEE80211_WORK_DIRECT_PROBE && |
|
|
|
|
tmp->type != IEEE80211_WORK_AUTH && |
|
|
|
|
tmp->type != IEEE80211_WORK_ASSOC && |
|
|
|
|
tmp->type != IEEE80211_WORK_ASSOC_BEACON_WAIT) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN)) |
|
|
|
|
if (memcmp(req->bss->bssid, tmp->filter_ta, ETH_ALEN)) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
not_auth_yet = wk->type == IEEE80211_WORK_DIRECT_PROBE; |
|
|
|
|
list_del_rcu(&wk->list); |
|
|
|
|
free_work(wk); |
|
|
|
|
not_auth_yet = tmp->type == IEEE80211_WORK_DIRECT_PROBE; |
|
|
|
|
list_del_rcu(&tmp->list); |
|
|
|
|
synchronize_rcu(); |
|
|
|
|
wk = tmp; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
mutex_unlock(&local->mtx); |
|
|
|
|
|
|
|
|
|
if (wk && wk->type == IEEE80211_WORK_ASSOC) { |
|
|
|
|
/* clean up dummy sta & TX sync */ |
|
|
|
|
sta_info_destroy_addr(wk->sdata, wk->filter_ta); |
|
|
|
|
if (wk->assoc.synced) |
|
|
|
|
drv_finish_tx_sync(local, wk->sdata, |
|
|
|
|
wk->filter_ta, |
|
|
|
|
IEEE80211_TX_SYNC_ASSOC); |
|
|
|
|
} else if (wk && wk->type == IEEE80211_WORK_AUTH) { |
|
|
|
|
if (wk->probe_auth.synced) |
|
|
|
|
drv_finish_tx_sync(local, wk->sdata, |
|
|
|
|
wk->filter_ta, |
|
|
|
|
IEEE80211_TX_SYNC_AUTH); |
|
|
|
|
} |
|
|
|
|
kfree(wk); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* If somebody requests authentication and we haven't |
|
|
|
|
* sent out an auth frame yet there's no need to send |
|
|
|
|