Browse Source

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
Yeshwanth Sriram Guntuka 6 years ago
parent
commit
a6c3d27152

+ 1 - 0
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];
 };

+ 1 - 0
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

+ 4 - 1
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;

+ 85 - 3
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;
 		}