|
@@ -316,7 +316,8 @@ static void lim_process_auth_open_system_algo(struct mac_context *mac_ctx,
|
|
|
static QDF_STATUS
|
|
|
lim_validate_mac_address_in_auth_frame(struct mac_context *mac_ctx,
|
|
|
tpSirMacMgmtHdr mac_hdr,
|
|
|
- struct qdf_mac_addr *mld_addr)
|
|
|
+ struct qdf_mac_addr *mld_addr,
|
|
|
+ uint8_t vdev_id)
|
|
|
{
|
|
|
struct wlan_objmgr_vdev *vdev;
|
|
|
|
|
@@ -329,7 +330,7 @@ lim_validate_mac_address_in_auth_frame(struct mac_context *mac_ctx,
|
|
|
return QDF_STATUS_E_ALREADY;
|
|
|
}
|
|
|
|
|
|
- if (mlo_mgr_ml_peer_exist_on_diff_ml_ctx(mac_hdr->sa, NULL))
|
|
|
+ if (mlo_mgr_ml_peer_exist_on_diff_ml_ctx(mac_hdr->sa, &vdev_id))
|
|
|
return QDF_STATUS_E_ALREADY;
|
|
|
|
|
|
if (qdf_is_macaddr_zero(mld_addr))
|
|
@@ -343,7 +344,7 @@ lim_validate_mac_address_in_auth_frame(struct mac_context *mac_ctx,
|
|
|
return QDF_STATUS_E_ALREADY;
|
|
|
}
|
|
|
|
|
|
- if (mlo_mgr_ml_peer_exist_on_diff_ml_ctx(mld_addr->bytes, NULL))
|
|
|
+ if (mlo_mgr_ml_peer_exist_on_diff_ml_ctx(mld_addr->bytes, &vdev_id))
|
|
|
return QDF_STATUS_E_ALREADY;
|
|
|
|
|
|
return QDF_STATUS_SUCCESS;
|
|
@@ -663,6 +664,73 @@ static QDF_STATUS lim_update_link_to_mld_address(struct mac_context *mac_ctx,
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
+static bool
|
|
|
+lim_check_and_trigger_pmf_sta_deletion(struct mac_context *mac,
|
|
|
+ struct pe_session *pe_session,
|
|
|
+ tpSirMacMgmtHdr mac_hdr)
|
|
|
+{
|
|
|
+ tpDphHashNode sta_ds_ptr = NULL;
|
|
|
+ tLimMlmDisassocReq *mlm_disassoc_req = NULL;
|
|
|
+ tLimMlmDeauthReq *mlm_deauth_req = NULL;
|
|
|
+ bool is_connected = true;
|
|
|
+ uint16_t associd = 0;
|
|
|
+
|
|
|
+ sta_ds_ptr = dph_lookup_hash_entry(mac, mac_hdr->sa, &associd,
|
|
|
+ &pe_session->dph.dphHashTable);
|
|
|
+ if (!sta_ds_ptr)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ mlm_disassoc_req = mac->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
|
|
|
+ if (mlm_disassoc_req &&
|
|
|
+ !qdf_mem_cmp(mac_hdr->sa, &mlm_disassoc_req->peer_macaddr.bytes,
|
|
|
+ QDF_MAC_ADDR_SIZE)) {
|
|
|
+ pe_debug("TODO:Ack pending for disassoc frame Issue del sta for "
|
|
|
+ QDF_MAC_ADDR_FMT,
|
|
|
+ QDF_MAC_ADDR_REF(mlm_disassoc_req->peer_macaddr.bytes));
|
|
|
+ lim_process_disassoc_ack_timeout(mac);
|
|
|
+ is_connected = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ mlm_deauth_req = mac->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
|
|
|
+ if (mlm_deauth_req &&
|
|
|
+ !qdf_mem_cmp(mac_hdr->sa, &mlm_deauth_req->peer_macaddr.bytes,
|
|
|
+ QDF_MAC_ADDR_SIZE)) {
|
|
|
+ pe_debug("TODO:Ack for deauth frame is pending Issue del sta for "
|
|
|
+ QDF_MAC_ADDR_FMT,
|
|
|
+ QDF_MAC_ADDR_REF(mlm_deauth_req->peer_macaddr.bytes));
|
|
|
+ lim_process_deauth_ack_timeout(mac, pe_session->vdev_id);
|
|
|
+ is_connected = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * pStaDS != NULL and is_connected = 1 means the STA is already
|
|
|
+ * connected, But SAP received the Auth from that station. For non-PMF
|
|
|
+ * connection send Deauth frame as STA will retry to connect back. The
|
|
|
+ * reason for above logic is captured in CR620403. If we silently drop
|
|
|
+ * the auth, the subsequent EAPOL exchange will fail & peer STA will
|
|
|
+ * keep trying until DUT SAP/GO gets a kickout event from FW & cleans
|
|
|
+ * up.
|
|
|
+ *
|
|
|
+ * For PMF connection the AP should not tear down or otherwise modify
|
|
|
+ * the state of the existing association until the SA-Query procedure
|
|
|
+ * determines that the original SA is invalid.
|
|
|
+ */
|
|
|
+ if (is_connected && !sta_ds_ptr->rmfEnabled) {
|
|
|
+ pe_err("STA is already connected but received auth frame"
|
|
|
+ "Send the Deauth and lim Delete Station Context"
|
|
|
+ "(associd: %d) sta mac" QDF_MAC_ADDR_FMT,
|
|
|
+ associd, QDF_MAC_ADDR_REF(mac_hdr->sa));
|
|
|
+
|
|
|
+ lim_send_deauth_mgmt_frame(mac, REASON_UNSPEC_FAILURE,
|
|
|
+ mac_hdr->sa, pe_session, false);
|
|
|
+ lim_trigger_sta_deletion(mac, sta_ds_ptr, pe_session);
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* lim_process_sae_auth_frame()-Process SAE authentication frame
|
|
|
* @mac_ctx: MAC context
|
|
@@ -687,9 +755,17 @@ static void lim_process_sae_auth_frame(struct mac_context *mac_ctx,
|
|
|
body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
|
|
|
frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
|
|
|
|
|
|
- pe_nofl_rl_info("vdev:%d SAE Auth RX type %d subtype %d from " QDF_MAC_ADDR_FMT,
|
|
|
+ auth_algo = *(uint16_t *)body_ptr;
|
|
|
+ if (frame_len >= (SAE_AUTH_STATUS_CODE_OFFSET + 2)) {
|
|
|
+ sae_auth_seq = *(uint16_t *)(body_ptr + SAE_AUTH_SEQ_NUM_OFFSET);
|
|
|
+ sae_status_code = *(uint16_t *)(body_ptr +
|
|
|
+ SAE_AUTH_STATUS_CODE_OFFSET);
|
|
|
+ }
|
|
|
+
|
|
|
+ pe_nofl_rl_info("vdev:%d SAE Auth RX type %d subtype %d trans_seq_num:%d from " QDF_MAC_ADDR_FMT,
|
|
|
pe_session->vdev_id,
|
|
|
mac_hdr->fc.type, mac_hdr->fc.subType,
|
|
|
+ sae_auth_seq,
|
|
|
QDF_MAC_ADDR_REF(mac_hdr->sa));
|
|
|
|
|
|
if (LIM_IS_STA_ROLE(pe_session) &&
|
|
@@ -702,13 +778,13 @@ static void lim_process_sae_auth_frame(struct mac_context *mac_ctx,
|
|
|
struct qdf_mac_addr peer_mld = {0};
|
|
|
|
|
|
rx_flags = RXMGMT_FLAG_EXTERNAL_AUTH;
|
|
|
- /* Add preauth node when the first SAE authentication frame
|
|
|
+ /*
|
|
|
+ * Add preauth node when the first SAE authentication frame
|
|
|
* is received and mark state as authenticating.
|
|
|
* It's not good to track SAE authentication frames with
|
|
|
* authTransactionSeqNumber as it's subjected to
|
|
|
* SAE protocol optimizations.
|
|
|
*/
|
|
|
- /* Extract pre-auth context for the STA, if any. */
|
|
|
pre_auth_node = lim_search_pre_auth_list(mac_ctx, mac_hdr->sa);
|
|
|
if (!pre_auth_node ||
|
|
|
(pre_auth_node->mlmState != eLIM_MLM_WT_SAE_AUTH_STATE)) {
|
|
@@ -730,7 +806,8 @@ static void lim_process_sae_auth_frame(struct mac_context *mac_ctx,
|
|
|
frame_len, &peer_mld);
|
|
|
status = lim_validate_mac_address_in_auth_frame(mac_ctx,
|
|
|
mac_hdr,
|
|
|
- &peer_mld);
|
|
|
+ &peer_mld,
|
|
|
+ pe_session->vdev_id);
|
|
|
if (QDF_IS_STATUS_ERROR(status)) {
|
|
|
pe_debug("Drop SAE auth, duplicate entity found");
|
|
|
return;
|
|
@@ -758,9 +835,9 @@ 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.ptr) {
|
|
|
- if (lim_is_sae_auth_algo_match(
|
|
|
- sae_retry->sae_auth.ptr, sae_retry->sae_auth.len,
|
|
|
- rx_pkt_info))
|
|
|
+ if (lim_is_sae_auth_algo_match(sae_retry->sae_auth.ptr,
|
|
|
+ sae_retry->sae_auth.len,
|
|
|
+ rx_pkt_info))
|
|
|
lim_sae_auth_cleanup_retry(mac_ctx,
|
|
|
pe_session->vdev_id);
|
|
|
}
|
|
@@ -771,22 +848,13 @@ static void lim_process_sae_auth_frame(struct mac_context *mac_ctx,
|
|
|
* So call the Connectivity logging API before address
|
|
|
* translation while forwarding the frame to userspace.
|
|
|
*/
|
|
|
- auth_algo = *(uint16_t *)body_ptr;
|
|
|
- if (frame_len >= (SAE_AUTH_STATUS_CODE_OFFSET + 2)) {
|
|
|
- sae_auth_seq =
|
|
|
- *(uint16_t *)(body_ptr +
|
|
|
- SAE_AUTH_SEQ_NUM_OFFSET);
|
|
|
- sae_status_code =
|
|
|
- *(uint16_t *)(body_ptr +
|
|
|
- SAE_AUTH_STATUS_CODE_OFFSET);
|
|
|
- }
|
|
|
-
|
|
|
wlan_connectivity_mgmt_event(
|
|
|
- mac_ctx->psoc,
|
|
|
- (struct wlan_frame_hdr *)mac_hdr, pe_session->vdev_id,
|
|
|
- sae_status_code, 0,
|
|
|
- WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info), auth_algo,
|
|
|
- sae_auth_seq, sae_auth_seq, 0, WLAN_AUTH_RESP);
|
|
|
+ mac_ctx->psoc,
|
|
|
+ (struct wlan_frame_hdr *)mac_hdr,
|
|
|
+ pe_session->vdev_id, sae_status_code, 0,
|
|
|
+ WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info),
|
|
|
+ auth_algo, sae_auth_seq, sae_auth_seq, 0,
|
|
|
+ WLAN_AUTH_RESP);
|
|
|
|
|
|
status = lim_update_link_to_mld_address(mac_ctx,
|
|
|
pe_session->vdev,
|
|
@@ -944,70 +1012,10 @@ static void lim_process_auth_frame_type1(struct mac_context *mac_ctx,
|
|
|
uint16_t associd = 0;
|
|
|
QDF_STATUS status;
|
|
|
|
|
|
- /* AuthFrame 1 */
|
|
|
- sta_ds_ptr = dph_lookup_hash_entry(mac_ctx, mac_hdr->sa,
|
|
|
- &associd, &pe_session->dph.dphHashTable);
|
|
|
- if (sta_ds_ptr) {
|
|
|
- tLimMlmDisassocReq *pMlmDisassocReq = NULL;
|
|
|
- tLimMlmDeauthReq *pMlmDeauthReq = NULL;
|
|
|
- bool is_connected = true;
|
|
|
-
|
|
|
- pMlmDisassocReq =
|
|
|
- mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDisassocReq;
|
|
|
- if (pMlmDisassocReq &&
|
|
|
- (!qdf_mem_cmp((uint8_t *) mac_hdr->sa, (uint8_t *)
|
|
|
- &pMlmDisassocReq->peer_macaddr.bytes,
|
|
|
- QDF_MAC_ADDR_SIZE))) {
|
|
|
- pe_debug("TODO:Ack for disassoc frame is pending Issue delsta for "
|
|
|
- QDF_MAC_ADDR_FMT,
|
|
|
- QDF_MAC_ADDR_REF(
|
|
|
- pMlmDisassocReq->peer_macaddr.bytes));
|
|
|
- lim_process_disassoc_ack_timeout(mac_ctx);
|
|
|
- is_connected = false;
|
|
|
- }
|
|
|
- pMlmDeauthReq =
|
|
|
- mac_ctx->lim.limDisassocDeauthCnfReq.pMlmDeauthReq;
|
|
|
- if (pMlmDeauthReq &&
|
|
|
- (!qdf_mem_cmp((uint8_t *) mac_hdr->sa, (uint8_t *)
|
|
|
- &pMlmDeauthReq->peer_macaddr.bytes,
|
|
|
- QDF_MAC_ADDR_SIZE))) {
|
|
|
- pe_debug("TODO:Ack for deauth frame is pending Issue delsta for "
|
|
|
- QDF_MAC_ADDR_FMT,
|
|
|
- QDF_MAC_ADDR_REF(
|
|
|
- pMlmDeauthReq->peer_macaddr.bytes));
|
|
|
- lim_process_deauth_ack_timeout(mac_ctx,
|
|
|
- pe_session->vdev_id);
|
|
|
- is_connected = false;
|
|
|
- }
|
|
|
+ if (lim_check_and_trigger_pmf_sta_deletion(mac_ctx, pe_session,
|
|
|
+ mac_hdr))
|
|
|
+ return;
|
|
|
|
|
|
- /*
|
|
|
- * pStaDS != NULL and is_connected = 1 means the STA is already
|
|
|
- * connected, But SAP received the Auth from that station.
|
|
|
- * For non PMF connection send Deauth frame as STA will retry
|
|
|
- * to connect back. The reason for above logic is captured in
|
|
|
- * CR620403. If we silently drop the auth, the subsequent EAPOL
|
|
|
- * exchange will fail & peer STA will keep trying until DUT
|
|
|
- * SAP/GO gets a kickout event from FW & cleans up.
|
|
|
- *
|
|
|
- * For PMF connection the AP should not tear down or otherwise
|
|
|
- * modify the state of the existing association until the
|
|
|
- * SA-Query procedure determines that the original SA is
|
|
|
- * invalid.
|
|
|
- */
|
|
|
- if (is_connected && !sta_ds_ptr->rmfEnabled) {
|
|
|
- pe_err("STA is already connected but received auth frame"
|
|
|
- "Send the Deauth and lim Delete Station Context"
|
|
|
- "(associd: %d) sta mac" QDF_MAC_ADDR_FMT,
|
|
|
- associd, QDF_MAC_ADDR_REF(mac_hdr->sa));
|
|
|
- lim_send_deauth_mgmt_frame(mac_ctx,
|
|
|
- REASON_UNSPEC_FAILURE,
|
|
|
- (uint8_t *) mac_hdr->sa,
|
|
|
- pe_session, false);
|
|
|
- lim_trigger_sta_deletion(mac_ctx, sta_ds_ptr,
|
|
|
- pe_session);
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
/* Check if there exists pre-auth context for this STA */
|
|
|
auth_node = lim_search_pre_auth_list(mac_ctx, mac_hdr->sa);
|
|
|
if (auth_node) {
|
|
@@ -1042,16 +1050,18 @@ static void lim_process_auth_frame_type1(struct mac_context *mac_ctx,
|
|
|
* SAP dphHashTable.size = 8
|
|
|
*/
|
|
|
for (associd = 0; associd < pe_session->dph.dphHashTable.size;
|
|
|
- associd++) {
|
|
|
+ associd++) {
|
|
|
sta_ds_ptr = dph_get_hash_entry(mac_ctx, associd,
|
|
|
- &pe_session->dph.dphHashTable);
|
|
|
+ &pe_session->dph.dphHashTable);
|
|
|
if (!sta_ds_ptr)
|
|
|
continue;
|
|
|
+
|
|
|
if (sta_ds_ptr->valid && (!qdf_mem_cmp(
|
|
|
(uint8_t *)&sta_ds_ptr->staAddr,
|
|
|
(uint8_t *) &(mac_hdr->sa),
|
|
|
(uint8_t) sizeof(tSirMacAddr))))
|
|
|
break;
|
|
|
+
|
|
|
sta_ds_ptr = NULL;
|
|
|
}
|
|
|
|
|
@@ -1068,9 +1078,10 @@ static void lim_process_auth_frame_type1(struct mac_context *mac_ctx,
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
maxnum_preauth = mac_ctx->mlme_cfg->lfr.max_num_pre_auth;
|
|
|
if (mac_ctx->lim.gLimNumPreAuthContexts == maxnum_preauth &&
|
|
|
- !lim_delete_open_auth_pre_auth_node(mac_ctx)) {
|
|
|
+ !lim_delete_open_auth_pre_auth_node(mac_ctx)) {
|
|
|
pe_err("Max no of preauth context reached");
|
|
|
/*
|
|
|
* Maximum number of pre-auth contexts reached.
|
|
@@ -1095,7 +1106,8 @@ static void lim_process_auth_frame_type1(struct mac_context *mac_ctx,
|
|
|
|
|
|
status = lim_validate_mac_address_in_auth_frame(mac_ctx,
|
|
|
mac_hdr,
|
|
|
- mld_addr);
|
|
|
+ mld_addr,
|
|
|
+ pe_session->vdev_id);
|
|
|
if (QDF_IS_STATUS_ERROR(status)) {
|
|
|
pe_err("Duplicate MAC address found, reject auth");
|
|
|
auth_frame->authAlgoNumber =
|