Selaa lähdekoodia

qcacld-3.0: Don't process SAE address conversion for non-ml STA

In the case of an ML SAP SAE connection, if the reference
STA is a non-ML, the driver should not perform SAE address
conversion. Currently, during SAE Auth commit RX, if the
ML IE is not present in the frame, the driver decodes an
incorrect peer MLD address and saves it in the pre-auth
node structure. Later, userspace sends the SAE Auth commit
TX frame, and the driver fails during pre-auth node search
due to the incorrect MLD address saved in the pre-auth node,
which leads to SAP connection failure.

As part of the fix, the driver should decode the correct
peer MLD address or set it to 0 if the ML IE is not present.

Change-Id: I335361dca50969c7ee25a502732ae3f29cc99eff
CRs-Fixed: 3481176
Deeksha Gupta 1 vuosi sitten
vanhempi
sitoutus
18a512bff8

+ 2 - 0
core/hdd/src/wlan_hdd_assoc.c

@@ -318,6 +318,8 @@ wlan_hdd_sae_update_mld_addr(struct cfg80211_external_auth_params *params,
 	}
 
 	qdf_mem_copy(params->mld_addr, mld_addr.bytes, QDF_MAC_ADDR_SIZE);
+	hdd_debug("Sending MLD:" QDF_MAC_ADDR_FMT" to userspace",
+		  QDF_MAC_ADDR_REF(mld_addr.bytes));
 
 end:
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_HDD_ID_OBJ_MGR);

+ 30 - 10
core/mac/src/pe/lim/lim_process_auth_frame.c

