Ver Fonte

qcacld-3.0: Fix SAE whitelist SSID roam failure

In whitelist roaming, the roam offload event is sent
for an BSSID with different SSID, however host driver
copies the connected bssid in the external auth event
to the userspace. This leads to preauth failure.

Cache the ssid from the beacon received as part of the
roam frame event before every roam auth offload event
and use that ssid for external auth events to userspace.

Change-Id: I634992baf0c98054897707aaf3b1265e17d46f04
CRs-Fixed: 3262859
Surya Prakash Sivaraj há 2 anos atrás
pai
commit
20f32531a3

+ 0 - 17
components/mlme/core/inc/wlan_mlme_main.h

@@ -766,23 +766,6 @@ bool mlme_get_peer_pmf_status(struct wlan_objmgr_peer *peer);
 enum QDF_OPMODE wlan_get_opmode_from_vdev_id(struct wlan_objmgr_pdev *pdev,
 					     uint8_t vdev_id);
 
-/**
- * wlan_mlme_get_ssid_vdev_id() - get ssid
- * @pdev: pdev object
- * @vdev_id: vdev id
- * @ssid: SSID
- * @ssid_len: Length of SSID
- *
- * API to get the SSID of vdev id, it updates the SSID and its length
- * in @ssid, @ssid_len respectively
- *
- * Return: SUCCESS, if update is done
- *          FAILURE, if ssid length is > max ssid len
- */
-QDF_STATUS wlan_mlme_get_ssid_vdev_id(struct wlan_objmgr_pdev *pdev,
-				      uint8_t vdev_id,
-				      uint8_t *ssid, uint8_t *ssid_len);
-
 /**
  * wlan_mlme_get_bssid_vdev_id() - get bss peer mac address(BSSID) using vdev id
  * @pdev: pdev

+ 0 - 23
components/mlme/core/src/wlan_mlme_main.c

@@ -3260,29 +3260,6 @@ enum QDF_OPMODE wlan_get_opmode_from_vdev_id(struct wlan_objmgr_pdev *pdev,
 	return opmode;
 }
 
-QDF_STATUS wlan_mlme_get_ssid_vdev_id(struct wlan_objmgr_pdev *pdev,
-				      uint8_t vdev_id,
-				      uint8_t *ssid, uint8_t *ssid_len)
-{
-	struct wlan_objmgr_vdev *vdev;
-	QDF_STATUS status;
-
-	*ssid_len = 0;
-
-	if (!pdev)
-		return QDF_STATUS_E_INVAL;
-
-	vdev = wlan_objmgr_get_vdev_by_id_from_pdev(pdev, vdev_id,
-						    WLAN_LEGACY_MAC_ID);
-	if (!vdev)
-		return QDF_STATUS_E_INVAL;
-
-	status = wlan_vdev_mlme_get_ssid(vdev, ssid, ssid_len);
-	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
-
-	return status;
-}
-
 QDF_STATUS wlan_mlme_get_bssid_vdev_id(struct wlan_objmgr_pdev *pdev,
 				       uint8_t vdev_id,
 				       struct qdf_mac_addr *bss_peer_mac)

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

@@ -587,6 +587,15 @@ cm_roam_candidate_event_handler(struct wlan_objmgr_psoc *psoc,
 	ie_ptr = candidate->frame + ie_offset;
 	ie_len = candidate->frame_length - ie_offset;
 
+	extracted_ie = (uint8_t *)wlan_get_ie_ptr_from_eid(WLAN_ELEMID_SSID,
+							   ie_ptr, ie_len);
+	if (extracted_ie && extracted_ie[0] == WLAN_ELEMID_SSID &&
+	    extracted_ie[1] > MIN_IE_LEN) {
+		mlme_debug("SSID of the candidate is %.*s", extracted_ie[1],
+			   &extracted_ie[2]);
+		wlan_cm_set_roam_offload_ssid(vdev, extracted_ie);
+	}
+
 	/* For 2.4GHz,5GHz get channel from DS IE */
 	extracted_ie = (uint8_t *)wlan_get_ie_ptr_from_eid(WLAN_ELEMID_DSPARMS,
 							   ie_ptr, ie_len);

