Sfoglia il codice sorgente

qcacld-3.0: Add support for PASN authentication frame handling

Define PASN authentication algorithm enum.
PASN authentication is offloaded to userspace. So
forward the PASN authentication frames to supplicant.
The PASN authentication can also be received when the
pe_session for the vdev is not created, so don't drop
the PASN frame when pe session is not found.

Indicate the PASN authentication frame by invoking
cfg80211_rx_mgmt() call. In PASN management frame
TX path, allow the PASN frames to request ROC
and configure RX filter to firmware to receive
frames with address other than the vdev address.

Change-Id: I0903285c1e5c1982ed6317d9418dd2a1f2b30abb
CRs-Fixed: 3139604
Pragaspathi Thilagaraj 3 anni fa
parent
commit
90cdeef35e

+ 14 - 2
core/hdd/src/wlan_hdd_p2p.c

@@ -270,6 +270,7 @@ int wlan_hdd_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
 	return errno;
 }
 
+#define WLAN_AUTH_FRAME_MIN_LEN 2
 static int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
 			      struct ieee80211_channel *chan, bool offchan,
 			      unsigned int wait,
@@ -281,8 +282,8 @@ static int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
 	struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
 	struct wlan_objmgr_vdev *vdev;
-	uint8_t type;
-	uint8_t sub_type;
+	uint8_t type, sub_type;
+	uint16_t auth_algo;
 	QDF_STATUS qdf_status;
 	int ret;
 
@@ -314,6 +315,16 @@ static int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
 	     adapter->device_mode == QDF_P2P_GO_MODE) &&
 	    (type == SIR_MAC_MGMT_FRAME &&
 	    sub_type == SIR_MAC_MGMT_AUTH)) {
+		/* Request ROC for PASN authentication frame */
+		if (len > (sizeof(struct wlan_frame_hdr) +
+			   WLAN_AUTH_FRAME_MIN_LEN)) {
+			auth_algo =
+				*(uint16_t *)(buf +
+					      sizeof(struct wlan_frame_hdr));
+			if (auth_algo == eSIR_AUTH_TYPE_PASN)
+				goto off_chan_tx;
+		}
+
 		qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_SME,
 			   TRACE_CODE_HDD_SEND_MGMT_TX, adapter->vdev_id, 0);
 
@@ -326,6 +337,7 @@ static int __wlan_hdd_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
 			return -EINVAL;
 	}
 
+off_chan_tx:
 	hdd_debug("device_mode:%d type:%d sub_type:%d chan:%d",
 		  adapter->device_mode, type, sub_type,
 		  chan ? chan->center_freq : 0);

+ 2 - 0
core/mac/inc/ani_system_defs.h

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2011-2019, 2021 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 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
@@ -58,6 +59,7 @@ typedef enum eAniAuthType {
 	SIR_FILS_SK_WITHOUT_PFS = 4,
 	SIR_FILS_SK_WITH_PFS = 5,
 	SIR_FILS_PK_AUTH = 6,
+	eSIR_AUTH_TYPE_PASN = 7,
 	eSIR_AUTH_TYPE_OWE,
 	eSIR_AUTO_SWITCH,
 	eSIR_DONOT_USE_AUTH_TYPE = SIR_MAX_ENUM_SIZE

+ 20 - 26
core/mac/src/pe/lim/lim_process_action_frame.c

@@ -950,7 +950,7 @@ static void __lim_process_qos_map_configure_frame(struct mac_context *mac_ctx,
 	lim_send_sme_mgmt_frame_ind(mac_ctx, mac_hdr->fc.subType,
 				    (uint8_t *)mac_hdr,
 				    frame_len + sizeof(tSirMacMgmtHdr), 0,
-				    WMA_GET_RX_FREQ(rx_pkt_info), session,
+				    WMA_GET_RX_FREQ(rx_pkt_info),
 				    WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info),
 				    RXMGMT_FLAG_NONE);
 }
