[PATCH 65/97] NAN: Move local schedule from NDL data to global NAN data

Andrei Otcheretianski andrei.otcheretianski at intel.com
Tue Apr 28 13:06:06 PDT 2026


From: Avraham Stern <avraham.stern at intel.com>

The local schedule is copied to each peer's NDL data. This is
redundant as the local schedule is common. Move the local schedule
to the nan_data struct.

Signed-off-by: Avraham Stern <avraham.stern at intel.com>
---
 src/nan/nan.c     | 16 ++++++++++------
 src/nan/nan_i.h   |  4 ++--
 src/nan/nan_ndl.c | 49 ++++++++++++++++++++++++-----------------------
 3 files changed, 37 insertions(+), 32 deletions(-)

diff --git a/src/nan/nan.c b/src/nan/nan.c
index 1e8325a140..ed948b1a44 100644
--- a/src/nan/nan.c
+++ b/src/nan/nan.c
@@ -232,6 +232,7 @@ void nan_deinit(struct nan_data *nan)
 	pasn_initiator_pmksa_cache_deinit(nan->initiator_pmksa);
 	pasn_responder_pmksa_cache_deinit(nan->responder_pmksa);
 #endif /* CONFIG_PASN */
+	wpabuf_free(nan->sched.elems);
 	os_free(nan->cfg);
 	os_free(nan);
 }
@@ -372,6 +373,8 @@ void nan_flush(struct nan_data *nan)
 
 	nan->nan_started = 0;
 	nan_peer_clear_all(nan);
+	wpabuf_free(nan->sched.elems);
+	os_memset(&nan->sched, 0, sizeof(nan->sched));
 }
 
 
