Ver Fonte

qcacld-3.0: Allow roaming between same OWE profile AP's

Currently, firmware can roam between owe security SSID's
even though open SSID is different for both of the AP's.
This commit adds support to restrict roaming between the
same OWE profile AP's which means if the device needs to
roam then target AP's open SSID and owe SSID should match
with current AP.

Change-Id: Ib59127a90cab9ee6626b018d581edbf76ad89856
CRs-Fixed: 3025667
abhinav kumar há 3 anos atrás
pai
commit
04389c608d

+ 7 - 0
components/mlme/dispatcher/inc/wlan_mlme_public_struct.h

@@ -35,6 +35,13 @@
 #define OWE_TRANSITION_OUI_TYPE "\x50\x6f\x9a\x1c"
 #define OWE_TRANSITION_OUI_SIZE 4
 
+/**
+ * EID_VENDOR| IE_LEN | OUI |OUI_TYPE| OWE transition BSSID|SSID_LEN|   SSID   |
+ *   (1)     |  (1)   | (3) |   (1)  |         (6)         |   (1)  |(SSID_LEN)|
+*/
+#define OWE_SSID_LEN_OFFSET 12
+#define OWE_SSID_OFFSET     13
+
 #define CFG_PMKID_MODES_OKC                        (0x1)
 #define CFG_PMKID_MODES_PMKSA_CACHING              (0x2)
 

+ 1 - 0
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_fw_sync.c

