diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 24f352d8ec..a6c5743d94 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -231,16 +231,24 @@ static const int beacon_filter_extn_table[] = { (defined(CFG80211_EXTERNAL_AUTH_SUPPORT) || \ LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)) #if defined (CFG80211_SAE_AUTH_TA_ADDR_SUPPORT) +/** + * wlan_hdd_sae_copy_ta_addr() - Send TA address to supplicant + * @params: pointer to external auth params + * @adapter: pointer adapter context + * + * This API is used to copy TA address info in supplicant structure. + * + * Return: None + */ static inline void wlan_hdd_sae_copy_ta_addr(struct cfg80211_external_auth_params *params, - struct hdd_adapter *adapter, - struct sir_sae_info *sae_info) + struct hdd_adapter *adapter) { struct qdf_mac_addr ta = QDF_MAC_ADDR_ZERO_INIT; QDF_STATUS status = QDF_STATUS_SUCCESS; status = ucfg_cm_get_sae_auth_ta(adapter->hdd_ctx->pdev, - sae_info->vdev_id, + adapter->vdev_id, &ta); if (QDF_IS_STATUS_SUCCESS(status)) qdf_mem_copy(params->tx_addr, ta.bytes, QDF_MAC_ADDR_SIZE); @@ -256,12 +264,49 @@ void wlan_hdd_sae_copy_ta_addr(struct cfg80211_external_auth_params *params, #else static inline void wlan_hdd_sae_copy_ta_addr(struct cfg80211_external_auth_params *params, - struct hdd_adapter *adapter, - struct sir_sae_info *sae_info) + struct hdd_adapter *adapter) { } #endif +#if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_EXTERNAL_AUTH_MLO_SUPPORT) +/** + * wlan_hdd_sae_update_mld_addr() - Send mld address to supplicant + * @params: pointer to external auth params + * @adapter: pointer adapter context + * + * This API is used to copy MLD address info in supplicant structure. + * + * Return: QDF_STATUS + */ +static inline QDF_STATUS +wlan_hdd_sae_update_mld_addr(struct cfg80211_external_auth_params *params, + struct hdd_adapter *adapter) +{ + struct qdf_mac_addr mld_addr; + QDF_STATUS status; + + if (!wlan_vdev_mlme_is_mlo_vdev(adapter->vdev)) + return QDF_STATUS_SUCCESS; + + status = wlan_vdev_get_bss_peer_mld_mac(adapter->vdev, &mld_addr); + if (QDF_IS_STATUS_ERROR(status)) + return QDF_STATUS_E_INVAL; + + qdf_mem_copy(params->mld_addr, mld_addr.bytes, + QDF_MAC_ADDR_SIZE); + + return QDF_STATUS_SUCCESS; +} +#else +static inline QDF_STATUS +wlan_hdd_sae_update_mld_addr(struct cfg80211_external_auth_params *params, + struct hdd_adapter *adapter) +{ + return QDF_STATUS_SUCCESS; +} +#endif + /** * wlan_hdd_get_keymgmt_for_sae_akm() - Get the keymgmt OUI * corresponding to the SAE AKM type @@ -305,6 +350,7 @@ static void wlan_hdd_sae_callback(struct hdd_adapter *adapter, int flags; struct sir_sae_info *sae_info = roam_info->sae_info; struct cfg80211_external_auth_params params = {0}; + QDF_STATUS status; if (wlan_hdd_validate_context(hdd_ctx)) return; @@ -322,7 +368,10 @@ static void wlan_hdd_sae_callback(struct hdd_adapter *adapter, params.action = NL80211_EXTERNAL_AUTH_START; qdf_mem_copy(params.bssid, sae_info->peer_mac_addr.bytes, QDF_MAC_ADDR_SIZE); - wlan_hdd_sae_copy_ta_addr(¶ms, adapter, sae_info); + wlan_hdd_sae_copy_ta_addr(¶ms, adapter); + status = wlan_hdd_sae_update_mld_addr(¶ms, adapter); + if (QDF_IS_STATUS_ERROR(status)) + return; qdf_mem_copy(params.ssid.ssid, sae_info->ssid.ssId, sae_info->ssid.length); diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 982da53376..76bbd10595 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -217,6 +217,7 @@ #ifdef WLAN_FEATURE_11BE_MLO #include #endif +#include "wlan_osif_features.h" #include "wlan_vdev_mgr_ucfg_api.h" #include #include @@ -6489,6 +6490,22 @@ hdd_populate_vdev_create_params(struct hdd_adapter *adapter, } #endif +#if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_EXTERNAL_AUTH_MLO_SUPPORT) +static void +hdd_set_vdev_mlo_external_sae_auth_conversion(struct wlan_objmgr_vdev *vdev, + enum QDF_OPMODE mode) +{ + if (mode == QDF_STA_MODE || mode == QDF_SAP_MODE) + wlan_vdev_set_mlo_external_sae_auth_conversion(vdev, true); +} +#else +static inline void +hdd_set_vdev_mlo_external_sae_auth_conversion(struct wlan_objmgr_vdev *vdev, + enum QDF_OPMODE mode) +{ +} +#endif + int hdd_vdev_create(struct hdd_adapter *adapter) { QDF_STATUS status; @@ -6588,6 +6605,9 @@ int hdd_vdev_create(struct hdd_adapter *adapter) } hdd_store_nss_chains_cfg_in_vdev(adapter); + hdd_set_vdev_mlo_external_sae_auth_conversion(vdev, + adapter->device_mode); + /* Configure vdev params */ ucfg_fwol_configure_vdev_params(hdd_ctx->psoc, hdd_ctx->pdev, adapter->device_mode, adapter->vdev_id); diff --git a/core/mac/src/pe/include/lim_global.h b/core/mac/src/pe/include/lim_global.h index c3d3d6f06b..56bd6f8b09 100644 --- a/core/mac/src/pe/include/lim_global.h +++ b/core/mac/src/pe/include/lim_global.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -220,6 +220,9 @@ typedef struct tLimPreAuthNode { */ struct lim_assoc_data assoc_req; bool is_mlo_ie_present; +#ifdef WLAN_FEATURE_11BE_MLO + tSirMacAddr peer_mld; +#endif } tLimPreAuthNode, *tpLimPreAuthNode; /* Pre-authentication table definition */ diff --git a/core/mac/src/pe/lim/lim_process_auth_frame.c b/core/mac/src/pe/lim/lim_process_auth_frame.c index d98eabd053..93dff7aee0 100644 --- a/core/mac/src/pe/lim/lim_process_auth_frame.c +++ b/core/mac/src/pe/lim/lim_process_auth_frame.c @@ -320,12 +320,14 @@ static void lim_process_auth_open_system_algo(struct mac_context *mac_ctx, * @mac_ctx: MAC context * @mac_hdr: Mac header of the packet * @mlm_state: MLM state to be marked to track SAE authentication + * @peer_mld: Peer MLD address * * Return: None */ static void lim_external_auth_add_pre_auth_node(struct mac_context *mac_ctx, tpSirMacMgmtHdr mac_hdr, - tLimMlmStates mlm_state) + tLimMlmStates mlm_state, + struct qdf_mac_addr *peer_mld) { struct tLimPreAuthNode *auth_node; tpLimPreAuthTable preauth_table = &mac_ctx->lim.gLimPreAuthTimerTable; @@ -342,6 +344,10 @@ static void lim_external_auth_add_pre_auth_node(struct mac_context *mac_ctx, QDF_MAC_ADDR_REF(mac_hdr->sa)); qdf_mem_copy((uint8_t *)auth_node->peerMacAddr, mac_hdr->sa, sizeof(tSirMacAddr)); +#ifdef WLAN_FEATURE_11BE_MLO + qdf_mem_copy((uint8_t *)auth_node->peer_mld, peer_mld->bytes, + QDF_MAC_ADDR_SIZE); +#endif auth_node->mlmState = mlm_state; auth_node->authType = eSIR_AUTH_TYPE_SAE; auth_node->timestamp = qdf_mc_timer_get_system_ticks(); @@ -409,6 +415,172 @@ static bool lim_is_sae_auth_algo_match(uint8_t *queued_frame, uint16_t q_len, return false; } +#ifdef WLAN_FEATURE_11BE_MLO +/* + * lim_skip_sae_fixed_field: This API is called to parse the SAE auth frame and + * skip the SAE fixed fields + * @body_ptr: Pointer to a SAE auth frame + * @frame_len: Length of SAE auth frame + * @ie_ptr: Buffer to be searched for the Multi-Link element or the start of the + * Multi-Link element fragment sequence + * @ie_len: Length of the buffer + * + * Return: QDF_STATUS_SUCCESS in the case of success, QDF_STATUS value giving + * the reason for error in the case of failure + */ +static QDF_STATUS lim_skip_sae_fixed_field(uint8_t *body_ptr, + uint32_t frame_len, + uint8_t **ie_ptr, qdf_size_t *ie_len) +{ + uint16_t sae_status_code = 0; + uint16_t sae_group_id = 0; + + if (!body_ptr || !frame_len || !ie_ptr || !ie_len) + return QDF_STATUS_E_NULL_VALUE; + + if (frame_len < (SAE_AUTH_GROUP_ID_OFFSET + 2)) + return QDF_STATUS_E_INVAL; + + sae_status_code = *(uint16_t *)(body_ptr + SAE_AUTH_STATUS_CODE_OFFSET); + + if (sae_status_code != WLAN_SAE_STATUS_HASH_TO_ELEMENT && + sae_status_code != WLAN_SAE_STATUS_PK) + return QDF_STATUS_E_NOSUPPORT; + + sae_group_id = *(uint16_t *)(body_ptr + SAE_AUTH_GROUP_ID_OFFSET); + *ie_ptr = body_ptr + SAE_AUTH_GROUP_ID_OFFSET + 2; + *ie_len = frame_len - SAE_AUTH_GROUP_ID_OFFSET - 2; + + switch (sae_group_id) { + case SAE_GROUP_ID_19: + if (*ie_len < SAE_GROUP_19_FIXED_FIELDS_LEN) + return QDF_STATUS_E_NOSUPPORT; + + *ie_ptr = *ie_ptr + SAE_GROUP_19_FIXED_FIELDS_LEN; + *ie_len = *ie_len - SAE_GROUP_19_FIXED_FIELDS_LEN; + break; + case SAE_GROUP_ID_20: + if (*ie_len < SAE_GROUP_20_FIXED_FIELDS_LEN) + return QDF_STATUS_E_NOSUPPORT; + + *ie_ptr = *ie_ptr + SAE_GROUP_20_FIXED_FIELDS_LEN; + *ie_len = *ie_len - SAE_GROUP_20_FIXED_FIELDS_LEN; + break; + case SAE_GROUP_ID_21: + if (*ie_len < SAE_GROUP_21_FIXED_FIELDS_LEN) + return QDF_STATUS_E_NOSUPPORT; + + *ie_ptr = *ie_ptr + SAE_GROUP_21_FIXED_FIELDS_LEN; + *ie_len = *ie_len - SAE_GROUP_21_FIXED_FIELDS_LEN; + break; + default: + return QDF_STATUS_E_NOSUPPORT; + } + + if (*ie_len == 0) + return QDF_STATUS_E_NOSUPPORT; + + return QDF_STATUS_SUCCESS; +} + +/** + * lim_get_sta_mld_address: This API is called to get the STA MLD address + * from SAE 1st auth frame. + * @body_ptr: Pointer to a SAE auth frame + * @frame_len: Length of SAE auth frame + * @peer_mld: fill peer MLD address + * + * Return: void + */ +static void lim_get_sta_mld_address(uint8_t *body_ptr, uint32_t frame_len, + struct qdf_mac_addr *peer_mld) +{ + uint8_t *ie_ptr = NULL; + uint8_t *ml_ie = NULL; + qdf_size_t ml_ie_total_len = 0; + qdf_size_t ie_len = 0; + QDF_STATUS status; + + status = lim_skip_sae_fixed_field(body_ptr, frame_len, &ie_ptr, + &ie_len); + if (QDF_IS_STATUS_ERROR(status)) + return; + + status = util_find_mlie(ie_ptr, ie_len, &ml_ie, &ml_ie_total_len); + if (QDF_IS_STATUS_ERROR(status)) + return; + + util_get_bvmlie_mldmacaddr(ml_ie, ml_ie_total_len, peer_mld); +} + +/** + * lim_update_link_to_mld_address:This API is called to update SA and DA address + * @mac_ctx: Pointer to mac context + * @vdev: vdev + * @mac_hdr: Pointer to MAC management header + * + * Return: void + */ +static QDF_STATUS lim_update_link_to_mld_address(struct mac_context *mac_ctx, + struct wlan_objmgr_vdev *vdev, + tpSirMacMgmtHdr mac_hdr) +{ + struct qdf_mac_addr *self_mld_addr; + struct tLimPreAuthNode *pre_auth_node; + struct qdf_mac_addr peer_mld_addr; + enum QDF_OPMODE opmode; + QDF_STATUS status; + + if (!wlan_vdev_mlme_is_mlo_vdev(vdev) || + !wlan_vdev_get_mlo_external_sae_auth_conversion(vdev)) + return QDF_STATUS_SUCCESS; + + opmode = wlan_vdev_mlme_get_opmode(vdev); + self_mld_addr = (struct qdf_mac_addr *)wlan_vdev_mlme_get_mldaddr(vdev); + + switch (opmode) { + case QDF_SAP_MODE: + pre_auth_node = lim_search_pre_auth_list(mac_ctx, mac_hdr->sa); + if (!pre_auth_node) + return QDF_STATUS_E_INVAL; + + qdf_mem_copy(mac_hdr->sa, pre_auth_node->peer_mld, + QDF_MAC_ADDR_SIZE); + qdf_mem_copy(mac_hdr->bssId, self_mld_addr->bytes, + QDF_MAC_ADDR_SIZE); + break; + case QDF_STA_MODE: + status = wlan_vdev_get_bss_peer_mld_mac(vdev, &peer_mld_addr); + if (QDF_IS_STATUS_ERROR(status)) + return status; + + qdf_mem_copy(mac_hdr->sa, peer_mld_addr.bytes, + QDF_MAC_ADDR_SIZE); + qdf_mem_copy(mac_hdr->bssId, peer_mld_addr.bytes, + QDF_MAC_ADDR_SIZE); + break; + default: + return QDF_STATUS_SUCCESS; + } + + qdf_mem_copy(mac_hdr->da, self_mld_addr->bytes, QDF_MAC_ADDR_SIZE); + + return QDF_STATUS_SUCCESS; +} +#else +static void lim_get_sta_mld_address(uint8_t *body_ptr, uint32_t frame_len, + struct qdf_mac_addr *peer_mld) +{ +} + +static QDF_STATUS lim_update_link_to_mld_address(struct mac_context *mac_ctx, + struct wlan_objmgr_vdev *vdev, + tpSirMacMgmtHdr mac_hdr) +{ + return QDF_STATUS_SUCCESS; +} +#endif + /** * lim_process_sae_auth_frame()-Process SAE authentication frame * @mac_ctx: MAC context @@ -427,6 +599,7 @@ static void lim_process_sae_auth_frame(struct mac_context *mac_ctx, struct sae_auth_retry *sae_retry; uint16_t sae_auth_seq = 0, sae_status_code = 0; uint16_t auth_algo; + QDF_STATUS status; mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info); body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info); @@ -443,6 +616,7 @@ static void lim_process_sae_auth_frame(struct mac_context *mac_ctx, if (LIM_IS_AP_ROLE(pe_session)) { struct tLimPreAuthNode *pre_auth_node; + struct qdf_mac_addr peer_mld; rx_flags = RXMGMT_FLAG_EXTERNAL_AUTH; /* Add preauth node when the first SAE authentication frame @@ -462,8 +636,28 @@ static void lim_process_sae_auth_frame(struct mac_context *mac_ctx, QDF_MAC_ADDR_REF(mac_hdr->sa)); lim_delete_pre_auth_node(mac_ctx, mac_hdr->sa); } + /* case: when SAP receives auth SAE 1st frame with + * SA, DA and bssid as link address. Driver needs to + * get the STA MLD address and save it in preauth node + * struct for further use. + * For the 1st SAE RX frame, + * driver does not need to convert it in mld_address. + */ + lim_get_sta_mld_address(body_ptr, frame_len, + &peer_mld); lim_external_auth_add_pre_auth_node(mac_ctx, mac_hdr, - eLIM_MLM_WT_SAE_AUTH_STATE); + eLIM_MLM_WT_SAE_AUTH_STATE, + &peer_mld); + } else { + /* case: when SAP receives Auth SAE 3rd frame with + * SA, DA and bssid as link address. Needs to convert + * it into MLD address and send it userspace. + */ + status = lim_update_link_to_mld_address(mac_ctx, + pe_session->vdev, + mac_hdr); + if (QDF_IS_STATUS_ERROR(status)) + return; } } @@ -478,6 +672,12 @@ static void lim_process_sae_auth_frame(struct mac_context *mac_ctx, } if (LIM_IS_STA_ROLE(pe_session)) { + status = lim_update_link_to_mld_address(mac_ctx, + pe_session->vdev, + mac_hdr); + if (QDF_IS_STATUS_ERROR(status)) + return; + auth_algo = *(uint16_t *)body_ptr; if (frame_len >= (SAE_AUTH_STATUS_CODE_OFFSET + 2)) { sae_auth_seq = diff --git a/core/mac/src/pe/lim/lim_security_utils.c b/core/mac/src/pe/lim/lim_security_utils.c index 434ec6d5e5..ef9c369980 100644 --- a/core/mac/src/pe/lim/lim_security_utils.c +++ b/core/mac/src/pe/lim/lim_security_utils.c @@ -207,6 +207,26 @@ struct tLimPreAuthNode *lim_search_pre_auth_list(struct mac_context *mac, return pTempNode; } /*** end lim_search_pre_auth_list() ***/ +#ifdef WLAN_FEATURE_11BE_MLO +struct tLimPreAuthNode * +lim_search_pre_auth_list_by_mld_addr(struct mac_context *mac, + tSirMacAddr mldaddr) +{ + struct tLimPreAuthNode *pTempNode = mac->lim.pLimPreAuthList; + + while (pTempNode) { + if (!qdf_mem_cmp((uint8_t *)mldaddr, + (uint8_t *)&pTempNode->peer_mld, + sizeof(tSirMacAddr))) + break; + + pTempNode = pTempNode->next; + } + + return pTempNode; +} +#endif + /** * lim_delete_open_auth_pre_auth_node() - delete any stale preauth nodes * @mac_ctx: Pointer to Global MAC structure diff --git a/core/mac/src/pe/lim/lim_security_utils.h b/core/mac/src/pe/lim/lim_security_utils.h index 620f3ecc5b..869e52c65c 100644 --- a/core/mac/src/pe/lim/lim_security_utils.h +++ b/core/mac/src/pe/lim/lim_security_utils.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2011-2015, 2017-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -57,6 +58,22 @@ void lim_init_pre_auth_list(struct mac_context *); void lim_delete_pre_auth_list(struct mac_context *); struct tLimPreAuthNode *lim_search_pre_auth_list(struct mac_context *, tSirMacAddr); + +#ifdef WLAN_FEATURE_11BE_MLO +/** + * lim_search_pre_auth_list_by_mld_addr() - This function is called when + * Authentication frame is received by AP (or at a STA in IBSS supporting MAC + * based authentication) to search using MLD address if a STA is in the middle + * of MAC Authentication transaction sequence. + * @mac: MAC context + * @mldaddr: MLD address of the STA that sent + * + * Return: Pointer to pre-auth node if found, else NULL + */ +struct tLimPreAuthNode *lim_search_pre_auth_list_by_mld_addr( + struct mac_context *mac, + tSirMacAddr mldaddr); +#endif void lim_add_pre_auth_node(struct mac_context *, struct tLimPreAuthNode *); void lim_delete_pre_auth_node(struct mac_context *, tSirMacAddr); void lim_release_pre_auth_node(struct mac_context *mac, diff --git a/core/mac/src/pe/lim/lim_send_management_frames.c b/core/mac/src/pe/lim/lim_send_management_frames.c index 33941013ea..7ad7e97b64 100644 --- a/core/mac/src/pe/lim/lim_send_management_frames.c +++ b/core/mac/src/pe/lim/lim_send_management_frames.c @@ -6687,6 +6687,65 @@ lim_handle_sae_auth_retry(struct mac_context *mac_ctx, uint8_t vdev_id, } } +#ifdef WLAN_FEATURE_11BE_MLO +static QDF_STATUS lim_update_mld_to_link_address(struct mac_context *mac_ctx, + struct wlan_objmgr_vdev *vdev, + tpSirMacMgmtHdr mac_hdr) +{ + struct qdf_mac_addr *self_link_addr; + struct tLimPreAuthNode *pre_auth_node; + struct qdf_mac_addr peer_link_addr; + enum QDF_OPMODE opmode; + QDF_STATUS status; + + if (!wlan_vdev_mlme_is_mlo_vdev(vdev) || + !wlan_vdev_get_mlo_external_sae_auth_conversion(vdev)) + return QDF_STATUS_SUCCESS; + + opmode = wlan_vdev_mlme_get_opmode(vdev); + self_link_addr = (struct qdf_mac_addr *) + wlan_vdev_mlme_get_linkaddr(vdev); + + switch (opmode) { + case QDF_SAP_MODE: + pre_auth_node = + lim_search_pre_auth_list_by_mld_addr(mac_ctx, + mac_hdr->da); + if (!pre_auth_node) + return QDF_STATUS_E_INVAL; + + qdf_mem_copy(mac_hdr->da, pre_auth_node->peerMacAddr, + QDF_MAC_ADDR_SIZE); + qdf_mem_copy(mac_hdr->bssId, self_link_addr->bytes, + QDF_MAC_ADDR_SIZE); + break; + case QDF_STA_MODE: + status = wlan_vdev_get_bss_peer_mac(vdev, &peer_link_addr); + if (QDF_IS_STATUS_ERROR(status)) + return status; + + qdf_mem_copy(mac_hdr->da, peer_link_addr.bytes, + QDF_MAC_ADDR_SIZE); + qdf_mem_copy(mac_hdr->bssId, peer_link_addr.bytes, + QDF_MAC_ADDR_SIZE); + break; + default: + return QDF_STATUS_SUCCESS; + } + + qdf_mem_copy(mac_hdr->sa, self_link_addr->bytes, QDF_MAC_ADDR_SIZE); + + return QDF_STATUS_SUCCESS; +} +#else +static QDF_STATUS lim_update_mld_to_link_address(struct mac_context *mac_ctx, + struct wlan_objmgr_vdev *vdev, + tpSirMacMgmtHdr mac_hdr) +{ + return QDF_STATUS_SUCCESS; +} +#endif + void lim_send_frame(struct mac_context *mac_ctx, uint8_t vdev_id, uint8_t *buf, uint16_t buf_len) { @@ -6695,9 +6754,27 @@ void lim_send_frame(struct mac_context *mac_ctx, uint8_t vdev_id, uint8_t *buf, void *packet; tpSirMacFrameCtl fc = (tpSirMacFrameCtl)buf; tpSirMacMgmtHdr mac_hdr = (tpSirMacMgmtHdr)buf; + struct wlan_objmgr_vdev *vdev; + QDF_STATUS status; - pe_debug("sending fc->type: %d fc->subType: %d", - fc->type, fc->subType); + pe_debug("sending fc->type: %d fc->subType: %d", fc->type, fc->subType); + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac_ctx->psoc, vdev_id, + WLAN_LEGACY_MAC_ID); + if (!vdev) + return; + + /* Case: + * 1. In case of SAP, userspace will send MLD addresses in 2nd and 4th + * SAE auth frames. Driver needs to convert it into link address. + * 2. In case of STA, userspace will send MLD addresses in 1st and 3rd + * SAE auth frames. Driver needs to convert it into link address. + */ + status = lim_update_mld_to_link_address(mac_ctx, vdev, mac_hdr); + wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID); + + if (QDF_IS_STATUS_ERROR(status)) + return; lim_add_mgmt_seq_num(mac_ctx, mac_hdr); qdf_status = cds_packet_alloc(buf_len, (void **)&frame, diff --git a/core/mac/src/pe/lim/lim_types.h b/core/mac/src/pe/lim/lim_types.h index 505e819f0e..ac2c5a53c3 100644 --- a/core/mac/src/pe/lim/lim_types.h +++ b/core/mac/src/pe/lim/lim_types.h @@ -53,6 +53,18 @@ #define SAE_AUTH_SEQ_NUM_OFFSET 2 #define SAE_AUTH_STATUS_CODE_OFFSET 4 +#define SAE_AUTH_GROUP_ID_OFFSET 6 + +#define SAE_GROUP_ID_19 19 +#define SAE_GROUP_ID_20 20 +#define SAE_GROUP_ID_21 21 + +#define SAE_GROUP_19_FIXED_FIELDS_LEN 96 +#define SAE_GROUP_20_FIXED_FIELDS_LEN 144 +#define SAE_GROUP_21_FIXED_FIELDS_LEN 198 + +#define WLAN_SAE_STATUS_HASH_TO_ELEMENT 126 +#define WLAN_SAE_STATUS_PK 127 /* MLM message types */ enum mlmmsgtype {