Browse Source

qcacld-3.0: reject client if the peer is present same ml address

Host/fw doesn't support the ml peers or legacy peers with same
mac address, So reject the client with the same link address or
mld address as one of the ml or legacy peers in the system.

Change-Id: I5f625e06c1f3832739d0424e1567a9957037fef8
CRs-Fixed: 3344809
Arun Kumar Khandavalli 2 years ago
parent
commit
6d5ce1983d

+ 1 - 0
core/mac/inc/sir_mac_prot_def.h

@@ -1263,6 +1263,7 @@ typedef struct sSirMacAuthFrameBody {
 	uint8_t nonce[SIR_FILS_NONCE_LENGTH];
 #endif
 	bool is_mlo_ie_present;
+	struct qdf_mac_addr peer_mld;
 } qdf_packed tSirMacAuthFrameBody, *tpSirMacAuthFrameBody;
 
 /* / Common header for all action frames */

+ 41 - 9
core/mac/src/pe/lim/lim_process_auth_frame.c

@@ -46,6 +46,7 @@
 #include "wlan_mlme_api.h"
 #include "wlan_connectivity_logging.h"
 #include "lim_types.h"
+#include <wlan_mlo_mgr_main.h>
 
 /**
  * is_auth_valid
@@ -628,6 +629,40 @@ lim_process_pasn_auth_frame(struct mac_context *mac_ctx,
 	return QDF_STATUS_SUCCESS;
 }
 
+static QDF_STATUS
+lim_validate_mac_address_in_auth_frame(struct mac_context *mac_ctx,
+				       tpSirMacMgmtHdr mac_hdr,
+				       tSirMacAuthFrameBody *rx_auth_frm_body)
+{
+	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;
+	}
+
+	vdev = wlan_objmgr_get_vdev_by_macaddr_from_pdev(
+					mac_ctx->pdev,
+					rx_auth_frm_body->peer_mld.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(mac_hdr->sa))
+		return QDF_STATUS_E_ALREADY;
+
+	if (mlo_mgr_ml_peer_exist(rx_auth_frm_body->peer_mld.bytes))
+		return QDF_STATUS_E_ALREADY;
+
+	return QDF_STATUS_SUCCESS;
+}
+
 static void lim_process_auth_frame_type1(struct mac_context *mac_ctx,
 		tpSirMacMgmtHdr mac_hdr,
 		tSirMacAuthFrameBody *rx_auth_frm_body,
@@ -638,6 +673,7 @@ 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;
 
 	/* AuthFrame 1 */
 	sta_ds_ptr = dph_lookup_hash_entry(mac_ctx, mac_hdr->sa,
@@ -785,15 +821,11 @@ 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 wlan_objmgr_vdev *vdev;
-
-		vdev =
-		  wlan_objmgr_get_vdev_by_macaddr_from_pdev(mac_ctx->pdev,
-							    mac_hdr->sa,
-							    WLAN_LEGACY_MAC_ID);
-		/* SA is same as any of the device vdev, return failure */
-		if (vdev) {
-			wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
+		status = lim_validate_mac_address_in_auth_frame(
+						mac_ctx, mac_hdr,
+						rx_auth_frm_body);
+		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 =

+ 10 - 0
core/mac/src/sys/legacy/src/utils/src/parser_api.c

@@ -5588,6 +5588,16 @@ sir_convert_auth_frame2_struct(struct mac_context *mac,
 
 	/* Copy MLO IE presence flag to pAuth in case of ML connection */
 	pAuth->is_mlo_ie_present = auth.mlo_ie.present;
+	/* The minimum length is set to 9 based on below calculation
+	 * Multi-Link Control Field => 2 Bytes
+	 * Minimum CInfo Field => CInfo Length (1 Byte) + MLD Addr (6 Bytes)
+	 * min_len = 2 + 1 + 6
+	 * MLD Offset = min_len - (2 + 1)
+	 */
+	if (pAuth->is_mlo_ie_present && auth.mlo_ie.num_data >= 9) {
+		qdf_copy_macaddr(&pAuth->peer_mld,
+				 (struct qdf_mac_addr *)(auth.mlo_ie.data + 3));
+	}
 
 	sir_update_auth_frame2_struct_fils_conf(&auth, pAuth);
 

+ 3 - 1
core/wma/inc/wma.h

@@ -1677,13 +1677,15 @@ QDF_STATUS wma_create_peer(tp_wma_handle wma,
  * @vdev_id: vdev id
  * @peer_addr: peer mac address
  * @wma_peer_type: peer type of enum wmi_peer_type
+ * @peer_mld: peer mld address
  *
  * Return: Pointer to objmgr_peer
  */
 struct wlan_objmgr_peer *wma_create_objmgr_peer(tp_wma_handle wma,
 						uint8_t vdev_id,
 						uint8_t *peer_addr,
-						uint32_t wma_peer_type);
+						uint32_t wma_peer_type,
+						uint8_t *peer_mld);
 
 /**
  * wma_remove_objmgr_peer() - Remove Object manager peer

+ 17 - 5
core/wma/src/wma_dev_if.c

@@ -1568,6 +1568,10 @@ bool wma_objmgr_peer_exist(tp_wma_handle wma,
 {
 	struct wlan_objmgr_peer *peer;
 
+	if (!peer_addr ||
+	    qdf_is_macaddr_zero((struct qdf_mac_addr *)peer_addr))
+		return false;
+
 	peer = wlan_objmgr_get_peer_by_mac(wma->psoc, peer_addr,
 					   WLAN_LEGACY_WMA_ID);
 	if (!peer)
@@ -1763,7 +1767,8 @@ static int wma_get_obj_mgr_peer_type(tp_wma_handle wma, uint8_t vdev_id,
 struct wlan_objmgr_peer *wma_create_objmgr_peer(tp_wma_handle wma,
 						uint8_t vdev_id,
 						uint8_t *peer_addr,
-						uint32_t wma_peer_type)
+						uint32_t wma_peer_type,
+						uint8_t *peer_mld_addr)
 {
 	uint32_t obj_peer_type = 0;
 	struct wlan_objmgr_peer *obj_peer = NULL;
@@ -1776,11 +1781,16 @@ struct wlan_objmgr_peer *wma_create_objmgr_peer(tp_wma_handle wma,
 	 * adding this peer.
 	 */
 	if (wma_objmgr_peer_exist(wma, peer_addr, &peer_vdev_id)) {
-		wma_info("Peer "QDF_MAC_ADDR_FMT" already exist on vdev %d, current vdev %d",
-			  QDF_MAC_ADDR_REF(peer_addr), peer_vdev_id, vdev_id);
+		wma_info("Peer " QDF_MAC_ADDR_FMT " already exist on vdev %d, current vdev %d",
+			 QDF_MAC_ADDR_REF(peer_addr), peer_vdev_id, vdev_id);
 		return NULL;
 	}
 
+	if (wma_objmgr_peer_exist(wma, peer_mld_addr, &peer_vdev_id)) {
+		wma_info("Peer " QDF_MAC_ADDR_FMT " already exist on vdev %d, current vdev %d",
+			 QDF_MAC_ADDR_REF(peer_mld_addr), peer_vdev_id, vdev_id);
+		return NULL;
+	}
 	obj_peer_type = wma_get_obj_mgr_peer_type(wma, vdev_id, peer_addr,
 						  wma_peer_type);
 	if (!obj_peer_type) {
@@ -1893,7 +1903,8 @@ QDF_STATUS wma_add_peer(tp_wma_handle wma,
 		return QDF_STATUS_E_FAILURE;
 	}
 
-	obj_peer = wma_create_objmgr_peer(wma, vdev_id, peer_addr, peer_type);
+	obj_peer = wma_create_objmgr_peer(wma, vdev_id, peer_addr, peer_type,
+					  peer_mld_addr);
 	if (!obj_peer)
 		return QDF_STATUS_E_FAILURE;
 
@@ -2681,7 +2692,8 @@ QDF_STATUS wma_vdev_self_peer_create(struct vdev_mlme_obj *vdev_mlme)
 		obj_peer = wma_create_objmgr_peer(wma_handle,
 						  wlan_vdev_get_id(vdev),
 						  self_peer_macaddr,
-						  WMI_PEER_TYPE_DEFAULT);
+						  WMI_PEER_TYPE_DEFAULT,
+						  vdev->vdev_mlme.macaddr);
 		if (!obj_peer) {
 			wma_err("Failed to create obj mgr peer for self");
 			status = QDF_STATUS_E_INVAL;

+ 1 - 1
core/wma/src/wma_pasn_peer_api.c

@@ -121,7 +121,7 @@ wma_pasn_peer_create(struct wlan_objmgr_psoc *psoc,
 	 * create command to firmware.
 	 */
 	obj_peer = wma_create_objmgr_peer(wma, vdev_id, peer_addr->bytes,
-					  WMI_PEER_TYPE_PASN);
+					  WMI_PEER_TYPE_PASN, NULL);
 	if (!obj_peer) {
 		wma_release_wakelock(&wma->wmi_cmd_rsp_wake_lock);
 		return QDF_STATUS_E_FAILURE;