@@ -798,6 +798,7 @@ cm_fw_roam_sync_propagation(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id,
 	cm_if_mgr_inform_connect_complete(cm_ctx->vdev,
 					  connect_rsp->connect_status);
 	cm_inform_blm_connect_complete(cm_ctx->vdev, connect_rsp);
+	cm_update_owe_info(vdev, connect_rsp, vdev_id);
 	cm_connect_info(vdev, true, &connect_rsp->bssid, &connect_rsp->ssid,
 			connect_rsp->freq);
 	wlan_tdls_notify_sta_connect(vdev_id,

+ 96 - 0
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c

@@ -1092,6 +1092,99 @@ cm_update_mlo_score_params(struct scoring_param *req_score_params,
 }
 #endif
 
+void cm_update_owe_info(struct wlan_objmgr_vdev *vdev,
+			struct wlan_cm_connect_resp *rsp, uint8_t vdev_id)
+{
+	struct rso_config *rso_cfg;
+	struct owe_transition_mode_info *owe_info;
+	uint8_t *ie_ptr;
+	uint32_t ie_len, akm;
+	const uint8_t *owe_transition_ie = NULL;
+	uint8_t length;
+
+	rso_cfg = wlan_cm_get_rso_config(vdev);
+	if (!rso_cfg)
+		return;
+	owe_info = &rso_cfg->owe_info;
+
+	akm = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT);
+	if (!QDF_HAS_PARAM(akm, WLAN_CRYPTO_KEY_MGMT_OWE))
+		goto reset;
+
+	mlme_debug("[OWE_TRANSITION]:Update the owe open bss's ssid");
+
+	if (!rsp->connect_ies.bcn_probe_rsp.ptr ||
+	    !rsp->connect_ies.bcn_probe_rsp.len ||
+	    (rsp->connect_ies.bcn_probe_rsp.len <=
+		(sizeof(struct wlan_frame_hdr) +
+		offsetof(struct wlan_bcn_frame, ie)))) {
+		mlme_debug("invalid beacon probe rsp len %d",
+			   rsp->connect_ies.bcn_probe_rsp.len);
+		goto reset;
+	}
+
+	ie_len = (rsp->connect_ies.bcn_probe_rsp.len -
+			sizeof(struct wlan_frame_hdr) -
+			offsetof(struct wlan_bcn_frame, ie));
+	ie_ptr = (uint8_t *)(rsp->connect_ies.bcn_probe_rsp.ptr +
+			     sizeof(struct wlan_frame_hdr) +
+			     offsetof(struct wlan_bcn_frame, ie));
+
+	owe_transition_ie = wlan_get_vendor_ie_ptr_from_oui(
+				OWE_TRANSITION_OUI_TYPE,
+				OWE_TRANSITION_OUI_SIZE, ie_ptr, ie_len);
+	if (!owe_transition_ie || owe_transition_ie[1] <= OWE_SSID_OFFSET) {
+		mlme_debug("[OWE_TRANSITION]: Invalid owe transition ie");
+		goto reset;
+	}
+
+	owe_info->is_owe_transition_conn = true;
+
+	length = *(owe_transition_ie + OWE_SSID_LEN_OFFSET);
+	if (length > WLAN_SSID_MAX_LEN) {
+		mlme_debug("[OWE_TRANSITION] Invalid ssid len %d", length);
+		goto reset;
+	}
+	owe_info->ssid.length = length;
+	qdf_mem_copy(owe_info->ssid.ssid, owe_transition_ie + OWE_SSID_OFFSET,
+		     owe_info->ssid.length);
+
+	mlme_debug("[OWE_TRANSITION] open bss ssid: \"%.*s\"",
+		   owe_info->ssid.length, owe_info->ssid.ssid);
+	return;
+
+reset:
+	if (owe_info->is_owe_transition_conn)
+		owe_info->is_owe_transition_conn = false;
+
+	return;
+}
+
+/**
+ * cm_update_owe_ap_profile() - set owe ap profile
+ * @params:  roam offload scan period related parameters
+ * @rso_cfg: rso config
+ *
+ * This function is used to set OPEN SSID value when STA is connected to OWE
+ * transition AP in OWE security
+ *
+ * Return: None
+ */
+static void cm_update_owe_ap_profile(struct ap_profile_params *params,
+				     struct rso_config *rso_cfg)
+{
+	struct owe_transition_mode_info *owe_ap_profile;
+	bool is_owe_transition_conn;
+
+	owe_ap_profile = &params->owe_ap_profile;
+	is_owe_transition_conn = rso_cfg->owe_info.is_owe_transition_conn;
+	mlme_debug("set owe ap profile:%d", is_owe_transition_conn);
+	owe_ap_profile->is_owe_transition_conn = is_owe_transition_conn;
+	owe_ap_profile->ssid.length = rso_cfg->owe_info.ssid.length;
+	qdf_mem_copy(owe_ap_profile->ssid.ssid, rso_cfg->owe_info.ssid.ssid,
+		     rso_cfg->owe_info.ssid.length);
+}
+
 static void cm_update_score_params(struct wlan_objmgr_psoc *psoc,
 				   struct wlan_mlme_psoc_ext_obj *mlme_obj,
 				   struct scoring_param *req_score_params,
@@ -1378,6 +1471,9 @@ cm_roam_scan_offload_ap_profile(struct wlan_objmgr_psoc *psoc,
 	profile->rssi_abs_thresh =
 			mlme_obj->cfg.lfr.roam_rssi_abs_threshold;
 
+	if (rso_cfg->owe_info.is_owe_transition_conn)
+		cm_update_owe_ap_profile(params, rso_cfg);
+
 	cm_update_score_params(psoc, mlme_obj, &params->param, rso_cfg);
 
 	params->min_rssi_params[DEAUTH_MIN_RSSI] =

+ 12 - 0
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.h

@@ -243,4 +243,16 @@ cm_check_and_set_sae_single_pmk_cap(struct wlan_objmgr_psoc *psoc,
 bool cm_is_auth_type_11r(struct wlan_mlme_psoc_ext_obj *mlme_obj,
 			 struct wlan_objmgr_vdev *vdev,
 			 bool mdie_present);
+
+/**
+ * cm_update_owe_info() - Update owe transition mode element info
+ * @vdev: Object manager VDEV
+ * @rsp: connect resp from VDEV mgr
+ * @vdev_id: vdev id
+ *
+ * Return: none
+ */
+void cm_update_owe_info(struct wlan_objmgr_vdev *vdev,
+			struct wlan_cm_connect_resp *rsp, uint8_t vdev_id);
+
 #endif /* _WLAN_CM_ROAM_OFFLOAD_H_ */

+ 1 - 0
components/umac/mlme/connection_mgr/core/src/wlan_cm_vdev_connect.c

@@ -1344,6 +1344,7 @@ static void cm_process_connect_complete(struct wlan_objmgr_psoc *psoc,
 		cm_update_pmk_cache_ft(psoc, vdev_id);
 	}
 
+	cm_update_owe_info(vdev, rsp, vdev_id);
 	cm_csr_set_joined(vdev_id);
 	cm_csr_send_set_ie(vdev);
 

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

@@ -288,6 +288,16 @@ struct roam_synch_frame_ind {
 	uint8_t vdev_id;
 };
 
+/* struct owe_transition_mode_info - structure containing owe transition mode
+ * element info
+ * @is_owe_transition_conn: Current connection is in owe transition mode or not
+ * @ssid: ssid
+ */
+struct owe_transition_mode_info {
+	bool is_owe_transition_conn;
+	struct wlan_ssid  ssid;
+};
+
 /**
  * struct rso_config - connect config to be used to send info in
  * RSO. This is the info we dont have in VDEV or CM ctx
@@ -324,6 +334,7 @@ struct roam_synch_frame_ind {
  * @btk: btk data
  * @psk_pmk: pmk
  * @pmk_len: length of pmk
+ * @owe_info: owe ap profile info
  * @mdid: mdid info
  * @is_11r_assoc: is 11r assoc
  * @is_adaptive_11r_connection: is adaptive 11r connection
@@ -370,6 +381,7 @@ struct rso_config {
 	uint8_t psk_pmk[ROAM_SCAN_PSK_SIZE];
 	uint8_t pmk_len;
 #endif
+	struct owe_transition_mode_info owe_info;
 	struct mobility_domain_info mdid;
 	bool is_11r_assoc;
 	bool is_adaptive_11r_connection;
@@ -800,6 +812,7 @@ struct wlan_roam_triggers {
  * @param: scoring params to short candidate
  * @min_rssi_params: Min RSSI values for different roam triggers
  * @score_delta_params: Roam score delta values for different triggers
+ * @owe_ap_profile: owe ap profile info
  */
 struct ap_profile_params {
 	uint8_t vdev_id;
@@ -807,6 +820,7 @@ struct ap_profile_params {
 	struct scoring_param param;
 	struct roam_trigger_min_rssi min_rssi_params[NUM_OF_ROAM_MIN_RSSI];
 	struct roam_trigger_score_delta score_delta_param[NUM_OF_ROAM_TRIGGERS];
+	struct owe_transition_mode_info owe_ap_profile;
 };
 
 /**

+ 55 - 1
components/wmi/src/wmi_unified_roam_tlv.c

@@ -4013,10 +4013,11 @@ send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle,
 	wmi_ap_profile *profile;
 	wmi_roam_score_delta_param *score_delta_param;
 	wmi_roam_cnd_min_rssi_param *min_rssi_param;
+	wmi_owe_ap_profile *owe_ap_profile;
 	enum roam_trigger_reason trig_reason;
 
 	len = sizeof(wmi_roam_ap_profile_fixed_param) + sizeof(wmi_ap_profile);
-	len += sizeof(*score_param);
+	len += sizeof(*score_param) + WMI_TLV_HDR_SIZE;
 
 	if (!wmi_service_enabled(wmi_handle,
 			wmi_service_configure_roam_trigger_param_support)) {
@@ -4024,7 +4025,15 @@ send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle,
 		len += NUM_OF_ROAM_TRIGGERS * sizeof(*score_delta_param);
 		len += WMI_TLV_HDR_SIZE;
 		len += NUM_OF_ROAM_MIN_RSSI * sizeof(*min_rssi_param);
+	} else {
+		len += 2 * WMI_TLV_HDR_SIZE;
+	}
+
+	if (ap_profile->owe_ap_profile.is_owe_transition_conn) {
+		len += WMI_TLV_HDR_SIZE;
+		len += sizeof(*owe_ap_profile);
 	}
+
 	buf = wmi_buf_alloc(wmi_handle, len);
 	if (!buf)
 		return QDF_STATUS_E_NOMEM;
@@ -4268,7 +4277,52 @@ send_roam_scan_offload_ap_profile_cmd_tlv(wmi_unified_t wmi_handle,
 			convert_roam_trigger_reason(trig_reason);
 		min_rssi_param->candidate_min_rssi =
 			ap_profile->min_rssi_params[MIN_RSSI_2G_TO_5G_ROAM].min_rssi;
+
+		buf_ptr += sizeof(*min_rssi_param);
+	} else {
+		/* set zero TLV's for roam_score_delta_param_list */
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+			       WMITLV_GET_STRUCT_TLVLEN(0));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+
+		/* set zero TLV's for roam_cnd_min_rssi_param_list */
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+			       WMITLV_GET_STRUCT_TLVLEN(0));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+	}
+
+	/* set zero TLV's for roam_cnd_vendor_scoring_param */
+	WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+		       WMITLV_GET_STRUCT_TLVLEN(0));
+	buf_ptr += WMI_TLV_HDR_SIZE;
+
+	if (ap_profile->owe_ap_profile.is_owe_transition_conn) {
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+			       sizeof(*owe_ap_profile));
+		buf_ptr += WMI_TLV_HDR_SIZE;
+
+		owe_ap_profile = (wmi_owe_ap_profile *)buf_ptr;
+		WMITLV_SET_HDR(&owe_ap_profile->tlv_header,
+			       WMITLV_TAG_STRUC_wmi_owe_ap_profile,
+			       WMITLV_GET_STRUCT_TLVLEN(wmi_owe_ap_profile));
+
+		owe_ap_profile->open_ssid_for_owe_transition.ssid_len =
+					ap_profile->owe_ap_profile.ssid.length;
+		qdf_mem_copy(owe_ap_profile->open_ssid_for_owe_transition.ssid,
+			     ap_profile->owe_ap_profile.ssid.ssid,
+			     ap_profile->owe_ap_profile.ssid.length);
+		wmi_debug("[OWE_TRANSITION]: open ssid:%.*s",
+		      owe_ap_profile->open_ssid_for_owe_transition.ssid_len,
+		     (char *)owe_ap_profile->open_ssid_for_owe_transition.ssid);
+
+		buf_ptr += sizeof(*owe_ap_profile);
+	} else {
+		/* set zero TLV's for owe_ap_profile */
+		WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC,
+			       WMITLV_GET_STRUCT_TLVLEN(0));
+		buf_ptr += WMI_TLV_HDR_SIZE;
 	}
+
 	wmi_mtrace(WMI_ROAM_AP_PROFILE, NO_SESSION, 0);
 	status = wmi_unified_cmd_send(wmi_handle, buf,
 				      len, WMI_ROAM_AP_PROFILE);