+ 38 - 0
components/umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_roam_api.h

@@ -1105,6 +1105,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_set_roam_offload_ssid() - Set the roam offload candidate ssid
+ *
+ * @vdev: pointer to vdev
+ * @ssid_ie: ssid ie of the candidate
+ *
+ * Return: None
+ */
+void
+wlan_cm_set_roam_offload_ssid(struct wlan_objmgr_vdev *vdev, uint8_t *ssid_ie);
+
+/**
+ * wlan_cm_get_roam_offload_ssid() - Get the roam offload candidate ssid
+ *
+ * @psoc: pointer to psoc
+ * @vdev_id: vdev id
+ * @ssid: ssid of the candidate
+ * @len: length of the ssid
+ *
+ * Return: None
+ */
+void
+wlan_cm_get_roam_offload_ssid(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
+			      uint8_t *ssid, uint8_t *len);
+
 #else
 static inline
 void wlan_cm_roam_activate_pcl_per_vdev(struct wlan_objmgr_psoc *psoc,
@@ -1293,6 +1319,18 @@ wlan_cm_is_roam_sync_in_progress(struct wlan_objmgr_psoc *psoc,
 {
 	return false;
 }
+
+static inline void
+wlan_cm_set_roam_offload_ssid(struct wlan_objmgr_vdev *vdev, uint8_t *ssid_ie)
+{
+}
+
+static inline void
+wlan_cm_get_roam_offload_ssid(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
+			      uint8_t *ssid, uint8_t *len)
+{
+}
+
 #endif /* WLAN_FEATURE_ROAM_OFFLOAD */
 
 #ifdef WLAN_FEATURE_FIPS

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

@@ -2387,12 +2387,14 @@ struct wlan_cm_vendor_handoff_param {
  * @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
  */
 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;
 };
 
 /**

+ 51 - 0
components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c

@@ -3542,6 +3542,57 @@ bool wlan_cm_is_roam_sync_in_progress(struct wlan_objmgr_psoc *psoc,
 
 	return ret;
 }
+
+void
+wlan_cm_set_roam_offload_ssid(struct wlan_objmgr_vdev *vdev, uint8_t *ssid_ie)
+{
+	struct mlme_legacy_priv *mlme_priv;
+	uint8_t ssid_len = ssid_ie[1];
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv) {
+		mlme_err("vdev legacy private object is NULL");
+		return;
+	}
+
+	if (ssid_len > WLAN_SSID_MAX_LEN)
+		ssid_len = WLAN_SSID_MAX_LEN;
+
+	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;
+}
+
+void
+wlan_cm_get_roam_offload_ssid(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
+			      uint8_t *ssid, uint8_t *len)
+{
+	struct wlan_objmgr_vdev *vdev;
+	struct mlme_legacy_priv *mlme_priv;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
+						    WLAN_MLME_CM_ID);
+	if (!vdev) {
+		mlme_err("VDEV is NULL");
+		return;
+	}
+
+	mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
+	if (!mlme_priv) {
+		mlme_err("vdev legacy private object is NULL");
+		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;
+
+ret:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_CM_ID);
+}
+
 #else
 QDF_STATUS
 cm_roam_stats_event_handler(struct wlan_objmgr_psoc *psoc,

+ 3 - 3
core/sme/src/csr/csr_api_roam.c

@@ -7566,9 +7566,9 @@ csr_process_roam_auth_sae_callback(struct mac_context *mac_ctx,
 
 	sae_info.msg_len = sizeof(sae_info);
 	sae_info.vdev_id = vdev_id;
-	wlan_mlme_get_ssid_vdev_id(mac_ctx->pdev, vdev_id,
-				   sae_info.ssid.ssId,
-				   &sae_info.ssid.length);
+	wlan_cm_get_roam_offload_ssid(mac_ctx->psoc, vdev_id,
+				      sae_info.ssid.ssId,
+				      &sae_info.ssid.length);
 	qdf_mem_copy(sae_info.peer_mac_addr.bytes,
 		     roam_bssid.bytes, QDF_MAC_ADDR_SIZE);