Browse Source

qcacld-3.0: Process external auth command and set preauth node state

Hostapd sends SAE authentication status with the NL command
NL80211_CMD_EXTERNAL_AUTH. Extract status and peer mac address
from the command data and set mlmState in preauth node accordingly.

Change-Id: If507a2f56c031ae1885a11d5f7cbe31a18aa8821
CRs-Fixed: 2396366
Srinivas Dasari 6 years ago
parent
commit
e854ff0828

+ 6 - 3
core/hdd/src/wlan_hdd_cfg80211.c

@@ -20852,6 +20852,7 @@ __wlan_hdd_cfg80211_external_auth(struct wiphy *wiphy,
 	struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
 	int ret;
 	mac_handle_t mac_handle;
+	struct qdf_mac_addr peer_mac_addr;
 
 	if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
 		hdd_err("Command not allowed in FTM mode");
@@ -20865,10 +20866,12 @@ __wlan_hdd_cfg80211_external_auth(struct wiphy *wiphy,
 	if (ret)
 		return ret;
 
-
-	hdd_debug("external_auth status: %d", params->status);
+	hdd_debug("external_auth status: %d peer mac: " QDF_MAC_ADDR_STR,
+		  params->status, QDF_MAC_ADDR_ARRAY(params->bssid));
 	mac_handle = hdd_ctx->mac_handle;
-	sme_handle_sae_msg(mac_handle, adapter->vdev_id, params->status);
+	qdf_mem_copy(peer_mac_addr.bytes, params->bssid, QDF_MAC_ADDR_SIZE);
+	sme_handle_sae_msg(mac_handle, adapter->vdev_id, params->status,
+			   peer_mac_addr);
 
 	return ret;
 }

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

@@ -6061,12 +6061,14 @@ struct sir_sae_info {
  * @length: message length
  * @session_id: SME session id
  * @sae_status: SAE status, 0: Success, Non-zero: Failure.
+ * @peer_mac_addr: peer MAC address
  */
 struct sir_sae_msg {
 	uint16_t message_type;
 	uint16_t length;
 	uint16_t session_id;
 	uint8_t sae_status;
+	tSirMacAddr peer_mac_addr;
 };
 
 /**

+ 88 - 29
core/mac/src/pe/lim/lim_process_message_queue.c

@@ -65,6 +65,82 @@ static void lim_process_normal_hdd_msg(struct mac_context *mac_ctx,
 	struct scheduler_msg *msg, uint8_t rsp_reqd);
 
 #ifdef WLAN_FEATURE_SAE
+
+/**
+ * lim_process_sae_msg_sta() - Process SAE message for STA
+ * @mac: Global MAC pointer
+ * @session: Pointer to the PE session entry
+ * @sae_msg: SAE message buffer pointer
+ *
+ * Return: None
+ */
+static void lim_process_sae_msg_sta(struct mac_context *mac,
+				    struct pe_session *session,
+				    struct sir_sae_msg *sae_msg)
+{
+	switch (session->limMlmState) {
+	case eLIM_MLM_WT_SAE_AUTH_STATE:
+		/* SAE authentication is completed.
+		 * Restore from auth state
+		 */
+		if (tx_timer_running(&mac->lim.limTimers.sae_auth_timer))
+			lim_deactivate_and_change_timer(mac,
+							eLIM_AUTH_SAE_TIMER);
+		/* success */
+		if (sae_msg->sae_status == IEEE80211_STATUS_SUCCESS)
+			lim_restore_from_auth_state(mac,
+						    eSIR_SME_SUCCESS,
+						    eSIR_MAC_SUCCESS_STATUS,
+						    session);
+		else
+			lim_restore_from_auth_state(mac, eSIR_SME_AUTH_REFUSED,
+				eSIR_MAC_UNSPEC_FAILURE_STATUS, session);
+		break;
+	default:
+		/* SAE msg is received in unexpected state */
+		pe_err("received SAE msg in state %X", session->limMlmState);
+		lim_print_mlm_state(mac, LOGE, session->limMlmState);
+		break;
+	}
+}
+
+/**
+ * lim_process_sae_msg_ap() - Process SAE message
+ * @mac: Global MAC pointer
+ * @session: Pointer to the PE session entry
+ * @sae_msg: SAE message buffer pointer
+ *
+ * Return: None
+ */
+static void lim_process_sae_msg_ap(struct mac_context *mac,
+				   struct pe_session *session,
+				   struct sir_sae_msg *sae_msg)
+{
+	struct tLimPreAuthNode *sta_pre_auth_ctx;
+	/* Extract pre-auth context for the STA and move limMlmState
+	 * of preauth node to eLIM_MLM_AUTHENTICATED_STATE
+	 */
+	sta_pre_auth_ctx = lim_search_pre_auth_list(mac,
+						    sae_msg->peer_mac_addr);
+
+	if (!sta_pre_auth_ctx) {
+		pe_debug("No preauth node created for "
+			 QDF_MAC_ADDR_STR,
+			 QDF_MAC_ADDR_ARRAY(sae_msg->peer_mac_addr));
+		return;
+	}
+
+	if (sae_msg->sae_status == IEEE80211_STATUS_SUCCESS) {
+		sta_pre_auth_ctx->mlmState = eLIM_MLM_AUTHENTICATED_STATE;
+	} else {
+		pe_debug("SAE authentication failed for "
+			 QDF_MAC_ADDR_STR " status: %u",
+			 QDF_MAC_ADDR_ARRAY(sae_msg->peer_mac_addr),
+			 sae_msg->sae_status);
+		lim_delete_pre_auth_node(mac, sae_msg->peer_mac_addr);
+	}
+}
+
 /**
  * lim_process_sae_msg() - Process SAE message
  * @mac: Global MAC pointer
@@ -89,40 +165,23 @@ static void lim_process_sae_msg(struct mac_context *mac, struct sir_sae_msg *bod
 		return;
 	}
 
-	if (session->pePersona != QDF_STA_MODE) {
+	if (session->pePersona != QDF_STA_MODE &&
+	    session->pePersona != QDF_SAP_MODE) {
 		pe_err("SAE:Not supported in this mode %d",
 				session->pePersona);
 		return;
 	}
 
-	pe_debug("SAE:status %d limMlmState %d pePersona %d",
-		sae_msg->sae_status, session->limMlmState,
-		session->pePersona);
-	switch (session->limMlmState) {
-	case eLIM_MLM_WT_SAE_AUTH_STATE:
-		/* SAE authentication is completed. Restore from auth state */
-		if (tx_timer_running(&mac->lim.limTimers.sae_auth_timer))
-			lim_deactivate_and_change_timer(mac,
-				eLIM_AUTH_SAE_TIMER);
-		/* success */
-		if (sae_msg->sae_status == IEEE80211_STATUS_SUCCESS)
-			lim_restore_from_auth_state(mac,
-				eSIR_SME_SUCCESS,
-				eSIR_MAC_SUCCESS_STATUS,
-				session);
-		else
-			lim_restore_from_auth_state(mac,
-				eSIR_SME_AUTH_REFUSED,
-				eSIR_MAC_UNSPEC_FAILURE_STATUS,
-				session);
-		break;
-	default:
-		/* SAE msg is received in unexpected state */
-		pe_err("received SAE msg in state %X",
-			session->limMlmState);
-		lim_print_mlm_state(mac, LOGE, session->limMlmState);
-		break;
-	}
+	pe_debug("SAE:status %d limMlmState %d pePersona %d peer: "
+		 QDF_MAC_ADDR_STR, sae_msg->sae_status,
+		 session->limMlmState, session->pePersona,
+		 QDF_MAC_ADDR_ARRAY(sae_msg->peer_mac_addr));
+	if (LIM_IS_STA_ROLE(session))
+		lim_process_sae_msg_sta(mac, session, sae_msg);
+	else if (LIM_IS_AP_ROLE(session))
+		lim_process_sae_msg_ap(mac, session, sae_msg);
+	else
+		pe_debug("Unsupported interface");
 }
 #else
 static inline void lim_process_sae_msg(struct mac_context *mac, void *body)

