From a6c3d271524f87f2da98d426b5951dd3159f5aa7 Mon Sep 17 00:00:00 2001 From: Yeshwanth Sriram Guntuka Date: Sat, 13 Apr 2019 12:25:53 +0530 Subject: [PATCH] qcacld-3.0: Do not send unicast probe req on assoc disallowed Unicast probe requests are sent to AP even though beacons or probe responses from AP contain MBO IE with assoc disallowed bit set. In another scenario where AP rejects association with retry delay of 60 secs, unicast probe requests are being sent to AP as part of scan for ssid during connection within the retry delay. Fix is to reject connection when assoc disallowed bit is set in MBO IE and also not trigger scan for ssid when get_scan_results fails due to rssi reject. Change-Id: I855cf397ff7e3869fb1eceeddc1db5d109790465 CRs-Fixed: 2433740 --- core/mac/inc/sir_api.h | 1 + core/mac/inc/sir_mac_prot_def.h | 1 + core/sme/src/csr/csr_api_roam.c | 5 +- core/sme/src/csr/csr_api_scan.c | 88 +++++++++++++++++++++++++++++++-- 4 files changed, 91 insertions(+), 4 deletions(-) diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index e229071c8467..2aa599b9a84a 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -663,6 +663,7 @@ struct bss_description { #ifdef WLAN_FEATURE_FILS_SK struct fils_ind_elements fils_info_element; #endif + uint32_t assoc_disallowed; /* Please keep the structure 4 bytes aligned above the ieFields */ uint32_t ieFields[1]; }; diff --git a/core/mac/inc/sir_mac_prot_def.h b/core/mac/inc/sir_mac_prot_def.h index 9823b3d74166..ac3a16cbc494 100644 --- a/core/mac/inc/sir_mac_prot_def.h +++ b/core/mac/inc/sir_mac_prot_def.h @@ -315,6 +315,7 @@ /* MBO OUI definitions */ #define SIR_MAC_MBO_OUI "\x50\x6f\x9a\x16" #define SIR_MAC_MBO_OUI_SIZE 4 +#define SIR_MBO_ELEM_OFFSET (2 + SIR_MAC_MBO_OUI_SIZE) /* min size of wme oui header: oui(3) + type + subtype + version */ #define SIR_MAC_OUI_WME_HDR_MIN 6 diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index 05f4325b1d1e..9292e43da59e 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -8129,7 +8129,7 @@ QDF_STATUS csr_roam_connect(struct mac_context *mac, uint32_t sessionId, status); fCallCallback = true; } - } else { + } else if (status != QDF_STATUS_E_EXISTS) { /* scan for this SSID */ status = csr_scan_for_ssid(mac, sessionId, pProfile, roamId, true); @@ -8140,6 +8140,9 @@ QDF_STATUS csr_roam_connect(struct mac_context *mac, uint32_t sessionId, } else { sme_debug("SSID scan requested"); } + } else { + sme_debug("Scan entries removed either due to rssi reject or assoc disallowed"); + fCallCallback = true; } } else { fCallCallback = true; diff --git a/core/sme/src/csr/csr_api_scan.c b/core/sme/src/csr/csr_api_scan.c index 5bfe57de8362..a0997acb96a4 100644 --- a/core/sme/src/csr/csr_api_scan.c +++ b/core/sme/src/csr/csr_api_scan.c @@ -2532,6 +2532,38 @@ static void csr_update_bss_with_fils_data(struct mac_context *mac_ctx, { } #endif +/** + * csr_is_assoc_disallowed() - Find if assoc disallowed + * bit is set in AP's beacon or probe response + * @mac_ctx: mac context + * @scan_entry: scan entry + * + * Return: True if assoc disallowed is set else false + */ +static bool csr_is_assoc_disallowed(struct mac_context *mac_ctx, + struct scan_cache_entry *scan_entry) +{ + int ret; + tDot11fIEMBO_IE mbo_ie = {0}; + uint8_t *mbo_oce; + + mbo_oce = util_scan_entry_mbo_oce(scan_entry); + + if (!mbo_oce) + return false; + + ret = dot11f_unpack_ie_MBO_IE(mac_ctx, mbo_oce + SIR_MBO_ELEM_OFFSET, + *(mbo_oce + 1) - SIR_MAC_MBO_OUI_SIZE, + &mbo_ie, false); + + if (DOT11F_FAILED(ret)) { + sme_err("unpack failed ret: 0x%x", ret); + return false; + } + + return mbo_ie.assoc_disallowed.present; +} + static QDF_STATUS csr_fill_bss_from_scan_entry(struct mac_context *mac_ctx, struct scan_cache_entry *scan_entry, struct tag_csrscan_result **p_result) @@ -2619,6 +2651,8 @@ static QDF_STATUS csr_fill_bss_from_scan_entry(struct mac_context *mac_ctx, MGMT_SUBTYPE_PROBE_RESP); bss_desc->seq_ctrl = hdr->seqControl; bss_desc->tsf_delta = scan_entry->tsf_delta; + bss_desc->assoc_disallowed = csr_is_assoc_disallowed(mac_ctx, + scan_entry); qdf_mem_copy(&bss_desc->mbssid_info, &scan_entry->mbssid_info, sizeof(struct scan_mbssid_info)); @@ -2817,6 +2851,42 @@ static void csr_filter_ap_due_to_rssi_reject(struct mac_context *mac_ctx, } } +/** + * csr_remove_ap_with_assoc_disallowed() - Remove APs with assoc + * disallowed bit set + * @mac_ctx: mac context + * @scan_list: candidate list for the connection + * + * Return: None + */ +static void csr_remove_ap_with_assoc_disallowed(struct mac_context *mac_ctx, + struct scan_result_list *scan_list) +{ + tListElem *cur_entry; + tListElem *next_entry; + struct tag_csrscan_result *scan_res; + + if (!scan_list) + return; + + cur_entry = csr_ll_peek_head(&scan_list->List, LL_ACCESS_NOLOCK); + while (cur_entry) { + scan_res = GET_BASE_ADDR(cur_entry, struct tag_csrscan_result, + Link); + next_entry = csr_ll_next(&scan_list->List, cur_entry, + LL_ACCESS_NOLOCK); + + if (!mac_ctx->ignore_assoc_disallowed && + scan_res->Result.BssDescriptor.assoc_disallowed) { + csr_ll_remove_entry(&scan_list->List, cur_entry, + LL_ACCESS_NOLOCK); + csr_free_scan_result_entry(mac_ctx, scan_res); + } + cur_entry = next_entry; + next_entry = NULL; + } +} + QDF_STATUS csr_scan_get_result(struct mac_context *mac_ctx, tCsrScanResultFilter *pFilter, tScanResultHandle *results) @@ -2826,6 +2896,7 @@ QDF_STATUS csr_scan_get_result(struct mac_context *mac_ctx, qdf_list_t *list = NULL; struct scan_filter *filter = NULL; struct wlan_objmgr_pdev *pdev = NULL; + uint32_t num_bss; if (results) *results = CSR_INVALID_SCANRESULT_HANDLE; @@ -2872,19 +2943,30 @@ QDF_STATUS csr_scan_get_result(struct mac_context *mac_ctx, ret_list->pCurEntry = NULL; status = csr_parse_scan_list(mac_ctx, ret_list, list); + num_bss = csr_ll_count(&ret_list->List); sme_debug("status: %d No of BSS: %d", - status, csr_ll_count(&ret_list->List)); + status, num_bss); if (QDF_IS_STATUS_ERROR(status) || !results) /* Fail or No one wants the result. */ csr_scan_result_purge(mac_ctx, (tScanResultHandle) ret_list); else { - if (pFilter) + if (pFilter) { csr_filter_ap_due_to_rssi_reject(mac_ctx, ret_list); + csr_remove_ap_with_assoc_disallowed(mac_ctx, ret_list); + } if (!csr_ll_count(&ret_list->List)) { /* This mean that there is no match */ csr_ll_close(&ret_list->List); qdf_mem_free(ret_list); - status = QDF_STATUS_E_NULL_VALUE; + /* + * Do not trigger scan for ssid if the scan entries + * are removed either due to rssi reject or assoc + * disallowed. + */ + if (num_bss) + status = QDF_STATUS_E_EXISTS; + else + status = QDF_STATUS_E_NULL_VALUE; } else if (results) { *results = ret_list; }