瀏覽代碼

qcacld-3.0: Set proper SSID in the external auth req

In SAE roam offload case, the SSID of the candidate is
retrieved from the roam candidate frame, and this SSID
is sent to the userspace for initiating SAE authentication.

However, if roam candidate frame is an MBSS beacon and the
candidate BSSID is present in non-tx profile, still the
SSID from tx profile is sent to the userspace, which leads
to authentication failure.

To fix this:
a) Save the BSSID in addition to the SSID during the roam
candidate frame extraction.
b) During roam auth offload event, get the SSID from the
scan cache only if the existing BSSID cache(filled in #a)
doesn't match with the BSSID received in roam offload event.

This would prevent the time expensive scan table lookup
operation for non-MBSSID cases.

Change-Id: Ib8cc0408cba7ccfc8c2b3e2d657f7b40f8a4d421
CRs-Fixed: 3437698
Surya Prakash Sivaraj 2 年之前
父節點
當前提交
d24935c6f4

+ 9 - 3
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload_event.c

@@ -614,6 +614,8 @@ cm_roam_candidate_event_handler(struct wlan_objmgr_psoc *psoc,
 	uint8_t *extracted_ie = NULL;
 	uint8_t primary_channel, band;
 	qdf_freq_t op_freq;
+	struct wlan_frame_hdr *wh;
+	struct qdf_mac_addr bssid;
 
 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, candidate->vdev_id,
 						    WLAN_MLME_CM_ID);
@@ -651,9 +653,14 @@ cm_roam_candidate_event_handler(struct wlan_objmgr_psoc *psoc,
 							   ie_ptr, ie_len);
 	if (extracted_ie && extracted_ie[0] == WLAN_ELEMID_SSID &&
 	    extracted_ie[1] > MIN_IE_LEN) {
+		wh = (struct wlan_frame_hdr *)candidate->frame;
+		WLAN_ADDR_COPY(&bssid.bytes[0], wh->i_addr2);
+
 		mlme_debug("SSID of the candidate is " QDF_SSID_FMT,
 			   QDF_SSID_REF(extracted_ie[1], &extracted_ie[2]));
-		wlan_cm_set_roam_offload_ssid(vdev, extracted_ie);
+		wlan_cm_set_roam_offload_ssid(vdev, &extracted_ie[2],
+					      extracted_ie[1]);
+		wlan_cm_get_set_roam_offload_bssid(vdev, &bssid, true);
 	}
 
 	/* For 2.4GHz,5GHz get channel from DS IE */
@@ -699,12 +706,11 @@ cm_roam_candidate_event_handler(struct wlan_objmgr_psoc *psoc,
 			goto update_beacon;
 	}
 
-	mlme_err("Primary channel was not found in the candidate scan entry");
+	mlme_err("Ignore beacon, Primary channel was not found in the candidate frame");
 	goto err;
 
 update_beacon:
 	op_freq = wlan_reg_chan_band_to_freq(pdev, primary_channel, band);
-	mlme_debug("Roaming candidate frequency : %d", op_freq);
 	cm_inform_bcn_probe(cm_ctx, candidate->frame, candidate->frame_length,
 			    op_freq,
 			    0, /* Real RSSI will be updated by Roam synch ind */

+ 49 - 3
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h

@@ -1118,16 +1118,32 @@ cm_roam_candidate_event_handler(struct wlan_objmgr_psoc *psoc,
 bool wlan_cm_is_roam_sync_in_progress(struct wlan_objmgr_psoc *psoc,
 				      uint8_t vdev_id);
 
+/**
+ * wlan_cm_get_set_roam_offload_bssid() - Get/Set the roam offload
+ * bssid of the sae roam offload params
+ * @vdev: pointer to vdev
+ * @bssid: bssid
+ * @set: true - set; false - get
+ *
+ * Return: None
+ */
+void
+wlan_cm_get_set_roam_offload_bssid(struct wlan_objmgr_vdev *vdev,
+				   struct qdf_mac_addr *bssid,
+				   bool set);
+
 /**
  * wlan_cm_set_roam_offload_ssid() - Set the roam offload candidate ssid
  *
  * @vdev: pointer to vdev
- * @ssid_ie: ssid ie of the candidate
+ * @ssid: ssid of candidate
+ * @len: length of ssid
  *
  * Return: None
  */
 void
-wlan_cm_set_roam_offload_ssid(struct wlan_objmgr_vdev *vdev, uint8_t *ssid_ie);
+wlan_cm_set_roam_offload_ssid(struct wlan_objmgr_vdev *vdev,
+			      uint8_t *ssid, uint8_t len);
 
 /**
  * wlan_cm_get_roam_offload_ssid() - Get the roam offload candidate ssid
@@ -1257,6 +1273,21 @@ void mlme_cm_free_roam_stats_info(mlme_vdev_ext_t *ext_hdl)
 }
 #endif
 
+/**
+ * wlan_cm_set_offload_ssid() - Set the roam offload ssid in mlme priv
+ *
+ * @pdev: pointer to pdev
+ * @vdev_id: vdev id
+ * @ap_bssid: roam candidate bssid
+ *
+ * Get the scan entry corresponding to the bssid and save the ssid
+ * in the mlme priv of the STA vdev
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS
+wlan_cm_set_offload_ssid(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
+			 struct qdf_mac_addr *ap_bssid);
 #else
 static inline
 void wlan_cm_roam_activate_pcl_per_vdev(struct wlan_objmgr_psoc *psoc,
@@ -1447,7 +1478,15 @@ wlan_cm_is_roam_sync_in_progress(struct wlan_objmgr_psoc *psoc,
 }
 
 static inline void
-wlan_cm_set_roam_offload_ssid(struct wlan_objmgr_vdev *vdev, uint8_t *ssid_ie)
+wlan_cm_get_set_roam_offload_bssid(struct wlan_objmgr_vdev *vdev,
+				   struct qdf_mac_addr *bssid,
+				   bool set)
+{
+}
+
+static inline void
+wlan_cm_set_roam_offload_ssid(struct wlan_objmgr_vdev *vdev,
+			      uint8_t *ssid, uint8_t len)
 {
 }
 
@@ -1485,6 +1524,13 @@ void mlme_cm_free_roam_stats_info(mlme_vdev_ext_t *ext_hdl)
 {
 }
 
+static inline QDF_STATUS
+wlan_cm_set_offload_ssid(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
+			 struct qdf_mac_addr *ap_bssid)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
 
 #ifdef WLAN_FEATURE_FIPS

+ 12 - 2
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_public_struct.h

@@ -2624,20 +2624,30 @@ struct wlan_cm_vendor_handoff_param {
 };
 #endif
 
+/**
+ * struct sae_offload_params - SAE roam auth offload related params
+ * @ssid: SSID of the roam candidate
+ * @bssid: BSSID of the roam candidate
+ */
+struct sae_offload_params {
+	struct wlan_ssid ssid;
+	struct qdf_mac_addr bssid;
+};
+
 /**
  * struct wlan_cm_roam  - Connection manager roam configs, state and roam
  * data related structure
  * @pcl_vdev_cmd_active:  Flag to check if vdev level pcl command needs to be
  * sent or PDEV level PCL command needs to be sent
  * @vendor_handoff_param: vendor handoff params
- * @sae_offload_ssid: SSID of the roam auth offload bssid
+ * @sae_offload: SAE roam offload related params
  */
 struct wlan_cm_roam {
 	bool pcl_vdev_cmd_active;
 #ifdef WLAN_VENDOR_HANDOFF_CONTROL
 	struct wlan_cm_vendor_handoff_param vendor_handoff_param;
 #endif
-	struct wlan_ssid sae_offload_ssid;
+	struct sae_offload_params sae_offload;
 };
 
 /**

+ 129 - 12
components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c

@@ -4204,10 +4204,12 @@ bool wlan_cm_is_roam_sync_in_progress(struct wlan_objmgr_psoc *psoc,
 }
 
 void
-wlan_cm_set_roam_offload_ssid(struct wlan_objmgr_vdev *vdev, uint8_t *ssid_ie)
+wlan_cm_get_set_roam_offload_bssid(struct wlan_objmgr_vdev *vdev,
+				   struct qdf_mac_addr *bssid,
+				   bool set)
 {
 	struct mlme_legacy_priv *mlme_priv;
-	uint8_t ssid_len = ssid_ie[1];
+	struct qdf_mac_addr *mlme_bssid;
 
 	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
 	if (!mlme_priv) {
@@ -4215,14 +4217,49 @@ wlan_cm_set_roam_offload_ssid(struct wlan_objmgr_vdev *vdev, uint8_t *ssid_ie)
 		return;
 	}
 
-	if (ssid_len > WLAN_SSID_MAX_LEN)
-		ssid_len = WLAN_SSID_MAX_LEN;
+	mlme_bssid = &(mlme_priv->cm_roam.sae_offload.bssid);
 
-	qdf_mem_zero(&mlme_priv->cm_roam.sae_offload_ssid,
-		     sizeof(struct wlan_ssid));
-	qdf_mem_copy(mlme_priv->cm_roam.sae_offload_ssid.ssid,
-		     &ssid_ie[2], ssid_len);
-	mlme_priv->cm_roam.sae_offload_ssid.length = ssid_len;
+	if (set) {
+		if (!bssid || qdf_is_macaddr_zero(bssid)) {
+			mlme_err("NULL BSSID");
+			return;
+		}
+		qdf_mem_copy(mlme_bssid->bytes, bssid->bytes,
+			     QDF_MAC_ADDR_SIZE);
+	} else {
+		/* Get the BSSID present in sae_offload_param */
+		if (!bssid)
+			return;
+		qdf_mem_copy(bssid->bytes, mlme_bssid->bytes,
+			     QDF_MAC_ADDR_SIZE);
+	}
+}
+
+void
+wlan_cm_set_roam_offload_ssid(struct wlan_objmgr_vdev *vdev,
+			      uint8_t *ssid, uint8_t len)
+{
+	struct mlme_legacy_priv *mlme_priv;
+	struct wlan_ssid *mlme_ssid;
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv) {
+		mlme_err("vdev legacy private object is NULL");
+		return;
+	}
+
+	mlme_ssid = &mlme_priv->cm_roam.sae_offload.ssid;
+
+	if (len > WLAN_SSID_MAX_LEN)
+		len = WLAN_SSID_MAX_LEN;
+
+	qdf_mem_zero(mlme_ssid, sizeof(struct wlan_ssid));
+	qdf_mem_copy(&mlme_ssid->ssid[0], ssid, len);
+	mlme_ssid->length = len;
+
+	mlme_debug("Set roam offload ssid: " QDF_SSID_FMT,
+		   QDF_SSID_REF(mlme_ssid->length,
+				mlme_ssid->ssid));
 }
 
 void
