ソースを参照

qcacld-3.0: Handle SAE preauth management frame with no session

The host driver drops any authentication frames that doesn't
belong to current pe session. But, for WPA3 SAE roaming
pre-authentication is offloaded to user space, and as part of
that, the host driver should handle the SAE commit/confirm
messages received from the target AP for which there is no
pe_session.

Add changes to check the auth algorithm in the authentication
frames received for which no pe_session exist and if auth algo is
SAE, indicate that frame to wpa_supplicant.

Change-Id: Ie911524475423704246c1b4f694b83abdbf5129a
CRs-Fixed: 2505556
Pragaspathi Thilagaraj 5 年 前
コミット
21b88d2d5b
2 ファイル変更70 行追加10 行削除
  1. 56 8
      core/mac/src/pe/lim/lim_process_auth_frame.c
  2. 14 2
      core/mac/src/pe/lim/lim_types.h

+ 56 - 8
core/mac/src/pe/lim/lim_process_auth_frame.c

@@ -1602,15 +1602,57 @@ free:
 		qdf_mem_free(plainbody);
 }
 
-/*----------------------------------------------------------------------
+/**
+ * lim_process_sae_preauth_frame() - Send the WPA3 preauth SAE frame received
+ * to the user space.
+ * @mac: Global mac context
+ * @rx_pkt: Received auth packet
+ *
+ * SAE auth frame will be received with no session if its SAE preauth during
+ * roaming offloaded to the host. Forward this frame to the wpa supplicant.
+ *
+ * Return: True if auth algo is SAE else false
+ */
+static
+bool lim_process_sae_preauth_frame(struct mac_context *mac, uint8_t *rx_pkt)
+{
+	tpSirMacMgmtHdr dot11_hdr;
+	uint16_t auth_alg, frm_len;
+	uint8_t *frm_body;
+
+	dot11_hdr = WMA_GET_RX_MAC_HEADER(rx_pkt);
+	frm_body = WMA_GET_RX_MPDU_DATA(rx_pkt);
+	frm_len = WMA_GET_RX_PAYLOAD_LEN(rx_pkt);
+
+	if (frm_len < 2) {
+		pe_debug("LFR3: Invalid auth frame len:%d", frm_len);
+		return false;
+	}
+
+	auth_alg = *(uint16_t *)frm_body;
+	if (auth_alg != eSIR_AUTH_TYPE_SAE)
+		return false;
+
+	pe_debug("LFR3: SAE auth frame: seq_ctrl:0x%X auth_transaction_num:%d",
+		 ((dot11_hdr->seqControl.seqNumHi << 8) |
+		  (dot11_hdr->seqControl.seqNumLo << 4) |
+		  (dot11_hdr->seqControl.fragNum)), *(uint16_t *)(frm_body + 2));
+
+	lim_send_sme_mgmt_frame_ind(mac, dot11_hdr->fc.subType,
+				    (uint8_t *)dot11_hdr,
+				    frm_len + sizeof(tSirMacMgmtHdr), 0,
+				    WMA_GET_RX_CH(rx_pkt), NULL,
+				    WMA_GET_RX_RSSI_NORMALIZED(rx_pkt),
+				    RXMGMT_FLAG_NONE);
+	return true;
+}
+
+/**
  *
  * Pass the received Auth frame. This is possibly the pre-auth from the
  * neighbor AP, in the same mobility domain.
  * This will be used in case of 11r FT.
  *
- * !!!! This is going to be renoved for the next checkin. We will be creating
- * the session before sending out the Auth. Thus when auth response
- * is received we will have a session in progress. !!!!!
  ***----------------------------------------------------------------------
  */
 QDF_STATUS lim_process_auth_frame_no_session(struct mac_context *mac, uint8_t *pBd,
@@ -1624,6 +1666,7 @@ QDF_STATUS lim_process_auth_frame_no_session(struct mac_context *mac, uint8_t *p
 	tSirMacAuthFrameBody *pRxAuthFrameBody = NULL;
 	QDF_STATUS ret_status = QDF_STATUS_E_FAILURE;
 	int i;
+	bool sae_auth_frame;
 
 	pHdr = WMA_GET_RX_MAC_HEADER(pBd);
 	pBody = WMA_GET_RX_MPDU_DATA(pBd);
@@ -1633,6 +1676,15 @@ QDF_STATUS lim_process_auth_frame_no_session(struct mac_context *mac, uint8_t *p
 		 QDF_MAC_ADDR_ARRAY(pHdr->bssId),
 		 (uint) abs((int8_t) WMA_GET_RX_RSSI_NORMALIZED(pBd)));
 
+	if (frameLen == 0) {
+		pe_err("Frame len = 0");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	sae_auth_frame = lim_process_sae_preauth_frame(mac, pBd);
+	if (sae_auth_frame)
+		return QDF_STATUS_SUCCESS;
+
 	/* 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
 	 */
@@ -1659,10 +1711,6 @@ QDF_STATUS lim_process_auth_frame_no_session(struct mac_context *mac, uint8_t *p
 		return QDF_STATUS_E_FAILURE;
 	}
 
-	if (frameLen == 0) {
-		pe_err("Error: Frame len = 0");
-		return QDF_STATUS_E_FAILURE;
-	}
 	lim_print_mac_addr(mac, pHdr->bssId, LOGD);
 	lim_print_mac_addr(mac,
 			   pe_session->ftPEContext.pFTPreAuthReq->preAuthbssId,

+ 14 - 2
core/mac/src/pe/lim/lim_types.h

@@ -387,8 +387,20 @@ void lim_process_probe_req_frame_multiple_bss(struct mac_context *, uint8_t *,
 
 /* Process Auth frame when we have a session in progress. */
 void lim_process_auth_frame(struct mac_context *, uint8_t *, struct pe_session *);
-QDF_STATUS lim_process_auth_frame_no_session(struct mac_context *mac, uint8_t *,
-						void *body);
+
+/**
+ * lim_process_auth_frame_no_session() - Process auth frame received from AP to
+ * which we are not connected currently.
+ * @mac: Pointer to global mac context
+ * @bd: Pointer to rx auth frame
+ * @body: Pointer to lim_msg->body_ptr
+ *
+ * This is possibly the pre-auth from the neighbor AP, in the same mobility
+ * domain or pre-authentication reply for WPA3 SAE roaming.
+ * This will be used in case of 11r FT.
+ */
+QDF_STATUS lim_process_auth_frame_no_session(struct mac_context *mac,
+					     uint8_t *bd, void *body);
 
 void lim_process_assoc_req_frame(struct mac_context *, uint8_t *, uint8_t, struct pe_session *);
 void lim_send_mlm_assoc_ind(struct mac_context *mac, tpDphHashNode sta,