@@ -1992,7 +1995,7 @@ static int nan_action_rx_ndp(struct nan_data *nan, struct nan_peer *peer,
 	if (peer->ndp_setup.state == NAN_NDP_STATE_DONE &&
 	    peer->ndl->state == NAN_NDL_STATE_DONE) {
 		wpa_printf(MSG_DEBUG, "NAN: NAF: NDP setup done");
-		if (nan_configure_peer_schedule(nan, peer, &peer->ndl->sched) ||
+		if (nan_configure_peer_schedule(nan, peer, &nan->sched) ||
 		    nan_ndp_connected(nan, peer))
 			nan_ndp_disconnected(nan, peer,
 					     NAN_REASON_UNSPECIFIED_REASON,
@@ -2296,7 +2299,8 @@ int nan_tx_status(struct nan_data *nan, const u8 *dst, const u8 *data,
 	if (peer->ndp_setup.state == NAN_NDP_STATE_DONE &&
 	    peer->ndl->state == NAN_NDL_STATE_DONE) {
 		wpa_printf(MSG_DEBUG, "NAN: TX status: NDP setup done");
-		if (nan_configure_peer_schedule(nan, peer, &peer->ndl->sched) ||
+
+		if (nan_configure_peer_schedule(nan, peer, &nan->sched) ||
 		    nan_ndp_connected(nan, peer))
 			nan_ndp_disconnected(nan, peer,
 					     NAN_REASON_UNSPECIFIED_REASON,
@@ -2356,7 +2360,7 @@ int nan_handle_ndp_setup(struct nan_data *nan, struct nan_ndp_params *params)
 
 		naf_oui = NAN_SUBTYPE_DATA_PATH_REQUEST;
 		timeout = NAN_NDP_SETUP_TIMEOUT_LONG;
-		ret = nan_configure_peer_schedule(nan, peer, &peer->ndl->sched);
+		ret = nan_configure_peer_schedule(nan, peer, &nan->sched);
 		if (ret) {
 			nan_ndp_setup_stop(nan, peer);
 			return ret;
@@ -2378,8 +2382,8 @@ int nan_handle_ndp_setup(struct nan_data *nan, struct nan_ndp_params *params)
 			ret = nan_ndl_setup(nan, peer, params,
 					    peer->ndp_setup.dialog_token);
 			if (!ret) {
-				ret = nan_configure_peer_schedule(
-					nan, peer, &peer->ndl->sched);
+				ret = nan_configure_peer_schedule(nan, peer,
+								  &nan->sched);
 				if (ret)
 					peer->ndl->send_naf_on_error = 1;
 			}
@@ -2413,7 +2417,7 @@ int nan_handle_ndp_setup(struct nan_data *nan, struct nan_ndp_params *params)
 				    peer->ndp_setup.dialog_token);
 		if (!ret) {
 			ret = nan_configure_peer_schedule(nan, peer,
-							  &peer->ndl->sched);
+							  &nan->sched);
 			if (ret)
 				peer->ndl->send_naf_on_error = 1;
 		}
diff --git a/src/nan/nan_i.h b/src/nan/nan_i.h
index ff36fa04af..cf1c5819c1 100644
--- a/src/nan/nan_i.h
+++ b/src/nan/nan_i.h
@@ -390,7 +390,6 @@ enum nan_ndl_setup_reason {
  *     returned an error, a NAF still needs to be sent to the peer, i.e., the
  *     error cannot be silently ignored.
  * @reason: In case of status == NAN_NDL_STATUS_REJECTED, indicates the reason.
- * @sched: Holds the local schedule.
  * @dialog_token: The dialog token for the current NDL negotiation.
  * @max_idle_period: Indicate a period of time in units of 1024 TU during which
  *     the peer device can refrain from transmitting over the NDL without
@@ -409,7 +408,6 @@ struct nan_ndl {
 	enum nan_ndl_status status;
 	u8 send_naf_on_error;
 	enum nan_reason reason;
-	struct nan_schedule sched;
 
 	u8 dialog_token;
 	u16 max_idle_period;
@@ -575,6 +573,7 @@ struct nan_peer {
  *     and is used to set ndp_id in &struct nan_ndp.
  * @next_dialog_token: Dialog token for NDP and NDL negotiations. Incremented
  *     for each NDP and NDL request.
+ * @sched: Holds the local schedule. See &struct nan_schedule
  * @cluster_id: Current cluster ID
  * @nira_nonce: Nonce for NAN Identity Resolution attribute (NIRA)
  * @nira_tag: Tag for NAN Identity Resolution attribute (NIRA)
@@ -592,6 +591,7 @@ struct nan_data {
 
 	u8 ndp_id_counter;
 	u8 next_dialog_token;
+	struct nan_schedule sched;
 
 	u8 cluster_id[ETH_ALEN];
 
diff --git a/src/nan/nan_ndl.c b/src/nan/nan_ndl.c
index ca69b6ec06..d6cf1fa431 100644
--- a/src/nan/nan_ndl.c
+++ b/src/nan/nan_ndl.c
@@ -142,9 +142,6 @@ static void nan_ndl_clear(struct nan_data *nan, struct nan_peer *peer)
 	ndl->local_qos.max_latency = NAN_QOS_MAX_LATENCY_NO_PREF;
 
 	ndl->setup_reason = NAN_NDL_SETUP_REASON_NONE;
-
-	wpabuf_free(ndl->sched.elems);
-	os_memset(&ndl->sched, 0, sizeof(ndl->sched));
 }
 
 
@@ -345,7 +342,7 @@ static enum nan_ndl_status nan_ndl_determine_status(struct nan_data *nan,
 						    bool can_counter,
 						    enum nan_reason *reason)
 {
-	struct nan_schedule *sched = &peer->ndl->sched;
+	struct nan_schedule *sched = &nan->sched;
 	struct bitfield *common_bf = NULL, *ndc_bf = NULL, *track_ndc_bf = NULL;
 	enum nan_ndl_ver verdict;
 	size_t size, max_latency, i;
@@ -682,21 +679,23 @@ int nan_ndl_setup(struct nan_data *nan, struct nan_peer *peer,
 		goto out_fail;
 	}
 
-	wpabuf_free(ndl->sched.elems);
-	os_memcpy(&ndl->sched, &params->sched, sizeof(ndl->sched));
-	nan_ndl_sched_print(nan, &peer->ndl->sched);
+	wpabuf_free(nan->sched.elems);
+	os_memcpy(&nan->sched, &params->sched, sizeof(nan->sched));
+	nan_ndl_sched_print(nan, &nan->sched);
 
 	/* Copy elems buffer */
 	if (params->sched.elems) {
-		ndl->sched.elems =
+		nan->sched.elems =
 			wpabuf_alloc_copy(wpabuf_head(params->sched.elems),
 					  wpabuf_len(params->sched.elems));
-		if (!ndl->sched.elems) {
+		if (!nan->sched.elems) {
 			reason = NAN_REASON_UNSPECIFIED_REASON;
 			goto out_fail;
 		}
 	}
 
+	nan_ndl_sched_print(nan, &nan->sched);
+
 	if (is_zero_ether_addr(ndl->ndc_id)) {
 		os_get_random(ndl->ndc_id, ETH_ALEN);
 		wpa_printf(MSG_DEBUG,
@@ -1352,7 +1351,7 @@ int nan_ndl_add_avail_attrs(struct nan_data *nan, const struct nan_peer *peer,
 	if (!peer || !peer->ndl)
 		return -1;
 
-	sched = &peer->ndl->sched;
+	sched = &nan->sched;
 
 	wpa_printf(MSG_DEBUG,
 		   "NAN: NDL: Add Avail attribute. state=%s, status=%u",
@@ -1397,6 +1396,7 @@ int nan_ndl_add_ndl_attr(struct nan_data *nan, const struct nan_peer *peer,
 			 struct wpabuf *buf)
 {
 	struct nan_ndl *ndl;
+	struct nan_schedule *sched = &nan->sched;
 	u16 ndl_ctrl = 0;
 	u8 *len_ptr;
 	u8 type;
@@ -1426,18 +1426,18 @@ int nan_ndl_add_ndl_attr(struct nan_data *nan, const struct nan_peer *peer,
 		return -1;
 	case NAN_NDL_STATE_START:
 		type = NAN_NDL_TYPE_REQUEST;
-		if (ndl->sched.ndc.len)
+		if (sched->ndc.len)
 			ndl_ctrl |= NAN_NDL_CTRL_NDC_ATTR_PRESENT;
 		break;
 	case NAN_NDL_STATE_REQ_RECV:
 		type = NAN_NDL_TYPE_RESPONSE;
-		if (ndl->sched.ndc.len &&
+		if (sched->ndc.len &&
 		    ndl->status != NAN_NDL_STATUS_REJECTED)
 			ndl_ctrl |= NAN_NDL_CTRL_NDC_ATTR_PRESENT;
 		break;
 	case NAN_NDL_STATE_RES_RECV:
 		type = NAN_NDL_TYPE_CONFIRM;
-		if (ndl->sched.ndc.len &&
+		if (sched->ndc.len &&
 		    ndl->status != NAN_NDL_STATUS_REJECTED)
 			ndl_ctrl |= NAN_NDL_CTRL_NDC_ATTR_PRESENT;
 		break;
@@ -1480,6 +1480,7 @@ int nan_ndl_add_ndc_attr(struct nan_data *nan, const struct nan_peer *peer,
 			 struct wpabuf *buf)
 {
 	struct nan_ndl *ndl;
+	struct nan_schedule *sched = &nan->sched;
 	u8 ndc_ctrl = NAN_NDC_CTRL_SELECTED;
 	u16 sched_entry_ctrl = 0;
 
@@ -1504,7 +1505,7 @@ int nan_ndl_add_ndc_attr(struct nan_data *nan, const struct nan_peer *peer,
 	 * NDC attribute for NDP Request is optional. In all other cases it is
 	 * mandatory
 	 */
-	if (!ndl->sched.ndc.len) {
+	if (!sched->ndc.len) {
 		if (ndl->state != NAN_NDL_STATE_START) {
 			wpa_printf(MSG_DEBUG, "NAN: NDL: No NDC to add");
 			return -1;
@@ -1516,26 +1517,26 @@ int nan_ndl_add_ndc_attr(struct nan_data *nan, const struct nan_peer *peer,
 	wpabuf_put_u8(buf, NAN_ATTR_NDC);
 	wpabuf_put_le16(buf, sizeof(struct ieee80211_ndc) +
 			sizeof(struct nan_sched_entry) +
-			ndl->sched.ndc.len);
+			sched->ndc.len);
 
 	wpabuf_put_data(buf, ndl->ndc_id, sizeof(ndl->ndc_id));
 	wpabuf_put_u8(buf, ndc_ctrl);
 
 	/* Add the schedule entry */
-	wpabuf_put_u8(buf, ndl->sched.ndc_map_id);
+	wpabuf_put_u8(buf, sched->ndc_map_id);
 
-	sched_entry_ctrl |= ndl->sched.ndc.duration <<
+	sched_entry_ctrl |= sched->ndc.duration <<
 		NAN_TIME_BM_CTRL_BIT_DURATION_POS;
-	sched_entry_ctrl |= ndl->sched.ndc.period <<
+	sched_entry_ctrl |= sched->ndc.period <<
 		NAN_TIME_BM_CTRL_PERIOD_POS;
-	sched_entry_ctrl |= ndl->sched.ndc.offset <<
+	sched_entry_ctrl |= sched->ndc.offset <<
 		NAN_TIME_BM_CTRL_START_OFFSET_POS;
 
 	wpabuf_put_le16(buf, sched_entry_ctrl);
 
 	/* Add the time bitmap */
-	wpabuf_put_u8(buf, ndl->sched.ndc.len);
-	wpabuf_put_data(buf, ndl->sched.ndc.bitmap, ndl->sched.ndc.len);
+	wpabuf_put_u8(buf, sched->ndc.len);
+	wpabuf_put_data(buf, sched->ndc.bitmap, sched->ndc.len);
 
 	return 0;
 }
@@ -1692,7 +1693,7 @@ void nan_ndl_add_elem_container_attr(const struct nan_data *nan,
 {
 	const struct nan_ndl *ndl;
 
-	if (!peer || !peer->ndl || !peer->ndl->sched.elems)
+	if (!peer || !peer->ndl || !nan->sched.elems)
 		return;
 
 	ndl = peer->ndl;
@@ -1709,7 +1710,7 @@ void nan_ndl_add_elem_container_attr(const struct nan_data *nan,
 		return;
 
 	wpabuf_put_u8(buf, NAN_ATTR_ELEM_CONTAINER);
-	wpabuf_put_le16(buf, 1 + wpabuf_len(ndl->sched.elems));
+	wpabuf_put_le16(buf, 1 + wpabuf_len(nan->sched.elems));
 	wpabuf_put_u8(buf, 0);
-	wpabuf_put_buf(buf, ndl->sched.elems);
+	wpabuf_put_buf(buf, nan->sched.elems);
 }
-- 
2.53.0




More information about the Hostap mailing list