@@ -4231,6 +4268,7 @@ wlan_cm_get_roam_offload_ssid(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
 {
 	struct wlan_objmgr_vdev *vdev;
 	struct mlme_legacy_priv *mlme_priv;
+	struct wlan_ssid *mlme_ssid;
 
 	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
 						    WLAN_MLME_CM_ID);
@@ -4245,9 +4283,10 @@ wlan_cm_get_roam_offload_ssid(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
 		goto ret;
 	}
 
-	qdf_mem_copy(ssid, mlme_priv->cm_roam.sae_offload_ssid.ssid,
-		     mlme_priv->cm_roam.sae_offload_ssid.length);
-	*len = mlme_priv->cm_roam.sae_offload_ssid.length;
+	mlme_ssid = &mlme_priv->cm_roam.sae_offload.ssid;
+
+	qdf_mem_copy(ssid, mlme_ssid->ssid, mlme_ssid->length);
+	*len = mlme_ssid->length;
 
 ret:
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
@@ -4535,3 +4574,81 @@ bool wlan_cm_is_self_mld_roam_supported(struct wlan_objmgr_psoc *psoc)
 	return wmi_service_enabled(wmi_handle,
 				   wmi_service_self_mld_roam_between_dbs_and_hbs);
 }
+
+#ifdef WLAN_FEATURE_ROAM_OFFLOAD
+QDF_STATUS
+wlan_cm_set_offload_ssid(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
+			 struct qdf_mac_addr *ap_bssid)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct wlan_objmgr_psoc *psoc;
+	qdf_list_t *list = NULL;
+	struct scan_cache_node *first_node = NULL;
+	struct scan_filter *scan_filter;
+	struct scan_cache_entry *entry;
+	struct qdf_mac_addr cache_bssid;
+	QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+	psoc = wlan_pdev_get_psoc(pdev);
+	if (!psoc)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_MLME_OBJMGR_ID);
+	if (!vdev)
+		return QDF_STATUS_E_NULL_VALUE;
+
+	/*
+	 * sae_offload ssid, bssid would have already been cached
+	 * from the tx profile of the roam_candidate_frame from FW,
+	 * but if the roam offload is received for a non-tx BSSID,
+	 * then the ssid stored in mlme_priv would be incorrect.
+	 *
+	 * If the bssid cached in sae_offload_param doesn't match
+	 * with the bssid received in roam_offload_event, then
+	 * get the scan entry from scan table to save the proper
+	 * ssid, bssid.
+	 */
+	wlan_cm_get_set_roam_offload_bssid(vdev, &cache_bssid, false);
+	if (!qdf_mem_cmp(cache_bssid.bytes, ap_bssid->bytes, QDF_MAC_ADDR_SIZE))
+		goto end;
+
+	mlme_debug("Update the roam offload ssid from scan cache");
+
+	scan_filter = qdf_mem_malloc(sizeof(*scan_filter));
+	if (!scan_filter) {
+		status = QDF_STATUS_E_NOMEM;
+		goto end;
+	}
+
+	scan_filter->num_of_bssid = 1;
+	qdf_mem_copy(scan_filter->bssid_list[0].bytes,
+		     ap_bssid, sizeof(struct qdf_mac_addr));
+
+	list = wlan_scan_get_result(pdev, scan_filter);
+	qdf_mem_free(scan_filter);
+
+	if (!list || !qdf_list_size(list)) {
+		QDF_ASSERT(0);
+		mlme_err("Scan result is empty, candidate entry not found");
+		status = QDF_STATUS_E_FAILURE;
+		goto end;
+	}
+
+	qdf_list_peek_front(list, (qdf_list_node_t **)&first_node);
+	if (first_node && first_node->entry) {
+		entry = first_node->entry;
+		wlan_cm_set_roam_offload_ssid(vdev,
+					      &entry->ssid.ssid[0],
+					      entry->ssid.length);
+		wlan_cm_get_set_roam_offload_bssid(vdev, ap_bssid, true);
+	}
+
+end:
+	if (list)
+		wlan_scan_purge_results(list);
+
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);
+	return status;
+}
+#endif

+ 9 - 0
core/wma/src/wma_scan_roam.c

@@ -296,6 +296,15 @@ cm_handle_auth_offload(struct auth_offload_event *auth_event)
 	wlan_cm_set_sae_auth_ta(mac_ctx->pdev,
 				auth_event->vdev_id,
 				auth_event->ta);
+
+	status = wlan_cm_set_offload_ssid(mac_ctx->pdev, auth_event->vdev_id,
+					  &auth_event->ap_bssid);
+
+	if (QDF_IS_STATUS_ERROR(status)) {
+		wma_err_rl("Set offload ssid failed %d", status);
+		return QDF_STATUS_E_FAILURE;
+	}
+
 	status = wma->csr_roam_auth_event_handle_cb(mac_ctx, auth_event->vdev_id,
 						    auth_event->ap_bssid,
 						    auth_event->akm);