qcacld-3.0: Add support for silent deauth

Add support to facilitate silent deauthentication to peer
stations in master mode.

Change-Id: I8c92d68d7ae94d1d425bfcb6744bed84b67f1f3b
CRs-Fixed: 3070885
This commit is contained in:
Rachit Kankane
2021-07-07 17:01:39 +05:30
committed by Madan Koyyalamudi
parent 1e0bdf574a
commit 3ea99d7b08
4 changed files with 77 additions and 10 deletions

View File

@@ -1254,6 +1254,29 @@ static uint8_t hdd_son_get_rx_nss(struct wlan_objmgr_vdev *vdev)
return rx_nss; return rx_nss;
} }
static void hdd_son_deauth_sta(struct wlan_objmgr_vdev *vdev,
uint8_t *peer_mac,
bool ignore_frame)
{
struct hdd_adapter *adapter = wlan_hdd_get_adapter_from_objmgr(vdev);
struct csr_del_sta_params param;
if (!adapter) {
hdd_err("null adapter");
return;
}
qdf_mem_copy(param.peerMacAddr.bytes, peer_mac, QDF_MAC_ADDR_SIZE);
param.subtype = SIR_MAC_MGMT_DEAUTH;
param.reason_code = ignore_frame ? REASON_HOST_TRIGGERED_SILENT_DEAUTH
: REASON_UNSPEC_FAILURE;
hdd_debug("Peer - "QDF_MAC_ADDR_FMT" Ignore Frame - %u",
QDF_FULL_MAC_REF(peer_mac), ignore_frame);
if (hdd_softap_sta_deauth(adapter, &param) != QDF_STATUS_SUCCESS)
hdd_err("Error in deauthenticating peer");
}
void hdd_son_register_callbacks(struct hdd_context *hdd_ctx) void hdd_son_register_callbacks(struct hdd_context *hdd_ctx)
{ {
struct son_callbacks cb_obj = {0}; struct son_callbacks cb_obj = {0};
@@ -1277,6 +1300,7 @@ void hdd_son_register_callbacks(struct hdd_context *hdd_ctx)
cb_obj.os_if_get_rx_nss = hdd_son_get_rx_nss; cb_obj.os_if_get_rx_nss = hdd_son_get_rx_nss;
cb_obj.os_if_set_chwidth = hdd_son_set_chwidth; cb_obj.os_if_set_chwidth = hdd_son_set_chwidth;
cb_obj.os_if_get_chwidth = hdd_son_get_chwidth; cb_obj.os_if_get_chwidth = hdd_son_get_chwidth;
cb_obj.os_if_deauth_sta = hdd_son_deauth_sta;
os_if_son_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj); os_if_son_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj);
} }

View File

@@ -3901,25 +3901,38 @@ lim_send_deauth_mgmt_frame(struct mac_context *mac,
#endif #endif
uint8_t smeSessionId = 0; uint8_t smeSessionId = 0;
struct element_info *discon_ie; struct element_info *discon_ie;
bool drop_deauth = false;
if (!pe_session) { if (!pe_session) {
return; return;
} }
/* /*
* In case when cac timer is running for this SAP session then * Avoid sending deauth frame out when
* avoid deauth frame out. It is violation of dfs specification. * 1. CAC timer is running for this SAP session,
* It is avoid violation of dfs specification.
* 2. Silent deauth is requested for a particular peer
*/ */
if (((pe_session->opmode == QDF_SAP_MODE) || if ((pe_session->opmode == QDF_SAP_MODE) ||
(pe_session->opmode == QDF_P2P_GO_MODE)) && (pe_session->opmode == QDF_P2P_GO_MODE)) {
(true == mac->sap.SapDfsInfo.is_dfs_cac_timer_running)) { if (mac->sap.SapDfsInfo.is_dfs_cac_timer_running) {
QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
FL FL
("CAC timer is running, drop the deauth from going out")); ("CAC timer is running, drop the deauth from going out"));
drop_deauth = true;
}
if (nReason == REASON_HOST_TRIGGERED_SILENT_DEAUTH) {
QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO,
FL
("Silent deauth, remove the peer"));
drop_deauth = true;
}
if (drop_deauth) {
if (waitForAck) if (waitForAck)
lim_send_deauth_cnf(mac); lim_send_deauth_cnf(mac);
return; return;
} }
}
smeSessionId = pe_session->smeSessionId; smeSessionId = pe_session->smeSessionId;
qdf_mem_zero((uint8_t *) &frm, sizeof(frm)); qdf_mem_zero((uint8_t *) &frm, sizeof(frm));

View File

@@ -53,6 +53,7 @@
* @os_if_kickout_mac: kickout sta with given mac * @os_if_kickout_mac: kickout sta with given mac
* @os_if_set_chwidth: set chan width * @os_if_set_chwidth: set chan width
* @os_if_get_chwidth: get chan width * @os_if_get_chwidth: get chan width
* @os_if_deauth_sta: Deauths the target peer
*/ */
struct son_callbacks { struct son_callbacks {
uint32_t (*os_if_is_acs_in_progress)(struct wlan_objmgr_vdev *vdev); uint32_t (*os_if_is_acs_in_progress)(struct wlan_objmgr_vdev *vdev);
@@ -91,6 +92,9 @@ struct son_callbacks {
enum ieee80211_cwm_width son_chwidth); enum ieee80211_cwm_width son_chwidth);
enum ieee80211_cwm_width (*os_if_get_chwidth)( enum ieee80211_cwm_width (*os_if_get_chwidth)(
struct wlan_objmgr_vdev *vdev); struct wlan_objmgr_vdev *vdev);
void (*os_if_deauth_sta)(struct wlan_objmgr_vdev *vdev,
uint8_t *peer_mac,
bool ignore_frame);
}; };
/** /**
@@ -465,4 +469,16 @@ int os_if_son_set_chwidth(struct wlan_objmgr_vdev *vdev,
* Return: son chan width * Return: son chan width
*/ */
enum ieee80211_cwm_width os_if_son_get_chwidth(struct wlan_objmgr_vdev *vdev); enum ieee80211_cwm_width os_if_son_get_chwidth(struct wlan_objmgr_vdev *vdev);
/**
* os_if_son_deauth_peer_sta - Deauths specified STA
* @vdev: vdev
* @peer_mac: Target peer MAC address
* @ignore_frame: True to silently deauth the peer
*
* Return: void
*/
void os_if_son_deauth_peer_sta(struct wlan_objmgr_vdev *vdev,
uint8_t *peer_mac,
bool ignore_frame);
#endif #endif

View File

@@ -911,3 +911,17 @@ bool os_if_son_vdev_is_wds(struct wlan_objmgr_vdev *vdev)
} }
qdf_export_symbol(os_if_son_vdev_is_wds); qdf_export_symbol(os_if_son_vdev_is_wds);
void os_if_son_deauth_peer_sta(struct wlan_objmgr_vdev *vdev,
uint8_t *peer_mac,
bool ignore_frame)
{
if (!vdev || !peer_mac) {
osif_err("null vdev / peer_mac");
return;
}
if (g_son_os_if_cb.os_if_deauth_sta)
g_son_os_if_cb.os_if_deauth_sta(vdev, peer_mac, ignore_frame);
}
qdf_export_symbol(os_if_son_deauth_peer_sta);