mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-12 15:49:17 -04:00
qcacld-3.0: Add support for sae auth retry
Host retransmits WPA3 SAE authentication frames after 1 second if there is no response for previous auth frames from AP. Host keep retransmitting SAE auth frames for max WLAN_SAE_AUTH_RETRY times. Change-Id: I1be0bd5354586518781876646b063592e667b0bb CRs-Fixed: 2716719
This commit is contained in:
parent
e28544d9ee
commit
e5b5a03aeb
8 changed files with 237 additions and 31 deletions
|
|
@ -59,6 +59,16 @@ struct wlan_disconnect_info {
|
|||
bool from_ap;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sae_auth_retry - SAE auth retry Information
|
||||
* @sae_auth_max_retry: Max number of sae auth retries
|
||||
* @sae_auth: SAE auth frame information
|
||||
*/
|
||||
struct sae_auth_retry {
|
||||
uint8_t sae_auth_max_retry;
|
||||
struct wlan_ies sae_auth;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct peer_mlme_priv_obj - peer MLME component object
|
||||
* @last_pn_valid if last PN is valid
|
||||
|
|
@ -147,6 +157,7 @@ struct wlan_mlme_roam {
|
|||
* @vdev_stop_type: vdev stop type request
|
||||
* @roam_off_state: Roam offload state
|
||||
* @bigtk_vdev_support: BIGTK feature support for this vdev (SAP)
|
||||
* @sae_auth_retry: SAE auth retry information
|
||||
*/
|
||||
struct mlme_legacy_priv {
|
||||
bool chan_switch_in_progress;
|
||||
|
|
@ -165,6 +176,7 @@ struct mlme_legacy_priv {
|
|||
uint32_t vdev_stop_type;
|
||||
struct wlan_mlme_roam mlme_roam;
|
||||
bool bigtk_vdev_support;
|
||||
struct sae_auth_retry sae_retry;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -270,6 +282,22 @@ struct wlan_mlme_psoc_ext_obj *mlme_get_psoc_ext_obj_fl(struct wlan_objmgr_psoc
|
|||
const char *func,
|
||||
uint32_t line);
|
||||
|
||||
/**
|
||||
* mlme_get_sae_auth_retry() - Get sae_auth_retry pointer
|
||||
* @vdev: vdev pointer
|
||||
*
|
||||
* Return: Pointer to struct sae_auth_retry or NULL
|
||||
*/
|
||||
struct sae_auth_retry *mlme_get_sae_auth_retry(struct wlan_objmgr_vdev *vdev);
|
||||
|
||||
/**
|
||||
* mlme_free_sae_auth_retry() - Free the SAE auth info
|
||||
* @vdev: vdev pointer
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void mlme_free_sae_auth_retry(struct wlan_objmgr_vdev *vdev);
|
||||
|
||||
/**
|
||||
* mlme_set_self_disconnect_ies() - Set diconnect IEs configured from userspace
|
||||
* @vdev: vdev pointer
|
||||
|
|
|
|||
|
|
@ -2253,6 +2253,36 @@ QDF_STATUS mlme_cfg_on_psoc_enable(struct wlan_objmgr_psoc *psoc)
|
|||
return status;
|
||||
}
|
||||
|
||||
struct sae_auth_retry *mlme_get_sae_auth_retry(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
struct mlme_legacy_priv *mlme_priv;
|
||||
|
||||
mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
|
||||
if (!mlme_priv) {
|
||||
mlme_legacy_err("vdev legacy private object is NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &mlme_priv->sae_retry;
|
||||
}
|
||||
|
||||
void mlme_free_sae_auth_retry(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
struct mlme_legacy_priv *mlme_priv;
|
||||
|
||||
mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
|
||||
if (!mlme_priv) {
|
||||
mlme_legacy_err("vdev legacy private object is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
mlme_priv->sae_retry.sae_auth_max_retry = 0;
|
||||
if (mlme_priv->sae_retry.sae_auth.data)
|
||||
qdf_mem_free(mlme_priv->sae_retry.sae_auth.data);
|
||||
mlme_priv->sae_retry.sae_auth.data = NULL;
|
||||
mlme_priv->sae_retry.sae_auth.len = 0;
|
||||
}
|
||||
|
||||
void mlme_set_self_disconnect_ies(struct wlan_objmgr_vdev *vdev,
|
||||
struct wlan_ies *ie)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -973,6 +973,7 @@ QDF_STATUS vdevmgr_mlme_ext_hdl_destroy(struct vdev_mlme_obj *vdev_mlme)
|
|||
|
||||
mlme_free_self_disconnect_ies(vdev_mlme->vdev);
|
||||
mlme_free_peer_disconnect_ies(vdev_mlme->vdev);
|
||||
mlme_free_sae_auth_retry(vdev_mlme->vdev);
|
||||
qdf_mem_free(vdev_mlme->ext_vdev_ptr);
|
||||
vdev_mlme->ext_vdev_ptr = NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -338,6 +338,22 @@ static void lim_external_auth_add_pre_auth_node(struct mac_context *mac_ctx,
|
|||
lim_add_pre_auth_node(mac_ctx, auth_node);
|
||||
}
|
||||
|
||||
void lim_sae_auth_cleanup_retry(struct mac_context *mac_ctx,
|
||||
uint8_t vdev_id)
|
||||
{
|
||||
struct pe_session *pe_session;
|
||||
|
||||
pe_session = pe_find_session_by_vdev_id(mac_ctx, vdev_id);
|
||||
if (!pe_session) {
|
||||
pe_err("session not found for given vdev_id %d", vdev_id);
|
||||
return;
|
||||
}
|
||||
|
||||
pe_debug("sae auth cleanup for vdev_id %d", vdev_id);
|
||||
lim_deactivate_and_change_timer(mac_ctx, eLIM_AUTH_RETRY_TIMER);
|
||||
mlme_free_sae_auth_retry(pe_session->vdev);
|
||||
}
|
||||
|
||||
/**
|
||||
* lim_process_sae_auth_frame()-Process SAE authentication frame
|
||||
* @mac_ctx: MAC context
|
||||
|
|
@ -353,6 +369,7 @@ static void lim_process_sae_auth_frame(struct mac_context *mac_ctx,
|
|||
uint32_t frame_len;
|
||||
uint8_t *body_ptr;
|
||||
enum rxmgmt_flags rx_flags = RXMGMT_FLAG_NONE;
|
||||
struct sae_auth_retry *sae_retry;
|
||||
|
||||
mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
|
||||
body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
|
||||
|
|
@ -389,6 +406,12 @@ static void lim_process_sae_auth_frame(struct mac_context *mac_ctx,
|
|||
}
|
||||
}
|
||||
|
||||
sae_retry = mlme_get_sae_auth_retry(pe_session->vdev);
|
||||
if (LIM_IS_STA_ROLE(pe_session) && sae_retry &&
|
||||
sae_retry->sae_auth.data)
|
||||
lim_sae_auth_cleanup_retry(mac_ctx,
|
||||
pe_session->vdev_id);
|
||||
|
||||
lim_send_sme_mgmt_frame_ind(mac_ctx, mac_hdr->fc.subType,
|
||||
(uint8_t *)mac_hdr,
|
||||
frame_len + sizeof(tSirMacMgmtHdr),
|
||||
|
|
|
|||
|
|
@ -1627,6 +1627,36 @@ static void lim_process_periodic_join_probe_req_timer(struct mac_context *mac_ct
|
|||
}
|
||||
}
|
||||
|
||||
static void lim_handle_sae_auth_timeout(struct mac_context *mac_ctx,
|
||||
struct pe_session *session_entry)
|
||||
{
|
||||
struct sae_auth_retry *sae_retry;
|
||||
|
||||
sae_retry = mlme_get_sae_auth_retry(session_entry->vdev);
|
||||
if (!(sae_retry && sae_retry->sae_auth.data)) {
|
||||
pe_debug("sae auth frame is not buffered vdev id %d",
|
||||
session_entry->vdev_id);
|
||||
return;
|
||||
}
|
||||
|
||||
pe_debug("retry sae auth for seq num %d vdev id %d",
|
||||
mac_ctx->mgmtSeqNum, session_entry->vdev_id);
|
||||
lim_send_frame(mac_ctx, session_entry->vdev_id,
|
||||
sae_retry->sae_auth.data, sae_retry->sae_auth.len);
|
||||
|
||||
sae_retry->sae_auth_max_retry--;
|
||||
/* Activate Auth Retry timer if max_retries are not done */
|
||||
if (!sae_retry->sae_auth_max_retry || (tx_timer_activate(
|
||||
&mac_ctx->lim.lim_timers.g_lim_periodic_auth_retry_timer) !=
|
||||
TX_SUCCESS))
|
||||
goto free_and_deactivate_timer;
|
||||
|
||||
return;
|
||||
|
||||
free_and_deactivate_timer:
|
||||
lim_sae_auth_cleanup_retry(mac_ctx, session_entry->vdev_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* lim_process_auth_retry_timer()- function to Retry Auth when auth timeout
|
||||
* occurs
|
||||
|
|
@ -1639,15 +1669,19 @@ static void lim_process_auth_retry_timer(struct mac_context *mac_ctx)
|
|||
struct pe_session *session_entry;
|
||||
tAniAuthType auth_type;
|
||||
tLimTimers *lim_timers = &mac_ctx->lim.lim_timers;
|
||||
uint16_t vdev_id =
|
||||
uint16_t pe_session_id =
|
||||
lim_timers->g_lim_periodic_auth_retry_timer.sessionId;
|
||||
|
||||
session_entry = pe_find_session_by_session_id(mac_ctx, vdev_id);
|
||||
session_entry = pe_find_session_by_session_id(mac_ctx, pe_session_id);
|
||||
if (!session_entry) {
|
||||
pe_err("session does not exist for vdev_id: %d", vdev_id);
|
||||
pe_err("session does not exist for pe_session_id: %d",
|
||||
pe_session_id);
|
||||
return;
|
||||
}
|
||||
|
||||
/** For WPA3 SAE gLimAuthFailureTimer is not running hence
|
||||
* we don't enter in below "if" block in case of wpa3 sae
|
||||
*/
|
||||
if (tx_timer_running(&mac_ctx->lim.lim_timers.gLimAuthFailureTimer) &&
|
||||
(session_entry->limMlmState == eLIM_MLM_WT_AUTH_FRAME2_STATE) &&
|
||||
(LIM_AUTH_ACK_RCD_SUCCESS != mac_ctx->auth_ack_status)) {
|
||||
|
|
@ -1684,12 +1718,14 @@ static void lim_process_auth_retry_timer(struct mac_context *mac_ctx)
|
|||
/* Activate Auth Retry timer */
|
||||
if (tx_timer_activate
|
||||
(&mac_ctx->lim.lim_timers.g_lim_periodic_auth_retry_timer)
|
||||
!= TX_SUCCESS) {
|
||||
!= TX_SUCCESS)
|
||||
pe_err("could not activate Auth Retry failure timer");
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
|
||||
/* Auth retry time out for wpa3 sae */
|
||||
lim_handle_sae_auth_timeout(mac_ctx, session_entry);
|
||||
} /*** lim_process_auth_retry_timer() ***/
|
||||
|
||||
void lim_process_auth_failure_timeout(struct mac_context *mac_ctx)
|
||||
|
|
|
|||
|
|
@ -5294,28 +5294,28 @@ error_delba:
|
|||
return qdf_status;
|
||||
}
|
||||
|
||||
#define WLAN_SAE_AUTH_TIMEOUT 1000
|
||||
#define WLAN_SAE_AUTH_RETRY 1
|
||||
|
||||
/**
|
||||
* lim_tx_mgmt_frame() - Transmits Auth mgmt frame
|
||||
* @mac_ctx Pointer to Global MAC structure
|
||||
* @mb_msg: Received message info
|
||||
* @vdev_id: vdev id
|
||||
* @msg_len: Received message length
|
||||
* @packet: Packet to be transmitted
|
||||
* @frame: Received frame
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static void lim_tx_mgmt_frame(struct mac_context *mac_ctx,
|
||||
struct sir_mgmt_msg *mb_msg, uint32_t msg_len,
|
||||
void *packet, uint8_t *frame)
|
||||
static void lim_tx_mgmt_frame(struct mac_context *mac_ctx, uint8_t vdev_id,
|
||||
uint32_t msg_len, void *packet, uint8_t *frame)
|
||||
{
|
||||
tpSirMacFrameCtl fc = (tpSirMacFrameCtl) mb_msg->data;
|
||||
tpSirMacFrameCtl fc = (tpSirMacFrameCtl)frame;
|
||||
QDF_STATUS qdf_status;
|
||||
uint8_t vdev_id = 0;
|
||||
struct pe_session *session;
|
||||
uint16_t auth_ack_status;
|
||||
enum rateid min_rid = RATEID_DEFAULT;
|
||||
|
||||
vdev_id = mb_msg->vdev_id;
|
||||
session = pe_find_session_by_vdev_id(mac_ctx, vdev_id);
|
||||
if (!session) {
|
||||
cds_packet_free((void *)packet);
|
||||
|
|
@ -5349,35 +5349,99 @@ static void lim_tx_mgmt_frame(struct mac_context *mac_ctx,
|
|||
}
|
||||
}
|
||||
|
||||
void lim_send_mgmt_frame_tx(struct mac_context *mac_ctx,
|
||||
struct scheduler_msg *msg)
|
||||
static void
|
||||
lim_handle_sae_auth_retry(struct mac_context *mac_ctx, uint8_t vdev_id,
|
||||
uint8_t *frame, uint32_t frame_len)
|
||||
{
|
||||
struct pe_session *session;
|
||||
struct sae_auth_retry *sae_retry;
|
||||
|
||||
session = pe_find_session_by_vdev_id(mac_ctx, vdev_id);
|
||||
if (!session) {
|
||||
pe_err("session not found for given vdev_id %d",
|
||||
vdev_id);
|
||||
return;
|
||||
}
|
||||
|
||||
sae_retry = mlme_get_sae_auth_retry(session->vdev);
|
||||
if (!sae_retry) {
|
||||
pe_err("sae retry pointer is NULL for vdev_id %d",
|
||||
vdev_id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sae_retry->sae_auth.data)
|
||||
lim_sae_auth_cleanup_retry(mac_ctx, vdev_id);
|
||||
|
||||
sae_retry->sae_auth.data = qdf_mem_malloc(frame_len);
|
||||
if (!sae_retry->sae_auth.data) {
|
||||
pe_err("failed to alloc memory for sae auth");
|
||||
return;
|
||||
}
|
||||
|
||||
pe_debug("SAE auth frame queued vdev_id %d seq_num %d",
|
||||
vdev_id, mac_ctx->mgmtSeqNum);
|
||||
qdf_mem_copy(sae_retry->sae_auth.data, frame, frame_len);
|
||||
mac_ctx->lim.lim_timers.g_lim_periodic_auth_retry_timer.sessionId =
|
||||
session->peSessionId;
|
||||
sae_retry->sae_auth.len = frame_len;
|
||||
sae_retry->sae_auth_max_retry = WLAN_SAE_AUTH_RETRY;
|
||||
|
||||
tx_timer_change(
|
||||
&mac_ctx->lim.lim_timers.g_lim_periodic_auth_retry_timer,
|
||||
SYS_MS_TO_TICKS(WLAN_SAE_AUTH_TIMEOUT), 0);
|
||||
/* Activate Auth Retry timer */
|
||||
if (tx_timer_activate(
|
||||
&mac_ctx->lim.lim_timers.g_lim_periodic_auth_retry_timer) !=
|
||||
TX_SUCCESS) {
|
||||
pe_err("failed to start periodic auth retry timer");
|
||||
lim_sae_auth_cleanup_retry(mac_ctx, vdev_id);
|
||||
}
|
||||
}
|
||||
|
||||
void lim_send_frame(struct mac_context *mac_ctx, uint8_t vdev_id, uint8_t *buf,
|
||||
uint16_t buf_len)
|
||||
{
|
||||
struct sir_mgmt_msg *mb_msg = (struct sir_mgmt_msg *)msg->bodyptr;
|
||||
uint32_t msg_len;
|
||||
tpSirMacFrameCtl fc = (tpSirMacFrameCtl) mb_msg->data;
|
||||
uint8_t vdev_id;
|
||||
QDF_STATUS qdf_status;
|
||||
uint8_t *frame;
|
||||
void *packet;
|
||||
tpSirMacMgmtHdr mac_hdr;
|
||||
tpSirMacFrameCtl fc = (tpSirMacFrameCtl)buf;
|
||||
tpSirMacMgmtHdr mac_hdr = (tpSirMacMgmtHdr)buf;
|
||||
|
||||
msg_len = mb_msg->msg_len - sizeof(*mb_msg);
|
||||
pe_debug("sending fc->type: %d fc->subType: %d",
|
||||
fc->type, fc->subType);
|
||||
|
||||
vdev_id = mb_msg->vdev_id;
|
||||
mac_hdr = (tpSirMacMgmtHdr)mb_msg->data;
|
||||
fc->type, fc->subType);
|
||||
|
||||
lim_add_mgmt_seq_num(mac_ctx, mac_hdr);
|
||||
|
||||
qdf_status = cds_packet_alloc((uint16_t) msg_len, (void **)&frame,
|
||||
(void **)&packet);
|
||||
qdf_status = cds_packet_alloc(buf_len, (void **)&frame,
|
||||
(void **)&packet);
|
||||
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
|
||||
pe_err("call to bufAlloc failed for AUTH frame");
|
||||
return;
|
||||
}
|
||||
|
||||
qdf_mem_copy(frame, mb_msg->data, msg_len);
|
||||
|
||||
lim_tx_mgmt_frame(mac_ctx, mb_msg, msg_len, packet, frame);
|
||||
qdf_mem_copy(frame, buf, buf_len);
|
||||
lim_tx_mgmt_frame(mac_ctx, vdev_id, buf_len, packet, frame);
|
||||
}
|
||||
|
||||
void lim_send_mgmt_frame_tx(struct mac_context *mac_ctx,
|
||||
struct scheduler_msg *msg)
|
||||
{
|
||||
struct sir_mgmt_msg *mb_msg = (struct sir_mgmt_msg *)msg->bodyptr;
|
||||
uint32_t msg_len;
|
||||
tpSirMacFrameCtl fc = (tpSirMacFrameCtl)mb_msg->data;
|
||||
uint8_t vdev_id;
|
||||
uint16_t auth_algo;
|
||||
|
||||
msg_len = mb_msg->msg_len - sizeof(*mb_msg);
|
||||
vdev_id = mb_msg->vdev_id;
|
||||
|
||||
if (fc->subType == SIR_MAC_MGMT_AUTH) {
|
||||
auth_algo = *(uint16_t *)(mb_msg->data +
|
||||
sizeof(tSirMacMgmtHdr));
|
||||
if (auth_algo == eSIR_AUTH_TYPE_SAE)
|
||||
lim_handle_sae_auth_retry(mac_ctx, vdev_id,
|
||||
mb_msg->data, msg_len);
|
||||
}
|
||||
|
||||
lim_send_frame(mac_ctx, vdev_id, mb_msg->data, msg_len);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -803,6 +803,7 @@ void pe_delete_session(struct mac_context *mac_ctx, struct pe_session *session)
|
|||
QDF_MAC_ADDR_ARRAY(session->bssId));
|
||||
|
||||
lim_reset_bcn_probe_filter(mac_ctx, session);
|
||||
lim_sae_auth_cleanup_retry(mac_ctx, session->vdev_id);
|
||||
|
||||
/* Restore default failure timeout */
|
||||
if (session->defaultAuthFailureTimeout) {
|
||||
|
|
|
|||
|
|
@ -420,6 +420,17 @@ bool lim_fill_lim_assoc_ind_params(
|
|||
tpDphHashNode sta_ds,
|
||||
struct pe_session *session_entry);
|
||||
|
||||
/**
|
||||
* lim_sae_auth_cleanup_retry() - API to cleanup sae auth frmae stored
|
||||
* and deactivate the timer
|
||||
* @mac_ctx: Pointer to mac context
|
||||
* @vdev_id: vdev id
|
||||
*
|
||||
* Return: none
|
||||
*/
|
||||
void lim_sae_auth_cleanup_retry(struct mac_context *mac_ctx,
|
||||
uint8_t vdev_id);
|
||||
|
||||
/**
|
||||
* lim_fill_sme_assoc_ind_params() - Initialize association indication
|
||||
* @mac_ctx: Pointer to Global MAC structure
|
||||
|
|
@ -1220,6 +1231,18 @@ void lim_process_auth_failure_timeout(struct mac_context *mac_ctx);
|
|||
void lim_process_assoc_failure_timeout(struct mac_context *mac_ctx,
|
||||
uint32_t msg_type);
|
||||
|
||||
/**
|
||||
* lim_send_frame() - API to send frame
|
||||
* @mac_ctx Pointer to Global MAC structure
|
||||
* @vdev_id: vdev id
|
||||
* @buf: Pointer to SAE auth retry frame
|
||||
* @buf_len: length of frame
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void lim_send_frame(struct mac_context *mac_ctx, uint8_t vdev_id, uint8_t *buf,
|
||||
uint16_t buf_len);
|
||||
|
||||
/**
|
||||
* lim_send_mgmt_frame_tx() - Sends mgmt frame
|
||||
* @mac_ctx Pointer to Global MAC structure
|
||||
|
|
|
|||
Loading…
Reference in a new issue