@@ -1173,7 +1173,7 @@ __lim_process_radio_measure_request(struct mac_context *mac, uint8_t *pRxPacketI
 	mac->rrm.rrmPEContext.prev_rrm_report_seq_num = curr_seq_num;
 	lim_send_sme_mgmt_frame_ind(mac, pHdr->fc.subType, (uint8_t *)pHdr,
 				    frameLen + sizeof(tSirMacMgmtHdr), 0,
-				    WMA_GET_RX_FREQ(pRxPacketInfo), pe_session,
+				    WMA_GET_RX_FREQ(pRxPacketInfo),
 				    WMA_GET_RX_RSSI_NORMALIZED(pRxPacketInfo),
 				    RXMGMT_FLAG_NONE);
 
@@ -1452,7 +1452,6 @@ static void __lim_process_sa_query_response_action_frame(struct mac_context *mac
 					    frame_len + sizeof(tSirMacMgmtHdr),
 					    0,
 					    WMA_GET_RX_FREQ(pRxPacketInfo),
-					    pe_session,
 					    WMA_GET_RX_RSSI_NORMALIZED(
 					    pRxPacketInfo), RXMGMT_FLAG_NONE);
 		return;
@@ -1876,9 +1875,9 @@ void lim_process_action_frame(struct mac_context *mac_ctx,
 					mac_hdr->fc.subType,
 					(uint8_t *) mac_hdr,
 					frame_len + sizeof(tSirMacMgmtHdr),
-					session->smeSessionId,
+					session->vdev_id,
 					WMA_GET_RX_FREQ(rx_pkt_info),
-					session, rssi, RXMGMT_FLAG_NONE);
+					rssi, RXMGMT_FLAG_NONE);
 			break;
 		default:
 			pe_debug("Action ID: %d not handled in WNM category",
@@ -1967,15 +1966,12 @@ void lim_process_action_frame(struct mac_context *mac_ctx,
 			 * type is ACTION
 			 */
 			lim_send_sme_mgmt_frame_ind(mac_ctx,
-					mac_hdr->fc.subType,
-					(uint8_t *) mac_hdr,
-					frame_len +
-					sizeof(tSirMacMgmtHdr),
-					session->smeSessionId,
-					WMA_GET_RX_FREQ(rx_pkt_info),
-					session,
-					WMA_GET_RX_RSSI_NORMALIZED(
-					rx_pkt_info), RXMGMT_FLAG_NONE);
+				mac_hdr->fc.subType, (uint8_t *)mac_hdr,
+				frame_len + sizeof(tSirMacMgmtHdr),
+				session->vdev_id,
+				WMA_GET_RX_FREQ(rx_pkt_info),
+				WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info),
+				RXMGMT_FLAG_NONE);
 		} else {
 			pe_debug("Dropping the vendor specific action frame SelfSta address system role: %d",
 				 GET_LIM_SYSTEM_ROLE(session));
@@ -2036,13 +2032,12 @@ void lim_process_action_frame(struct mac_context *mac_ctx,
 			 * type is ACTION
 			 */
 			lim_send_sme_mgmt_frame_ind(mac_ctx,
-					mac_hdr->fc.subType,
-					(uint8_t *) mac_hdr,
-					frame_len + sizeof(tSirMacMgmtHdr),
-					session->smeSessionId,
-					WMA_GET_RX_FREQ(rx_pkt_info), session,
-					WMA_GET_RX_RSSI_NORMALIZED(
-					rx_pkt_info), RXMGMT_FLAG_NONE);
+				mac_hdr->fc.subType, (uint8_t *)mac_hdr,
+				frame_len + sizeof(tSirMacMgmtHdr),
+				session->vdev_id,
+				WMA_GET_RX_FREQ(rx_pkt_info),
+				WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info),
+				RXMGMT_FLAG_NONE);
 			break;
 		}
 		break;
