From 7becf9ee3308da3a6fe22a896ebc6bd57f1b49b5 Mon Sep 17 00:00:00 2001 From: Amruta Kulkarni Date: Thu, 30 Jun 2022 17:21:13 -0700 Subject: [PATCH] qcacld-3.0: Handling of ML probe response - Validate and process the ML probe response - Drop the beacon frame if ml probe sent flag is true Change-Id: Id55cd381bab334628650e19e74044ca102f65dbc CRs-Fixed: 3237674 --- core/mac/src/pe/include/lim_api.h | 13 ++ core/mac/src/pe/lim/lim_api.c | 180 +++++++++++++----- .../mac/src/pe/lim/lim_process_beacon_frame.c | 4 + .../src/pe/lim/lim_process_probe_rsp_frame.c | 8 + 4 files changed, 154 insertions(+), 51 deletions(-) diff --git a/core/mac/src/pe/include/lim_api.h b/core/mac/src/pe/include/lim_api.h index ee70ce5795..c26f006681 100644 --- a/core/mac/src/pe/include/lim_api.h +++ b/core/mac/src/pe/include/lim_api.h @@ -588,6 +588,13 @@ lim_gen_link_specific_probe_rsp(struct mac_context *mac_ctx, uint8_t *probe_rsp, uint32_t probe_rsp_len, int32_t rssi); +/** + * lim_check_for_ml_probe_req() - check if ml probe req is sent + * @session: pe session + * + * Return qdf status + */ +QDF_STATUS lim_check_for_ml_probe_req(struct pe_session *session); #else static inline QDF_STATUS lim_gen_link_specific_probe_rsp(struct mac_context *mac_ctx, @@ -596,6 +603,12 @@ lim_gen_link_specific_probe_rsp(struct mac_context *mac_ctx, uint8_t *probe_rsp, uint32_t probe_rsp_len, int32_t rssi) +{ + return QDF_STATUS_SUCCESS; +} + +static inline QDF_STATUS +lim_check_for_ml_probe_req(struct pe_session *session) { return QDF_STATUS_E_NOSUPPORT; } diff --git a/core/mac/src/pe/lim/lim_api.c b/core/mac/src/pe/lim/lim_api.c index 36b780fb00..de6a152ed2 100644 --- a/core/mac/src/pe/lim/lim_api.c +++ b/core/mac/src/pe/lim/lim_api.c @@ -3460,6 +3460,23 @@ lim_mlo_roam_delete_link_peer(struct pe_session *pe_session, #endif #ifdef WLAN_FEATURE_11BE_MLO +static bool +lim_match_link_info(uint8_t req_link_id, + struct qdf_mac_addr *link_addr, + struct mlo_partner_info *partner_info) +{ + uint8_t i; + + for (i = 0; i < partner_info->num_partner_links; i++) { + if (partner_info->partner_link_info[i].link_id == req_link_id && + (qdf_is_macaddr_equal(link_addr, + &partner_info->partner_link_info[i].link_addr))) + return true; + } + + return false; +} + static void lim_add_bcn_probe(struct wlan_objmgr_vdev *vdev, uint8_t *bcn_probe, uint32_t len, qdf_freq_t freq, int32_t rssi) @@ -3513,6 +3530,58 @@ lim_add_bcn_probe(struct wlan_objmgr_vdev *vdev, uint8_t *bcn_probe, &rx_param, frm_type); } +static QDF_STATUS +lim_validate_probe_rsp_link_info(struct pe_session *session_entry, + uint8_t *probe_rsp, + uint32_t probe_rsp_len) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + uint8_t *ml_ie = NULL; + qdf_size_t ml_ie_total_len; + struct mlo_partner_info partner_info; + uint8_t i; + struct mlo_partner_info ml_partner_info; + + status = util_find_mlie(probe_rsp + WLAN_PROBE_RESP_IES_OFFSET, + probe_rsp_len - WLAN_PROBE_RESP_IES_OFFSET, + &ml_ie, &ml_ie_total_len); + if (QDF_IS_STATUS_ERROR(status)) { + pe_err("Mlo ie not found in Probe response"); + return status; + } + status = util_get_bvmlie_persta_partner_info(ml_ie, + ml_ie_total_len, + &partner_info); + + if (QDF_IS_STATUS_ERROR(status)) { + pe_err("Per STA profile parsing failed"); + return status; + } + + ml_partner_info = session_entry->lim_join_req->partner_info; + for (i = 0; i < partner_info.num_partner_links; i++) { + if (!lim_match_link_info(ml_partner_info.partner_link_info[i].link_id, + &ml_partner_info.partner_link_info[i].link_addr, + &partner_info)) { + pe_err("Prb req link info does not match prb resp link info"); + return QDF_STATUS_E_PROTO; + } + } + + return status; +} + +QDF_STATUS lim_check_for_ml_probe_req(struct pe_session *session) +{ + if (!session || !session->lim_join_req) + return QDF_STATUS_E_NULL_VALUE; + + if (session->lim_join_req->is_ml_probe_req_sent) + return QDF_STATUS_SUCCESS; + + return QDF_STATUS_E_FAILURE; +} + QDF_STATUS lim_gen_link_specific_probe_rsp(struct mac_context *mac_ctx, struct pe_session *session_entry, @@ -3530,62 +3599,71 @@ lim_gen_link_specific_probe_rsp(struct mac_context *mac_ctx, uint8_t op_class; uint16_t chan_freq; - if (!rcvd_probe_resp->mlo_ie.mlo_ie_present || - !session_entry->lim_join_req->is_ml_probe_req_sent) - return QDF_STATUS_SUCCESS; + if (session_entry->lim_join_req->is_ml_probe_req_sent && + rcvd_probe_resp->mlo_ie.mlo_ie_present) { - link_probe_rsp.ptr = qdf_mem_malloc(probe_rsp_len); - if (!link_probe_rsp.ptr) - return QDF_STATUS_E_NOMEM; + status = lim_validate_probe_rsp_link_info(session_entry, + probe_rsp, + probe_rsp_len); - qdf_mem_copy(&sta_link_addr, session_entry->self_mac_addr, - QDF_MAC_ADDR_SIZE); + if (QDF_IS_STATUS_ERROR(status)) + return status; - link_probe_rsp.len = probe_rsp_len; - status = util_gen_link_probe_rsp(probe_rsp, - probe_rsp_len, - sta_link_addr, - link_probe_rsp.ptr, - probe_rsp_len, - (qdf_size_t *)&link_probe_rsp.len); + link_probe_rsp.ptr = qdf_mem_malloc(probe_rsp_len); + if (!link_probe_rsp.ptr) + return QDF_STATUS_E_NOMEM; - if (QDF_IS_STATUS_ERROR(status)) { - pe_err("MLO: Link probe response generation failed %d", status); - status = QDF_STATUS_E_FAILURE; - goto end; + qdf_mem_copy(&sta_link_addr, session_entry->self_mac_addr, + QDF_MAC_ADDR_SIZE); + + link_probe_rsp.len = probe_rsp_len; + status = util_gen_link_probe_rsp(probe_rsp, + probe_rsp_len, + sta_link_addr, + link_probe_rsp.ptr, + probe_rsp_len, + (qdf_size_t *)&link_probe_rsp.len); + + if (QDF_IS_STATUS_ERROR(status)) { + pe_err("MLO: Link probe response generation failed %d", status); + status = QDF_STATUS_E_FAILURE; + goto end; + } + + partner_info = &session_entry->lim_join_req->partner_info; + if (!partner_info->num_partner_links) { + pe_err("Partner link info not available"); + status = QDF_STATUS_E_FAILURE; + goto end; + } + + /* Currently only 2 link mlo is supported */ + link_info = &partner_info->partner_link_info[0]; + wlan_get_chan_by_bssid_from_rnr(session_entry->vdev, + session_entry->cm_id, + &link_info->link_addr, + &chan, &op_class); + if (!chan) + wlan_get_chan_by_link_id_from_rnr(session_entry->vdev, + session_entry->cm_id, + link_info->link_id, + &chan, &op_class); + if (!chan) { + pe_err("Invalid link id %d link mac: " QDF_MAC_ADDR_FMT, + link_info->link_id, + QDF_MAC_ADDR_REF(link_info->link_addr.bytes)); + status = QDF_STATUS_E_FAILURE; + goto end; + } + chan_freq = wlan_reg_chan_opclass_to_freq(chan, op_class, + true); + + lim_add_bcn_probe(session_entry->vdev, link_probe_rsp.ptr, + link_probe_rsp.len, + chan_freq, rssi); + } else { + return status; } - - partner_info = &session_entry->lim_join_req->partner_info; - if (!partner_info->num_partner_links) { - pe_err("Partner link info not available"); - status = QDF_STATUS_E_FAILURE; - goto end; - } - - /* Currently only 2 link mlo is supported */ - link_info = &partner_info->partner_link_info[0]; - wlan_get_chan_by_bssid_from_rnr(session_entry->vdev, - session_entry->cm_id, - &link_info->link_addr, - &chan, &op_class); - if (!chan) - wlan_get_chan_by_link_id_from_rnr(session_entry->vdev, - session_entry->cm_id, - link_info->link_id, - &chan, &op_class); - if (!chan) { - pe_err("Invalid link id %d link mac: " QDF_MAC_ADDR_FMT, - link_info->link_id, - QDF_MAC_ADDR_REF(link_info->link_addr.bytes)); - status = QDF_STATUS_E_FAILURE; - goto end; - } - chan_freq = wlan_reg_chan_opclass_to_freq(chan, op_class, - true); - - lim_add_bcn_probe(session_entry->vdev, probe_rsp, probe_rsp_len, - chan_freq, rssi); - end: qdf_mem_free(link_probe_rsp.ptr); link_probe_rsp.len = 0; diff --git a/core/mac/src/pe/lim/lim_process_beacon_frame.c b/core/mac/src/pe/lim/lim_process_beacon_frame.c index 1e620b2a7f..29e1f1f109 100644 --- a/core/mac/src/pe/lim/lim_process_beacon_frame.c +++ b/core/mac/src/pe/lim/lim_process_beacon_frame.c @@ -223,6 +223,9 @@ lim_process_beacon_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, return; } + if (QDF_IS_STATUS_SUCCESS(lim_check_for_ml_probe_req(session))) + goto end; + lim_process_beacon_mlo(mac_ctx, session, bcn_ptr); /* @@ -279,6 +282,7 @@ lim_process_beacon_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info, lim_check_and_announce_join_success(mac_ctx, bcn_ptr, mac_hdr, session); } +end: qdf_mem_free(bcn_ptr); return; } diff --git a/core/mac/src/pe/lim/lim_process_probe_rsp_frame.c b/core/mac/src/pe/lim/lim_process_probe_rsp_frame.c index d4b8cf0372..170a788dc1 100644 --- a/core/mac/src/pe/lim/lim_process_probe_rsp_frame.c +++ b/core/mac/src/pe/lim/lim_process_probe_rsp_frame.c @@ -155,6 +155,8 @@ lim_process_probe_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_Packet_info qdf_mem_free(probe_rsp); return; } + qdf_trace_hex_dump(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_DEBUG, body, + frame_len); status = lim_gen_link_specific_probe_rsp(mac_ctx, session_entry, probe_rsp, @@ -162,6 +164,11 @@ lim_process_probe_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_Packet_info frame_len, mac_ctx->lim.bss_rssi); + if (QDF_IS_STATUS_ERROR(status)) { + pe_debug("Link specific prb rsp generation failed"); + goto end; + } + if (session_entry->limMlmState == eLIM_MLM_WT_JOIN_BEACON_STATE) { /* @@ -277,6 +284,7 @@ lim_process_probe_rsp_frame(struct mac_context *mac_ctx, uint8_t *rx_Packet_info mac_ctx, probe_rsp, session_entry); } } +end: qdf_mem_free(probe_rsp); /* Ignore Probe Response frame in all other states */