فهرست منبع

qcacld-3.0: Do not allow duplicate peer creation for ML-SAP

As per current design, peer conflict detection logic allows
a peer with particular mac/mld to be created as long as
the ml dev context is same. However, this causes issues
for ML-STA wherein 2 different peer ML-STA could have same
mac address. In this case, the second peer creations should
be disallowed.

To fix this, skip the mac/mld conflict checks on the ml-dev
context of the ML-SAP and handle it separately.

In addition to the current checks add the following checks
for ML-SAP and reject the peer creation if:
a) MLO peer exists for the link mac of peer with different AID.
b) MLO peer exists for the MLD mac of peer with different AID:
c) If the associating client's MLD != one of the link mac address
and there is an MLO peer with different AID.

Change-Id: I75935e2362d6db1411c6a67f1e9db35f3b3963f2
CRs-Fixed: 3719956
Vinod Kumar Pirla 1 سال پیش
والد
کامیت
046d969548
2فایلهای تغییر یافته به همراه121 افزوده شده و 68 حذف شده
  1. 0 68
      core/mac/src/pe/lim/lim_process_auth_frame.c
  2. 121 0
      core/wma/src/wma_dev_if.c

+ 0 - 68
core/mac/src/pe/lim/lim_process_auth_frame.c

@@ -313,43 +313,6 @@ static void lim_process_auth_open_system_algo(struct mac_context *mac_ctx,
 					pe_session);
 }
 
-static QDF_STATUS
-lim_validate_mac_address_in_auth_frame(struct mac_context *mac_ctx,
-				       tpSirMacMgmtHdr mac_hdr,
-				       struct qdf_mac_addr *mld_addr,
-				       uint8_t vdev_id)
-{
-	struct wlan_objmgr_vdev *vdev;
-
-	/* SA is same as any of the device vdev, return failure */
-	vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(mac_ctx->pdev,
-							 mac_hdr->sa,
-							 WLAN_LEGACY_MAC_ID);
-	if (vdev) {
-		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
-		return QDF_STATUS_E_ALREADY;
-	}
-
-	if (mlo_mgr_ml_peer_exist_on_diff_ml_ctx(mac_hdr->sa, &vdev_id))
-		return QDF_STATUS_E_ALREADY;
-
-	if (qdf_is_macaddr_zero(mld_addr))
-		return QDF_STATUS_SUCCESS;
-
-	vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(mac_ctx->pdev,
-							 mld_addr->bytes,
-							 WLAN_LEGACY_MAC_ID);
-	if (vdev) {
-		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
-		return QDF_STATUS_E_ALREADY;
-	}
-
-	if (mlo_mgr_ml_peer_exist_on_diff_ml_ctx(mld_addr->bytes, &vdev_id))
-		return QDF_STATUS_E_ALREADY;
-
-	return QDF_STATUS_SUCCESS;
-}
-
 #ifdef WLAN_FEATURE_SAE
 #ifdef WLAN_FEATURE_11BE_MLO
 /**
@@ -804,15 +767,6 @@ static void lim_process_sae_auth_frame(struct mac_context *mac_ctx,
 			 */
 			lim_get_sta_mld_address(pe_session->vdev, body_ptr,
 						frame_len, &peer_mld);
-			status = lim_validate_mac_address_in_auth_frame(mac_ctx,
-									mac_hdr,
-									&peer_mld,
-									pe_session->vdev_id);
-			if (QDF_IS_STATUS_ERROR(status)) {
-				pe_debug("Drop SAE auth, duplicate entity found");
-				return;
-			}
-
 			lim_external_auth_add_pre_auth_node(mac_ctx, mac_hdr,
 						eLIM_MLM_WT_SAE_AUTH_STATE,
 						&peer_mld);
