فهرست منبع

qcacmn: Add MLD addr filter in link VDEV candidate selection

Wireless environment may have APs with same BSSID but different
MLD address and if any APs BSSID is similar to the current
candidates affiliated partner link BSSID, then receiving beacon
or probe resp from such APs will override the affiliated link's
scan entry and the MLD address may be different or NULL if the
AP is non-ML.

If link VDEV connection starts and during candidate selection
it may find the scan entry of this other AP and attempt to drive
connection will lead to creating ML link VDEV's peer with
different MLD address than assoc VDEV's peer.

Enhance scan filter to match MLD address for link VDEV to avoid
such scan entry override.

Change-Id: I11c9b4efdf2d60e92482b296d731d613a200bf0e
CRs-Fixed: 3668326
Vinod Kumar Pirla 1 سال پیش
والد
کامیت
da11474ac2

+ 9 - 2
umac/mlme/connection_mgr/core/src/wlan_cm_connect.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2012-2015, 2020-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -1420,9 +1420,16 @@ static QDF_STATUS cm_update_mlo_filter(struct wlan_objmgr_pdev *pdev,
 	psoc = wlan_pdev_get_psoc(pdev);
 	filter->band_bitmap = wlan_mlme_get_sta_mlo_conn_band_bmp(psoc);
 	/* Apply assoc band filter only for assoc link */
-	if (cm_req->req.is_non_assoc_link)
+	if (cm_req->req.is_non_assoc_link) {
 		filter->band_bitmap =
 			filter->band_bitmap | CFG_MLO_ASSOC_LINK_BAND_MAX;
+		/* Only select entry which matches MLD address filter for
+		 * link VDEV connect, to avoid assoc/link VDEV selecting
+		 * candidates with different MLD address.
+		 */
+		filter->match_mld_addr = true;
+		qdf_copy_macaddr(&filter->mld_addr, &cm_req->req.mld_addr);
+	}
 
 	mlme_debug(CM_PREFIX_FMT "band bitmap: 0x%x",
 		   CM_PREFIX_REF(cm_req->req.vdev_id, cm_req->cm_id),

+ 4 - 1
umac/mlme/connection_mgr/dispatcher/inc/wlan_cm_public_struct.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2012-2015,2020-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -233,6 +233,8 @@ enum wlan_cm_source {
  * @vht_caps_mask: mask of valid vht caps
  * @fils_info: Fills related connect info
  * @is_non_assoc_link: non assoc link
+ * @mld_addr: MLD address of candidate
+ *              -mandatory and only used for link VDEV connect
  * @ml_parnter_info: ml partner link info
  */
 struct wlan_cm_connect_req {
@@ -262,6 +264,7 @@ struct wlan_cm_connect_req {
 #endif
 	bool is_non_assoc_link;
 #ifdef WLAN_FEATURE_11BE_MLO
+	struct qdf_mac_addr mld_addr;
 	struct mlo_partner_info ml_parnter_info;
 #endif
 };

+ 26 - 9
umac/mlo_mgr/src/wlan_mlo_mgr_link_switch.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -723,14 +723,18 @@ QDF_STATUS mlo_mgr_link_switch_start_connect(struct wlan_objmgr_vdev *vdev)
 	struct mlo_link_info *mlo_link_info;
 	uint8_t *vdev_mac;
 	struct wlan_mlo_sta *sta_ctx;
-	struct wlan_mlo_link_switch_req *req =
-					&vdev->mlo_dev_ctx->link_ctx->last_req;
+	struct qdf_mac_addr mld_addr;
+	struct wlan_mlo_dev_context *mlo_dev_ctx = vdev->mlo_dev_ctx;
+	struct wlan_mlo_link_switch_req *req = &mlo_dev_ctx->link_ctx->last_req;
+	struct wlan_objmgr_vdev *assoc_vdev = wlan_mlo_get_assoc_link_vdev(vdev);
 
-	sta_ctx = vdev->mlo_dev_ctx->sta_ctx;
+	if (!assoc_vdev) {
+		mlo_err("Assoc VDEV not found");
+		goto out;
+	}
 
-	mlo_link_info =
-		mlo_mgr_get_ap_link_by_link_id(vdev->mlo_dev_ctx,
-					       req->new_ieee_link_id);
+	mlo_link_info = mlo_mgr_get_ap_link_by_link_id(mlo_dev_ctx,
+						       req->new_ieee_link_id);
 
 	if (!mlo_link_info) {
 		mlo_err("New link ID not found");
@@ -746,7 +750,7 @@ QDF_STATUS mlo_mgr_link_switch_start_connect(struct wlan_objmgr_vdev *vdev)
 		goto out;
 	}
 
-	wlan_vdev_set_link_id(vdev, req->new_ieee_link_id);
+	sta_ctx = mlo_dev_ctx->sta_ctx;
 	copied_conn_req_lock_acquire(sta_ctx);
 	if (sta_ctx->copied_conn_req) {
 		qdf_mem_copy(&conn_req, sta_ctx->copied_conn_req,
@@ -757,12 +761,25 @@ QDF_STATUS mlo_mgr_link_switch_start_connect(struct wlan_objmgr_vdev *vdev)
 	}
 	copied_conn_req_lock_release(sta_ctx);
 
+	status = wlan_vdev_get_bss_peer_mld_mac(assoc_vdev, &mld_addr);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		mlo_debug("Get MLD addr failed");
+		goto out;
+	}
+
 	conn_req.vdev_id = wlan_vdev_get_id(vdev);
 	conn_req.source = CM_MLO_LINK_SWITCH_CONNECT;
+	wlan_vdev_set_link_id(vdev, req->new_ieee_link_id);
+
 	qdf_copy_macaddr(&conn_req.bssid, &mlo_link_info->ap_link_addr);
-	mlo_allocate_and_copy_ies(&conn_req, sta_ctx->copied_conn_req);
+	qdf_copy_macaddr(&conn_req.mld_addr, &mld_addr);
+	wlan_vdev_mlme_get_ssid(assoc_vdev, conn_req.ssid.ssid,
+				&conn_req.ssid.length);
+
 	conn_req.crypto.auth_type = 0;
 	conn_req.ml_parnter_info = sta_ctx->ml_partner_info;
+	mlo_allocate_and_copy_ies(&conn_req, sta_ctx->copied_conn_req);
+
 	status = wlan_cm_start_connect(vdev, &conn_req);
 	if (QDF_IS_STATUS_SUCCESS(status))
 		mlo_update_connected_links(vdev, 1);

+ 15 - 4
umac/mlo_mgr/src/wlan_mlo_mgr_sta.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -818,6 +818,7 @@ mlo_update_connect_req_chan_info(struct wlan_cm_connect_req *req)
  * @ml_parnter_info: ml partner link info
  * @link_info: link info on which connect req will be sent
  * @ssid: ssid to connect
+ * @mld_addr: MLD address for connect request.
  *
  * Return: none
  */
@@ -826,7 +827,8 @@ static void
 mlo_prepare_and_send_connect(struct wlan_objmgr_vdev *vdev,
 			     struct mlo_partner_info ml_parnter_info,
 			     struct mlo_link_info link_info,
-			     struct wlan_ssid ssid)
+			     struct wlan_ssid ssid,
+			     struct qdf_mac_addr *mld_addr)
 {
 	struct wlan_cm_connect_req req = {0};
 	struct wlan_mlo_dev_context *mlo_dev_ctx = vdev->mlo_dev_ctx;
@@ -861,8 +863,11 @@ mlo_prepare_and_send_connect(struct wlan_objmgr_vdev *vdev,
 		     &ml_parnter_info,
 		     sizeof(struct mlo_partner_info));
 
+	req.vdev_id = wlan_vdev_get_id(vdev);
 	req.ssid.length = ssid.length;
 	qdf_mem_copy(&req.ssid.ssid, &ssid.ssid, ssid.length);
+	if (mld_addr)
+		qdf_copy_macaddr(&req.mld_addr, mld_addr);
 
 	if (sta_ctx->copied_conn_req)
 		mlo_allocate_and_copy_ies(&req, sta_ctx->copied_conn_req);
@@ -900,10 +905,12 @@ mlo_send_link_connect(struct wlan_objmgr_vdev *vdev,
 		      struct mlo_partner_info *ml_parnter_info)
 {
 	/* Create the secondary interface, Send keys if the last link */
+	QDF_STATUS status;
 	uint8_t i, partner_idx = 0;
 	struct wlan_ssid ssid = {0};
 	struct wlan_objmgr_vdev *wlan_vdev_list[WLAN_UMAC_MLO_MAX_VDEVS];
 	uint16_t vdev_count = 0;
+	struct qdf_mac_addr mld_addr;
 
 	mlo_debug("Sending link connect on partner interface");
 	wlan_vdev_mlme_get_ssid(
@@ -918,6 +925,10 @@ mlo_send_link_connect(struct wlan_objmgr_vdev *vdev,
 	if(wlan_vdev_mlme_is_mlo_link_vdev(vdev))
 		return;
 
+	status = wlan_vdev_get_bss_peer_mld_mac(vdev, &mld_addr);
+	if (QDF_IS_STATUS_ERROR(status))
+		return;
+
 	mlo_sta_get_vdev_list(vdev, &vdev_count, wlan_vdev_list);
 	for (i = 0; i < vdev_count; i++) {
 		if (wlan_vdev_list[i] == vdev) {
@@ -936,7 +947,7 @@ mlo_send_link_connect(struct wlan_objmgr_vdev *vdev,
 				wlan_vdev_list[i],
 				*ml_parnter_info,
 				ml_parnter_info->partner_link_info[partner_idx],
-				ssid);
+				ssid, &mld_addr);
 		mlo_update_connected_links(wlan_vdev_list[i], 1);
 		partner_idx++;
 		mlo_release_vdev_ref(wlan_vdev_list[i]);
@@ -984,7 +995,7 @@ mlo_send_link_connect(struct wlan_objmgr_vdev *vdev,
 							mlo_dev_ctx->wlan_vdev_list[i],
 							*ml_parnter_info,
 							ml_parnter_info->partner_link_info[j],
-							ssid);
+							ssid, NULL);
 						mlo_dev_lock_release(mlo_dev_ctx);
 						return;
 					}

+ 17 - 1
umac/scan/core/src/wlan_scan_filter.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -704,6 +704,22 @@ static bool scm_mlo_filter_match(struct wlan_objmgr_pdev *pdev,
 	enum reg_wifi_band band;
 	struct partner_link_info *partner_link;
 	bool is_disabled;
+	struct qdf_mac_addr *mld_addr;
+
+	/* If MLD address of scan entry doesn't match the MLD address in scan
+	 * filter, then drop the scan entry even if the BSSID matches.
+	 * This is to filter out entries from APs with similar BSSID
+	 * but different MLD address.
+	 */
+	if (filter->match_mld_addr) {
+		mld_addr = util_scan_entry_mldaddr(db_entry);
+		if (!mld_addr ||
+		    !qdf_is_macaddr_equal(&filter->mld_addr, mld_addr)) {
+			scm_debug("Scan filter MLD mismatch " QDF_MAC_ADDR_FMT,
+				  QDF_MAC_ADDR_REF(filter->mld_addr.bytes));
+			return false;
+		}
+	}
 
 	if (!db_entry->ie_list.multi_link_bv)
 		return true;

+ 6 - 2
umac/scan/dispatcher/inc/wlan_scan_public_structs.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -736,6 +736,7 @@ enum dot11_mode_filter {
  *                        this is set (For WPS/OSEN connection)
  * @ignore_nol_chan: Ignore entry with channel in the NOL list
  * @ignore_6ghz_channel: ignore 6Ghz channels
+ * @match_mld_addr: Flag to match mld addr of scan entry
  * @age_threshold: If set return entry which are newer than the age_threshold
  * @num_of_bssid: number of bssid passed
  * @num_of_ssid: number of ssid
@@ -761,6 +762,7 @@ enum dot11_mode_filter {
  * @ccx_validate_bss: Function pointer to custom bssid filter
  * @ccx_validate_bss_arg: Function argument to custom bssid filter
  * @band_bitmap: Allowed band bit map, BIT0: 2G, BIT1: 5G, BIT2: 6G
+ * @mld_addr: MLD addr to match if @match_mld_addr is set to true.
  */
 struct scan_filter {
 	uint8_t enable_adaptive_11r:1,
@@ -768,7 +770,8 @@ struct scan_filter {
 		ignore_pmf_cap:1,
 		ignore_auth_enc_type:1,
 		ignore_nol_chan:1,
-		ignore_6ghz_channel:1;
+		ignore_6ghz_channel:1,
+		match_mld_addr:1;
 	qdf_time_t age_threshold;
 	uint8_t num_of_bssid;
 	uint8_t num_of_ssid;
@@ -797,6 +800,7 @@ struct scan_filter {
 	bss_filter_arg_t ccx_validate_bss_arg;
 #ifdef WLAN_FEATURE_11BE_MLO
 	uint32_t band_bitmap;
+	struct qdf_mac_addr mld_addr;
 #endif
 };