Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 86552017 authored by Johannes Berg's avatar Johannes Berg
Browse files

mac80211: send deauth only with channel context



When userspace asks to deauthenticate and we're just
authenticated (or still authenticating) send a deauth
frame instead of deleting the auth request.

On the other hand, if we've just disassociated and
therefore deleted all our state already, drop the
deauth request because we no longer have a channel
context to send it on.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 50febf6a
Loading
Loading
Loading
Loading
+18 −14
Original line number Original line Diff line number Diff line
@@ -3662,40 +3662,44 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
	u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
	u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
	bool tx = !req->local_state_change;
	bool tx = !req->local_state_change;
	bool sent_frame = false;


	mutex_lock(&ifmgd->mtx);
	mutex_lock(&ifmgd->mtx);


	if (ifmgd->auth_data) {
		ieee80211_destroy_auth_data(sdata, false);
		mutex_unlock(&ifmgd->mtx);
		return 0;
	}

	sdata_info(sdata,
	sdata_info(sdata,
		   "deauthenticating from %pM by local choice (reason=%d)\n",
		   "deauthenticating from %pM by local choice (reason=%d)\n",
		   req->bssid, req->reason_code);
		   req->bssid, req->reason_code);


	if (ifmgd->associated &&
	if (ifmgd->auth_data) {
	    ether_addr_equal(ifmgd->associated->bssid, req->bssid)) {
		ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
				       req->reason_code, tx, frame_buf);
	} else {
		drv_mgd_prepare_tx(sdata->local, sdata);
		drv_mgd_prepare_tx(sdata->local, sdata);
		ieee80211_send_deauth_disassoc(sdata, req->bssid,
		ieee80211_send_deauth_disassoc(sdata, req->bssid,
					       IEEE80211_STYPE_DEAUTH,
					       IEEE80211_STYPE_DEAUTH,
					       req->reason_code, tx,
					       req->reason_code, tx,
					       frame_buf);
					       frame_buf);
		ieee80211_destroy_auth_data(sdata, false);
		mutex_unlock(&ifmgd->mtx);

		sent_frame = tx;
		goto out;
	}
	}


	if (ifmgd->associated &&
	    ether_addr_equal(ifmgd->associated->bssid, req->bssid)) {
		ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
				       req->reason_code, tx, frame_buf);
		sent_frame = tx;
	}
	mutex_unlock(&ifmgd->mtx);
	mutex_unlock(&ifmgd->mtx);


	__cfg80211_send_deauth(sdata->dev, frame_buf,
 out:
			       IEEE80211_DEAUTH_FRAME_LEN);

	mutex_lock(&sdata->local->mtx);
	mutex_lock(&sdata->local->mtx);
	ieee80211_recalc_idle(sdata->local);
	ieee80211_recalc_idle(sdata->local);
	mutex_unlock(&sdata->local->mtx);
	mutex_unlock(&sdata->local->mtx);


	if (sent_frame)
		__cfg80211_send_deauth(sdata->dev, frame_buf,
				       IEEE80211_DEAUTH_FRAME_LEN);

	return 0;
	return 0;
}
}