@@ -2102,9 +2097,8 @@ void lim_process_action_frame(struct mac_context *mac_ctx,
 		lim_send_sme_mgmt_frame_ind(mac_ctx, hdr->fc.subType,
 					    (uint8_t *)hdr,
 					    frame_len + sizeof(tSirMacMgmtHdr),
-					    session->smeSessionId,
+					    session->vdev_id,
 					    WMA_GET_RX_FREQ(rx_pkt_info),
-					    session,
 					    WMA_GET_RX_RSSI_NORMALIZED(
 					    rx_pkt_info), RXMGMT_FLAG_NONE);
 		break;
@@ -2122,8 +2116,8 @@ void lim_process_action_frame(struct mac_context *mac_ctx,
 			lim_send_sme_mgmt_frame_ind(mac_ctx,
 				mac_hdr->fc.subType, (uint8_t *) mac_hdr,
 				frame_len + sizeof(tSirMacMgmtHdr),
-				session->smeSessionId,
-				WMA_GET_RX_FREQ(rx_pkt_info), session, rssi,
+				session->vdev_id,
+				WMA_GET_RX_FREQ(rx_pkt_info), rssi,
 				RXMGMT_FLAG_NONE);
 			break;
 		default:
@@ -2228,7 +2222,7 @@ void lim_process_action_frame_no_session(struct mac_context *mac, uint8_t *pBd)
 					mac_hdr->fc.subType,
 					(uint8_t *) mac_hdr,
 					frame_len + sizeof(tSirMacMgmtHdr), 0,
-					WMA_GET_RX_FREQ(pBd), NULL,
+					WMA_GET_RX_FREQ(pBd),
 					WMA_GET_RX_RSSI_NORMALIZED(pBd),
 					RXMGMT_FLAG_NONE);
 			break;

+ 69 - 22
core/mac/src/pe/lim/lim_process_auth_frame.c

@@ -496,8 +496,8 @@ static void lim_process_sae_auth_frame(struct mac_context *mac_ctx,
 	lim_send_sme_mgmt_frame_ind(mac_ctx, mac_hdr->fc.subType,
 				    (uint8_t *)mac_hdr,
 				    frame_len + sizeof(tSirMacMgmtHdr),
-				    pe_session->smeSessionId,
-				    WMA_GET_RX_FREQ(rx_pkt_info), pe_session,
+				    pe_session->vdev_id,
+				    WMA_GET_RX_FREQ(rx_pkt_info),
 				    WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info),
 				    rx_flags);
 }