@@ -508,13 +508,15 @@ static QDF_STATUS lim_skip_sae_fixed_field(uint8_t *body_ptr,
 /**
  * lim_get_sta_mld_address: This API is called to get the STA MLD address
  * from SAE 1st auth frame.
+ * @vdev: vdev
  * @body_ptr: Pointer to a SAE auth frame
  * @frame_len: Length of SAE auth frame
  * @peer_mld: fill peer MLD address
  *
  * Return: void
  */
-static void lim_get_sta_mld_address(uint8_t *body_ptr, uint32_t frame_len,
+static void lim_get_sta_mld_address(struct wlan_objmgr_vdev *vdev,
+				    uint8_t *body_ptr, uint32_t frame_len,
 				    struct qdf_mac_addr *peer_mld)
 {
 	uint8_t *ie_ptr = NULL;
@@ -523,14 +525,21 @@ static void lim_get_sta_mld_address(uint8_t *body_ptr, uint32_t frame_len,
 	qdf_size_t ie_len = 0;
 	QDF_STATUS status;
 
+	if (!wlan_cm_is_sae_auth_addr_conversion_required(vdev))
+		return;
+
 	status = lim_skip_sae_fixed_field(body_ptr, frame_len, &ie_ptr,
 					  &ie_len);
-	if (QDF_IS_STATUS_ERROR(status))
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pe_debug("Failed in skip SAE field");
 		return;
+	}
 
 	status = util_find_mlie(ie_ptr, ie_len, &ml_ie, &ml_ie_total_len);
-	if (QDF_IS_STATUS_ERROR(status))
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pe_debug("ML IE not found");
 		return;
+	}
 
 	util_get_bvmlie_mldmacaddr(ml_ie, ml_ie_total_len, peer_mld);
 }
@@ -566,6 +575,10 @@ static QDF_STATUS lim_update_link_to_mld_address(struct mac_context *mac_ctx,
 		if (!pre_auth_node)
 			return QDF_STATUS_E_INVAL;
 
+		if (qdf_is_macaddr_zero(
+			(struct qdf_mac_addr *)pre_auth_node->peer_mld))
+			return QDF_STATUS_SUCCESS;
+
 		qdf_mem_copy(mac_hdr->sa, pre_auth_node->peer_mld,
 			     QDF_MAC_ADDR_SIZE);
 		qdf_mem_copy(mac_hdr->bssId, self_mld_addr->bytes,
@@ -600,7 +613,8 @@ static QDF_STATUS lim_update_link_to_mld_address(struct mac_context *mac_ctx,
 	return QDF_STATUS_SUCCESS;
 }
 #else
-static void lim_get_sta_mld_address(uint8_t *body_ptr, uint32_t frame_len,
+static void lim_get_sta_mld_address(struct wlan_objmgr_vdev *vdev,
+				    uint8_t *body_ptr, uint32_t frame_len,
 				    struct qdf_mac_addr *peer_mld)
 {
 }
@@ -648,7 +662,7 @@ static void lim_process_sae_auth_frame(struct mac_context *mac_ctx,
 
 	if (LIM_IS_AP_ROLE(pe_session)) {
 		struct tLimPreAuthNode *pre_auth_node;
-		struct qdf_mac_addr peer_mld;
+		struct qdf_mac_addr peer_mld = {0};
 
 		rx_flags = RXMGMT_FLAG_EXTERNAL_AUTH;
 		/* Add preauth node when the first SAE authentication frame
@@ -675,8 +689,8 @@ static void lim_process_sae_auth_frame(struct mac_context *mac_ctx,
 			 * For the 1st SAE RX frame,
 			 * driver does not need to convert it in mld_address.
 			 */
-			lim_get_sta_mld_address(body_ptr, frame_len,
-						&peer_mld);
+			lim_get_sta_mld_address(pe_session->vdev, body_ptr,
+						frame_len, &peer_mld);
 			lim_external_auth_add_pre_auth_node(mac_ctx, mac_hdr,
 						eLIM_MLM_WT_SAE_AUTH_STATE,
 						&peer_mld);
@@ -688,8 +702,11 @@ static void lim_process_sae_auth_frame(struct mac_context *mac_ctx,
 			status = lim_update_link_to_mld_address(mac_ctx,
 								pe_session->vdev,
 								mac_hdr);
-			if (QDF_IS_STATUS_ERROR(status))
+			if (QDF_IS_STATUS_ERROR(status)) {
+				pe_debug("SAE address conversion failure with status:%d",
+					 status);
 				return;
+			}
 		}
 	}
 
@@ -707,8 +724,11 @@ static void lim_process_sae_auth_frame(struct mac_context *mac_ctx,
 		status = lim_update_link_to_mld_address(mac_ctx,
 							pe_session->vdev,
 							mac_hdr);
-		if (QDF_IS_STATUS_ERROR(status))
+		if (QDF_IS_STATUS_ERROR(status)) {
+			pe_debug("SAE address conversion failure with status:%d",
+				 status);
 			return;
+		}
 
 		auth_algo = *(uint16_t *)body_ptr;
 		if (frame_len >= (SAE_AUTH_STATUS_CODE_OFFSET + 2)) {
@@ -2165,7 +2185,7 @@ bool lim_process_sae_preauth_frame(struct mac_context *mac, uint8_t *rx_pkt)
 	}
 
 	if (QDF_IS_STATUS_ERROR(status)) {
-		pe_err("dropping the auth frame for vdev id: %d and BSSID " QDF_MAC_ADDR_FMT,
+		pe_err("dropping the auth frame for vdev id: %d and BSSID " QDF_MAC_ADDR_FMT ", SAE address conversion failure",
 		       vdev_id, QDF_MAC_ADDR_REF(dot11_hdr->bssId));
 		return false;
 	}

+ 18 - 3
core/mac/src/pe/lim/lim_send_management_frames.c

@@ -6751,8 +6751,21 @@ static QDF_STATUS lim_update_mld_to_link_address(struct mac_context *mac_ctx,
 		pre_auth_node =
 			lim_search_pre_auth_list_by_mld_addr(mac_ctx,
 							     mac_hdr->da);
-		if (!pre_auth_node)
-			return QDF_STATUS_E_INVAL;
+		if (!pre_auth_node) {
+			/**
+			 * Using MLD address, if pre_auth_node is not present then
+			 * check for peer mac address due to legacy connection.
+			 */
+			pre_auth_node = lim_search_pre_auth_list(mac_ctx,
+								 mac_hdr->da);
+			if (!pre_auth_node) {
+				pe_err("pre_auth not found by MLD: "QDF_MAC_ADDR_FMT,
+				       QDF_MAC_ADDR_REF(mac_hdr->da));
+				return QDF_STATUS_E_INVAL;
+			} else {
+				return QDF_STATUS_SUCCESS;
+			}
+		}
 
 		qdf_mem_copy(mac_hdr->da, pre_auth_node->peerMacAddr,
 			     QDF_MAC_ADDR_SIZE);
@@ -6822,8 +6835,10 @@ void lim_send_frame(struct mac_context *mac_ctx, uint8_t vdev_id, uint8_t *buf,
 	status = lim_update_mld_to_link_address(mac_ctx, vdev, mac_hdr);
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
 
-	if (QDF_IS_STATUS_ERROR(status))
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pe_err("SAE address conversion failure with status:%d", status);
 		return;
+	}
 
 	lim_add_mgmt_seq_num(mac_ctx, mac_hdr);
 	qdf_status = cds_packet_alloc(buf_len, (void **)&frame,