@@ -1014,7 +968,6 @@ static void lim_process_auth_frame_type1(struct mac_context *mac_ctx,
 	struct tLimPreAuthNode *auth_node;
 	uint32_t maxnum_preauth;
 	uint16_t associd = 0;
-	QDF_STATUS status;
 
 	if (lim_check_and_trigger_pmf_sta_deletion(mac_ctx, pe_session,
 						   mac_hdr))
@@ -1106,27 +1059,6 @@ static void lim_process_auth_frame_type1(struct mac_context *mac_ctx,
 	if (lim_is_auth_algo_supported(mac_ctx,
 			(tAniAuthType) rx_auth_frm_body->authAlgoNumber,
 			pe_session)) {
-		struct qdf_mac_addr *mld_addr = &rx_auth_frm_body->peer_mld;
-
-		status = lim_validate_mac_address_in_auth_frame(mac_ctx,
-								mac_hdr,
-								mld_addr,
-								pe_session->vdev_id);
-		if (QDF_IS_STATUS_ERROR(status)) {
-			pe_err("Duplicate MAC address found, reject auth");
-			auth_frame->authAlgoNumber =
-				rx_auth_frm_body->authAlgoNumber;
-			auth_frame->authTransactionSeqNumber =
-				rx_auth_frm_body->authTransactionSeqNumber + 1;
-			auth_frame->authStatusCode =
-				STATUS_UNSPECIFIED_FAILURE;
-
-			lim_send_auth_mgmt_frame(mac_ctx, auth_frame,
-				mac_hdr->sa, LIM_NO_WEP_IN_FC,
-				pe_session);
-			return;
-		}
-
 		switch (rx_auth_frm_body->authAlgoNumber) {
 		case eSIR_OPEN_SYSTEM:
 			lim_process_auth_open_system_algo(mac_ctx, mac_hdr,

+ 121 - 0
core/wma/src/wma_dev_if.c

@@ -4776,6 +4776,110 @@ static void wma_get_mld_info_ap(tpAddStaParams add_sta,
 		*is_assoc_peer = false;
 	}
 }
+
+static inline QDF_STATUS
+wma_check_for_mlo_peer_conflict(struct wlan_mlo_peer_context *peer_1,
+				struct wlan_mlo_peer_context *peer_2)
+{
+	if (!peer_1 && !peer_2)
+		return QDF_STATUS_SUCCESS;
+
+	if (!peer_2) {
+		wma_err("ML-peer with same mac address exists for a different AID");
+		return QDF_STATUS_E_ALREADY;
+	} else if (peer_1 == peer_2) {
+		return QDF_STATUS_SUCCESS;
+	}
+
+	/* Two ML-peers exists with different AID */
+	QDF_ASSERT(0);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
+static QDF_STATUS
+wma_validate_mac_for_conflict_on_same_ml_ctx(tp_wma_handle wma,
+					     tpAddStaParams add_sta,
+					     uint8_t *peer_mld)
+{
+	struct wlan_objmgr_vdev *vdev = NULL;
+	struct wlan_mlo_peer_context *ml_peer, *tmp_ml_peer;
+	struct qdf_mac_addr sta_addr = {0};
+	struct wlan_objmgr_peer *peer;
+	QDF_STATUS status =  QDF_STATUS_SUCCESS;
+
+	vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma->psoc,
+						    add_sta->smesessionId,
+						    WLAN_LEGACY_WMA_ID);
+	if (!vdev)
+		return QDF_STATUS_E_FAILURE;
+
+	/* Not an ML-SAP, therefore skip the validation */
+	if (!vdev->mlo_dev_ctx)
+		goto release_ref;
+
+	qdf_mem_copy(&sta_addr.bytes[0], add_sta->staMac,
+		     sizeof(tSirMacAddr));
+
+	ml_peer = wlan_mlo_get_mlpeer(vdev->mlo_dev_ctx,
+				      &sta_addr);
+	/*
+	 * ML-peer exists on the ML-dev with same address.
+	 * If the AID is different, then another ML-STA
+	 * is already associated to this SAP using the
+	 * same MLD mac
+	 */
+	if (ml_peer) {
+		tmp_ml_peer = wlan_mlo_get_mlpeer_by_aid(vdev->mlo_dev_ctx,
+							 add_sta->assocId);
+
+		status = wma_check_for_mlo_peer_conflict(ml_peer, tmp_ml_peer);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			wma_err("Link mac address conflicts with another MLO peer on same interface");
+			goto release_ref;
+		}
+	}
+
+	/*
+	 * ML-peer exists on the ML-dev with same MLD address.
+	 * If the AID is different, reject the peer create
+	 */
+	ml_peer = wlan_mlo_get_mlpeer(vdev->mlo_dev_ctx,
+				      (struct qdf_mac_addr *)peer_mld);
+	if (ml_peer) {
+		tmp_ml_peer = wlan_mlo_get_mlpeer_by_aid(vdev->mlo_dev_ctx,
+							 add_sta->assocId);
+		status = wma_check_for_mlo_peer_conflict(ml_peer, tmp_ml_peer);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			wma_err("MLD mac address conflicts with another MLO peer on same interface");
+			goto release_ref;
+		}
+	}
+
+	/*
+	 * If the link address of another ML-peer(with different AID) matches
+	 * with the MLD address of the incoming peer, reject the peer create.
+	 *
+	 * Note: Legacy MLD mac - link mac conflict is taken care at
+	 * wma_create_peer_validate_mld_address()
+	 */
+	peer = wlan_objmgr_get_peer_by_mac(wma->psoc, peer_mld,
+					   WLAN_LEGACY_WMA_ID);
+	if (!peer) {
+		goto release_ref;
+	} else {
+		if (peer->mlo_peer_ctx &&
+		    peer->mlo_peer_ctx->assoc_id != add_sta->assocId) {
+			wma_err("MLD mac address conflicts with link mac address of another ML-peer on same interface");
+			status = QDF_STATUS_E_FAILURE;
+		}
+		wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
+	}
+
+release_ref:
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
+	return status;
+}
 #else
 static void wma_get_mld_info_ap(tpAddStaParams add_sta,
 				uint8_t **peer_mld_addr,
@@ -4784,6 +4888,14 @@ static void wma_get_mld_info_ap(tpAddStaParams add_sta,
 	*peer_mld_addr = NULL;
 	*is_assoc_peer = false;
 }
+
+static QDF_STATUS
+wma_validate_mac_for_conflict_on_same_ml_ctx(tp_wma_handle wma,
+					     tpAddStaParams add_sta,
+					     uint8_t *peer_mld)
+{
+	return QDF_STATUS_SUCCESS;
+}
 #endif
 
 /**
@@ -4849,6 +4961,15 @@ static void wma_add_sta_req_ap_mode(tp_wma_handle wma, tpAddStaParams add_sta)
 	wma_delete_invalid_peer_entries(add_sta->smesessionId, add_sta->staMac);
 
 	wma_get_mld_info_ap(add_sta, &peer_mld_addr, &is_assoc_peer);
+
+	status = wma_validate_mac_for_conflict_on_same_ml_ctx(wma, add_sta,
+							      peer_mld_addr);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		wma_err("Conflict detected with mac address, peer create failed");
+		add_sta->status = status;
+		goto send_rsp;
+	}
+
 	status = wma_create_peer(wma, add_sta->staMac, WMI_PEER_TYPE_DEFAULT,
 				 add_sta->smesessionId, peer_mld_addr,
 				 is_assoc_peer);