@@ -507,6 +507,48 @@ static inline void  lim_process_sae_auth_frame(struct mac_context *mac_ctx,
 {}
 #endif
 
+#ifdef WLAN_FEATURE_RTT_11AZ_SUPPORT
+/**
+ * lim_process_pasn_auth_frame()- Process PASN authentication frame
+ * @mac_ctx: MAC context
+ * @vdev_id: Vdev identifier
+ * @rx_pkt_info: Rx packet
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+lim_process_pasn_auth_frame(struct mac_context *mac_ctx,
+			    uint8_t vdev_id,
+			    uint8_t *rx_pkt_info)
+{
+	tpSirMacMgmtHdr mac_hdr;
+	uint32_t frame_len;
+	uint8_t *body_ptr;
+	enum rxmgmt_flags rx_flags = RXMGMT_FLAG_NONE;
+
+	mac_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt_info);
+	body_ptr = WMA_GET_RX_MPDU_DATA(rx_pkt_info);
+	frame_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt_info);
+
+	lim_send_sme_mgmt_frame_ind(mac_ctx, mac_hdr->fc.subType,
+				    (uint8_t *)mac_hdr,
+				    frame_len + sizeof(tSirMacMgmtHdr),
+				    vdev_id, WMA_GET_RX_FREQ(rx_pkt_info),
+				    WMA_GET_RX_RSSI_NORMALIZED(rx_pkt_info),
+				    rx_flags);
+
+	return QDF_STATUS_SUCCESS;
+}
+#else
+static inline QDF_STATUS
+lim_process_pasn_auth_frame(struct mac_context *mac_ctx,
+			    uint8_t vdev_id,
+			    uint8_t *rx_pkt_info)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
 static void lim_process_auth_frame_type1(struct mac_context *mac_ctx,
 		tpSirMacMgmtHdr mac_hdr,
 		tSirMacAuthFrameBody *rx_auth_frm_body,
@@ -1604,6 +1646,10 @@ lim_process_auth_frame(struct mac_context *mac_ctx, uint8_t *rx_pkt_info,
 			lim_process_sae_auth_frame(mac_ctx, rx_pkt_info,
 						   pe_session);
 		goto free;
+	} else if (auth_alg == eSIR_AUTH_TYPE_PASN) {
+		lim_process_pasn_auth_frame(mac_ctx, pe_session->vdev_id,
+					    rx_pkt_info);
+		goto free;
 	} else if ((sir_convert_auth_frame2_struct(mac_ctx, body_ptr,
 				frame_len, rx_auth_frame) != QDF_STATUS_SUCCESS)
 				|| (!is_auth_valid(mac_ctx, rx_auth_frame,
@@ -1757,12 +1803,13 @@ bool lim_process_sae_preauth_frame(struct mac_context *mac, uint8_t *rx_pkt)
 				    (uint8_t *)dot11_hdr,
 				    frm_len + sizeof(tSirMacMgmtHdr),
 				    SME_SESSION_ID_ANY,
-				    WMA_GET_RX_FREQ(rx_pkt), NULL,
+				    WMA_GET_RX_FREQ(rx_pkt),
 				    WMA_GET_RX_RSSI_NORMALIZED(rx_pkt),
 				    RXMGMT_FLAG_NONE);
 	return true;
 }
 
+#define WLAN_MIN_AUTH_FRM_ALGO_FIELD_LEN 2
 /**
  *
  * Pass the received Auth frame. This is possibly the pre-auth from the
@@ -1774,32 +1821,41 @@ bool lim_process_sae_preauth_frame(struct mac_context *mac, uint8_t *rx_pkt)
 QDF_STATUS lim_process_auth_frame_no_session(struct mac_context *mac,
 					     uint8_t *pBd, void *body)
 {
-	tpSirMacMgmtHdr pHdr;
+	tpSirMacMgmtHdr mac_hdr;
 	struct pe_session *pe_session = NULL;
 	uint8_t *pBody;
-	uint16_t frameLen;
+	uint16_t frameLen, curr_seq_num, auth_alg = 0;
 	tSirMacAuthFrameBody *rx_auth_frame;
 	QDF_STATUS ret_status = QDF_STATUS_E_FAILURE;
 	int i;
 	bool sae_auth_frame;
 
-	pHdr = WMA_GET_RX_MAC_HEADER(pBd);
+	mac_hdr = WMA_GET_RX_MAC_HEADER(pBd);
 	pBody = WMA_GET_RX_MPDU_DATA(pBd);
 	frameLen = WMA_GET_RX_PAYLOAD_LEN(pBd);
-
-	pe_debug("Auth Frame Received: BSSID " QDF_MAC_ADDR_FMT " (RSSI %d)",
-		 QDF_MAC_ADDR_REF(pHdr->bssId),
-		 (uint) abs((int8_t) WMA_GET_RX_RSSI_NORMALIZED(pBd)));
+	curr_seq_num = mac_hdr->seqControl.seqNumHi << 4 |
+		       mac_hdr->seqControl.seqNumLo;
 
 	if (frameLen == 0) {
 		pe_err("Frame len = 0");
 		return QDF_STATUS_E_FAILURE;
 	}
 
+	if (frameLen > WLAN_MIN_AUTH_FRM_ALGO_FIELD_LEN)
+		auth_alg = *(uint16_t *)pBody;
+
+	pe_debug("Auth RX: BSSID " QDF_MAC_ADDR_FMT " RSSI:%d auth_alg:%d seq:%d",
+		 QDF_MAC_ADDR_REF(mac_hdr->bssId),
+		 (uint)abs((int8_t)WMA_GET_RX_RSSI_NORMALIZED(pBd)),
+		 auth_alg, curr_seq_num);
+
 	sae_auth_frame = lim_process_sae_preauth_frame(mac, pBd);
 	if (sae_auth_frame)
 		return QDF_STATUS_SUCCESS;
 
+	if (auth_alg == eSIR_AUTH_TYPE_PASN)
+		return lim_process_pasn_auth_frame(mac, 0, pBd);
+
 	/* Auth frame has come on a new BSS, however, we need to find the session
 	 * from where the auth-req was sent to the new AP
 	 */
@@ -1826,19 +1882,10 @@ QDF_STATUS lim_process_auth_frame_no_session(struct mac_context *mac,
 		return QDF_STATUS_E_FAILURE;
 	}
 
-	lim_print_mac_addr(mac, pHdr->bssId, LOGD);
-	lim_print_mac_addr(mac,
-			   pe_session->ftPEContext.pFTPreAuthReq->preAuthbssId,
-			   LOGD);
-	pe_debug("seqControl: 0x%X",
-		((pHdr->seqControl.seqNumHi << 8) |
-		 (pHdr->seqControl.seqNumLo << 4) |
-		 (pHdr->seqControl.fragNum)));
-
 	/* Check that its the same bssId we have for preAuth */
 	if (qdf_mem_cmp
 		    (pe_session->ftPEContext.pFTPreAuthReq->preAuthbssId,
-		    pHdr->bssId, sizeof(tSirMacAddr))) {
+		     mac_hdr->bssId, sizeof(tSirMacAddr))) {
 		pe_err("Error: Same bssid as preauth BSSID");
 		/* In this case SME if indeed has triggered a */
 		/* pre auth it will time out. */
@@ -1897,12 +1944,12 @@ QDF_STATUS lim_process_auth_frame_no_session(struct mac_context *mac,
 		qdf_mem_free(rx_auth_frame);
 		return QDF_STATUS_E_FAILURE;
 	}
-	pe_info("Pre-Auth RX: type: %d seqnum: %d status: %d %d from " QDF_MAC_ADDR_FMT,
+	pe_info("Pre-Auth RX: type: %d trans_seqnum: %d status: %d %d from " QDF_MAC_ADDR_FMT,
 		(uint32_t)rx_auth_frame->authAlgoNumber,
 		(uint32_t)rx_auth_frame->authTransactionSeqNumber,
 		(uint32_t)rx_auth_frame->authStatusCode,
 		(uint32_t)mac->lim.gLimNumPreAuthContexts,
-		QDF_MAC_ADDR_REF(pHdr->sa));
+		QDF_MAC_ADDR_REF(mac_hdr->sa));
 
 	switch (rx_auth_frame->authTransactionSeqNumber) {
 	case SIR_MAC_AUTH_FRAME_2:

+ 2 - 2
core/mac/src/pe/lim/lim_process_message_queue.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2021-2022 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
@@ -1188,7 +1188,7 @@ lim_check_mgmt_registered_frames(struct mac_context *mac_ctx, uint8_t *buff_desc
 			(uint8_t *) hdr,
 			WMA_GET_RX_PAYLOAD_LEN(buff_desc) +
 			sizeof(tSirMacMgmtHdr), mgmt_frame->sessionId,
-			WMA_GET_RX_FREQ(buff_desc), session_entry,
+			WMA_GET_RX_FREQ(buff_desc),
 			WMA_GET_RX_RSSI_NORMALIZED(buff_desc),
 			RXMGMT_FLAG_NONE);
 

+ 1 - 2
core/mac/src/pe/lim/lim_process_probe_req_frame.c

@@ -486,9 +486,8 @@ lim_indicate_probe_req_to_hdd(struct mac_context *mac, uint8_t *pBd,
 	lim_send_sme_mgmt_frame_ind(mac, pHdr->fc.subType,
 				    (uint8_t *) pHdr,
 				    (frameLen + sizeof(tSirMacMgmtHdr)),
-				    pe_session->smeSessionId,
+				    pe_session->vdev_id,
 				    WMA_GET_RX_FREQ(pBd),
-				    pe_session,
 				    WMA_GET_RX_RSSI_NORMALIZED(pBd),
 				    RXMGMT_FLAG_NONE);
 } /*** end lim_indicate_probe_req_to_hdd() ***/

+ 6 - 5
core/mac/src/pe/lim/lim_utils.c

@@ -8950,8 +8950,7 @@ enum rateid lim_get_min_session_txrate(struct pe_session *session)
 
 void lim_send_sme_mgmt_frame_ind(struct mac_context *mac_ctx, uint8_t frame_type,
 				 uint8_t *frame, uint32_t frame_len,
-				 uint16_t session_id, uint32_t rx_freq,
-				 struct pe_session *psession_entry,
+				 uint16_t vdev_id, uint32_t rx_freq,
 				 int8_t rx_rssi, enum rxmgmt_flags rx_flags)
 {
 	tpSirSmeMgmtFrameInd sme_mgmt_frame = NULL;
@@ -8965,13 +8964,13 @@ void lim_send_sme_mgmt_frame_ind(struct mac_context *mac_ctx, uint8_t frame_type
 
 	if (qdf_is_macaddr_broadcast(
 		(struct qdf_mac_addr *)(frame + 4)) &&
-		!session_id) {
+		!vdev_id) {
 		pe_debug("Broadcast action frame");
-		session_id = SME_SESSION_ID_BROADCAST;
+		vdev_id = SME_SESSION_ID_BROADCAST;
 	}
 
 	sme_mgmt_frame->frame_len = frame_len;
-	sme_mgmt_frame->sessionId = session_id;
+	sme_mgmt_frame->sessionId = vdev_id;
 	sme_mgmt_frame->frameType = frame_type;
 	sme_mgmt_frame->rxRssi = rx_rssi;
 	sme_mgmt_frame->rx_freq = rx_freq;
@@ -8984,7 +8983,9 @@ void lim_send_sme_mgmt_frame_ind(struct mac_context *mac_ctx, uint8_t frame_type
 		mac_ctx->mgmt_frame_ind_cb(sme_mgmt_frame);
 	else
 		pe_debug_rl("Management indication callback not registered!!");
+
 	qdf_mem_free(sme_mgmt_frame);
+
 	return;
 }
 

+ 2 - 4
core/mac/src/pe/lim/lim_utils.h

@@ -334,8 +334,7 @@ void lim_update_short_slot_time(struct mac_context *mac, tSirMacAddr peerMacAddr
  * @frame_type: Type of mgmt frame
  * @frame: Frame pointer
  * @frame_len: Length og mgmt frame
- * @session_id: session id
- * @psession_entry: PE Session Entry
+ * @vdev_id: session id
  * @rx_freq: Frequency on which packet is received
  * @rx_rssi: rssi value
  * @rx_flags: RXMGMT flags to be set for the frame. Defined in enum rxmgmt_flags
@@ -347,8 +346,7 @@ void lim_update_short_slot_time(struct mac_context *mac, tSirMacAddr peerMacAddr
 */
 void lim_send_sme_mgmt_frame_ind(struct mac_context *mac_ctx, uint8_t frame_type,
 				 uint8_t *frame, uint32_t frame_len,
-				 uint16_t session_id, uint32_t rx_freq,
-				 struct pe_session *psession_entry,
+				 uint16_t vdev_id, uint32_t rx_freq,
 				 int8_t rx_rssi, enum rxmgmt_flags rx_flags);
 
 /*