[PATCH 06/92] nl80211: Track cookies for NAN Device action frames

Andrei Otcheretianski andrei.otcheretianski at intel.com
Wed Apr 22 05:22:57 PDT 2026


From: Ilan Peer <ilan.peer at intel.com>

Multiple action frames can be sent over a NAN Device interface
simultaneously, especially in cases that the NAN Discovery
Engine (DE) is not managed in the device.

As the cookie tracking for ACK processing was only tracking
the last sent action frame, Tx status events for previously
sent action frames where not forwarded for processing in
higher layers (due to a cookie mismatch).

Fix this by extending the existing tracking of cookies for
wait cancellation to also track multiple cookies for NAN Device.

Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
 src/drivers/driver_nl80211.c       | 23 ++++++++++++++-----
 src/drivers/driver_nl80211_event.c | 37 +++++++++++++++++++++++++++---
 2 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index e87aecc58d..6394844341 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -9770,14 +9770,21 @@ static int nl80211_send_frame_cmd(struct i802_bss *bss,
 			   "cookie 0x%llx", no_ack ? " (no ACK)" : "",
 			   (long long unsigned int) cookie);
 
-		if (save_cookie)
-			drv->send_frame_cookie = no_ack ? (u64) -1 : cookie;
+		if (drv->nlmode == NL80211_IFTYPE_NAN_DATA || no_ack)
+			drv->send_frame_cookie = (u64)-1;
+		else if (save_cookie)
+			drv->send_frame_cookie = cookie;
 
-		if (!wait) {
-			 /* There is no need to store this cookie since there
-			  * is no wait that could be canceled later.  */
+		/*
+		 * Store the cookie only in case there is a wait that needs to
+		 * be cancelled later or in case of a NAN Device interface,
+		 * where multiple action frames might be sent, specifically in
+		 * cases that the NAN Discovery Engine (NAN DE) is not managed
+		 * by the device.
+		 */
+		if (!wait && drv->nlmode != NL80211_IFTYPE_NAN)
 			goto fail;
-		}
+
 		if (drv->num_send_frame_cookies == MAX_SEND_FRAME_COOKIES) {
 			wpa_printf(MSG_DEBUG,
 				   "nl80211: Drop oldest pending send frame cookie 0x%llx",
@@ -9911,6 +9918,10 @@ static void wpa_driver_nl80211_send_action_cancel_wait(void *priv)
 	unsigned int i;
 	u64 cookie;
 
+	/* As there are no waits for NAN Device, nothing to do here */
+	if (drv->nlmode == NL80211_IFTYPE_NAN)
+		return;
+
 	/* Cancel the last pending TX cookie */
 	if (drv->send_frame_cookie != (u64) -1)
 		nl80211_frame_wait_cancel(bss, drv->send_frame_cookie);
diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c
index 2fa1035554..fe991b0b39 100644
--- a/src/drivers/driver_nl80211_event.c
+++ b/src/drivers/driver_nl80211_event.c
@@ -1500,15 +1500,46 @@ static void mlme_event_mgmt_tx_status(struct i802_bss *bss,
 
 	if (!is_ap_interface(drv->nlmode) &&
 	    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION) {
+		bool known = false;
+
 		if (!cookie)
 			return;
 
+		if (cookie_val == drv->send_frame_cookie) {
+			known = true;
+			drv->send_frame_cookie = (u64)-1;
+		}
+
+		if (drv->nlmode == NL80211_IFTYPE_NAN &&
+		    drv->num_send_frame_cookies > 0) {
+			unsigned int i;
+
+			/*
+			 * Check the cookie is stored for previously sent
+			 * frames. If it is found, remove it and in case of NAN
+			 * mark it as known
+			 */
+			for (i = 0; i < drv->num_send_frame_cookies; i++) {
+				if (cookie_val != drv->send_frame_cookies[i])
+					continue;
+
+				if (i < drv->num_send_frame_cookies - 1)
+					os_memmove(&drv->send_frame_cookies[i],
+						   &drv->send_frame_cookies[i + 1],
+						   (drv->num_send_frame_cookies - i - 1) * sizeof(u64));
+
+				drv->num_send_frame_cookies--;
+				known = true;
+				break;
+			}
+		}
+
 		wpa_printf(MSG_DEBUG,
 			   "nl80211: Frame TX status: cookie=0x%llx%s (ack=%d)",
 			   (long long unsigned int) cookie_val,
-			   cookie_val == drv->send_frame_cookie ?
-			   " (match)" : " (unknown)", ack != NULL);
-		if (cookie_val != drv->send_frame_cookie)
+			   known ? " (match)" : " (unknown)", ack != NULL);
+
+		if (!known)
 			return;
 	} else if (!is_ap_interface(drv->nlmode) &&
 		   WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_AUTH) {
-- 
2.53.0




More information about the Hostap mailing list