+ 9 - 4
core/sme/inc/sme_api.h

@@ -2467,15 +2467,20 @@ QDF_STATUS sme_send_mgmt_tx(mac_handle_t mac_handle, uint8_t session_id,
  * @mac_handle: The handle returned by mac_open
  * @session_id: session id
  * @sae_status: status of SAE authentication
+ * @peer_mac_addr: mac address of the peer to be authenticated
  *
  * Return: QDF_STATUS
  */
-QDF_STATUS sme_handle_sae_msg(mac_handle_t mac_handle, uint8_t session_id,
-			      uint8_t sae_status);
+QDF_STATUS sme_handle_sae_msg(mac_handle_t mac_handle,
+			      uint8_t session_id,
+			      uint8_t sae_status,
+			      struct qdf_mac_addr peer_mac_addr);
 #else
 static inline
-QDF_STATUS sme_handle_sae_msg(mac_handle_t mac_handle, uint8_t session_id,
-			      uint8_t sae_status)
+QDF_STATUS sme_handle_sae_msg(mac_handle_t mac_handle,
+			      uint8_t session_id,
+			      uint8_t sae_status,
+			      struct qdf_mac_addr peer_mac_addr)
 {
 	return QDF_STATUS_SUCCESS;
 }

+ 11 - 5
core/sme/src/common/sme_api.c

@@ -14351,8 +14351,10 @@ int sme_get_sec20chan_freq_mhz(struct wlan_objmgr_vdev *vdev,
 }
 
 #ifdef WLAN_FEATURE_SAE
-QDF_STATUS sme_handle_sae_msg(mac_handle_t mac_handle, uint8_t session_id,
-			      uint8_t sae_status)
+QDF_STATUS sme_handle_sae_msg(mac_handle_t mac_handle,
+			      uint8_t session_id,
+			      uint8_t sae_status,
+			      struct qdf_mac_addr peer_mac_addr)
 {
 	QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
 	struct mac_context *mac = MAC_CONTEXT(mac_handle);
@@ -14369,9 +14371,13 @@ QDF_STATUS sme_handle_sae_msg(mac_handle_t mac_handle, uint8_t session_id,
 			sae_msg->length = sizeof(*sae_msg);
 			sae_msg->session_id = session_id;
 			sae_msg->sae_status = sae_status;
-			sme_debug("SAE: sae_status %d session_id %d",
-				sae_msg->sae_status,
-				sae_msg->session_id);
+			qdf_mem_copy(sae_msg->peer_mac_addr,
+				     peer_mac_addr.bytes,
+				     QDF_MAC_ADDR_SIZE);
+			sme_debug("SAE: sae_status %d session_id %d Peer: "
+				  MAC_ADDRESS_STR, sae_msg->sae_status,
+				  sae_msg->session_id,
+				  MAC_ADDR_ARRAY(sae_msg->peer_mac_addr));
 
 			sch_msg.type = eWNI_SME_SEND_SAE_MSG;
 			sch_msg.bodyptr = sae_msg;