[RFC v2 26/99] NAN: Reject NDLs with overlapping time bitmaps

Andrei Otcheretianski andrei.otcheretianski at intel.com
Tue Dec 23 03:51:30 PST 2025


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

Overlapping bitmaps are not allowed in the same availability attribute.
Reject NDL with INVALID_AVAILABILITY reason in such case.
While at it, change the APIs so the rejection reason code would be
propagated correctly.
---
 src/nan/nan_i.h    |  2 +-
 src/nan/nan_ndl.c  | 20 +++++++++++---------
 src/nan/nan_util.c | 20 ++++++++++++++++++--
 3 files changed, 30 insertions(+), 12 deletions(-)

diff --git a/src/nan/nan_i.h b/src/nan/nan_i.h
index edaf6910e2..a087d76f97 100644
--- a/src/nan/nan_i.h
+++ b/src/nan/nan_i.h
@@ -441,7 +441,7 @@ struct bitfield *nan_tbm_to_bf(struct nan_data *nan,
 			       struct nan_time_bitmap *tbm);
 struct bitfield *nan_sched_to_bf(struct nan_data *nan,
 				 struct dl_list *sched,
-				 u8 *map_id);
+				 u8 *map_id, enum nan_reason *reason);
 bool nan_sched_covered_by_avail_entry(struct nan_data *nan,
 				      struct nan_avail_entry *avail,
 				      struct bitfield *sched_bf,
diff --git a/src/nan/nan_ndl.c b/src/nan/nan_ndl.c
index cf95c5ebf4..60a650b23f 100644
--- a/src/nan/nan_ndl.c
+++ b/src/nan/nan_ndl.c
@@ -191,35 +191,36 @@ struct nan_ndl *nan_ndl_alloc(struct nan_data *nan)
 }
 
 
-static int nan_ndl_validate_peer_avail(struct nan_data *nan,
-				       struct nan_peer *peer)
+static bool nan_ndl_validate_peer_avail(struct nan_data *nan,
+					struct nan_peer *peer)
 {
 	struct nan_ndl *ndl = peer->ndl;
-	int ret;
+	bool ret;
 
 	/* first validate if immutable is covered by the availability map */
 	ret = nan_sched_covered_by_avail_entries(nan, &peer->info.avail_entries,
 						 ndl->immut_sched,
 						 ndl->immut_sched_len);
-	if (ret <= 0) {
+	if (!ret) {
 		wpa_printf(MSG_DEBUG,
 			   "NAN: Peer avail: Immutable is not covered by avail");
-		return -1;
+		return ret;
 	}
 
 	/* now validate NDC schedule is covered by the availability map */
 	ret = nan_sched_covered_by_avail_entries(nan, &peer->info.avail_entries,
 						 ndl->ndc_sched,
 						 ndl->ndc_sched_len);
-	if (ret <= 0) {
+	if (!ret) {
 		wpa_printf(MSG_DEBUG,
 			   "NAN: Peer avail: NDC is not covered by avail");
-		return -1;
+		return ret;
 	}
 
 	wpa_printf(MSG_DEBUG,
 		   "NAN: NDL: peer NDC and immutable are covered by avail");
-	return 0;
+
+	return ret;
 }
 
 
@@ -349,6 +350,7 @@ nan_ndl_match_sched_vs_common(struct nan_data *nan,
 	u8 map_id;
 	enum nan_ndl_ver verdict;
 	int ret;
+	enum nan_reason reason;
 
 	/* No constraints */
 	if (!sched || !sched_len)
@@ -363,7 +365,7 @@ nan_ndl_match_sched_vs_common(struct nan_data *nan,
 		return NAN_NDL_VER_SCHED_NONE;
 
 	/* Convert the schedule availability entries to map ID and bitfield */
-	sched_bf = nan_sched_to_bf(nan, &sched_entries, &map_id);
+	sched_bf = nan_sched_to_bf(nan, &sched_entries, &map_id, &reason);
 	nan_flush_avail_entries(&sched_entries);
 
 	/*
diff --git a/src/nan/nan_util.c b/src/nan/nan_util.c
index 096c7ad57f..c1e5996f0c 100644
--- a/src/nan/nan_util.c
+++ b/src/nan/nan_util.c
@@ -1028,6 +1028,7 @@ done:
  * @nan: NAN module context from nan_init()
  * @sched: List of availability entries representing the schedule entries
  * @map_id: On return would hold the map_id covered by the schedule entires
+ * @reason: In case of failure contains the reason.
  * Returns A bitfield representing the schedule on success; otherwise NULL
  *
  * Note: The function only supports converting a schedule where all map IDs are
@@ -1035,7 +1036,7 @@ done:
  */
 struct bitfield *nan_sched_to_bf(struct nan_data *nan,
 				 struct dl_list *sched,
-				 u8 *map_id)
+				 u8 *map_id, enum nan_reason *reason)
 {
 	struct bitfield *sched_bf = NULL;
 	struct nan_avail_entry *cur;
@@ -1052,6 +1053,7 @@ struct bitfield *nan_sched_to_bf(struct nan_data *nan,
 		} else if (cur->map_id != *map_id) {
 			wpa_printf(MSG_DEBUG,
 				   "NAN: No support for multiple maps");
+			*reason = NAN_REASON_RESOURCE_LIMITATION;
 			goto fail;
 		}
 
@@ -1059,6 +1061,7 @@ struct bitfield *nan_sched_to_bf(struct nan_data *nan,
 		if (!tmp) {
 			wpa_printf(MSG_DEBUG,
 				   "NAN: Failed to convert sched to bf");
+			*reason = NAN_REASON_UNSPECIFIED_REASON;
 			goto fail;
 		}
 
@@ -1069,11 +1072,20 @@ struct bitfield *nan_sched_to_bf(struct nan_data *nan,
 		} else {
 			int res;
 
+			if (bitfield_intersects(sched_bf, tmp)) {
+				wpa_printf(MSG_DEBUG,
+					   "NAN: Invalid availability: TBMs intersect");
+				*reason = NAN_REASON_INVALID_AVAILABILITY;
+				bitfield_free(tmp);
+				goto fail;
+			}
+
 			res = bitfield_union_in_place(sched_bf, tmp);
 			bitfield_free(tmp);
 			if (res) {
 				wpa_printf(MSG_DEBUG,
 					   "NAN: Failed to union sched bf");
+				*reason = NAN_REASON_UNSPECIFIED_REASON;
 				goto fail;
 			}
 		}
@@ -1214,6 +1226,7 @@ bool nan_sched_covered_by_avail_entries(struct nan_data *nan,
 	struct bitfield *sched_bf, *avail_bf;
 	u8 map_id;
 	bool ret = false;
+	enum nan_reason reason;
 
 	if (!sched || !sched_len)
 		return true;
@@ -1223,7 +1236,10 @@ bool nan_sched_covered_by_avail_entries(struct nan_data *nan,
 						 &sched_entries,
 						 sched, sched_len);
 
-	sched_bf = nan_sched_to_bf(nan, &sched_entries, &map_id);
+	sched_bf = nan_sched_to_bf(nan, &sched_entries, &map_id, &reason);
+	if (!sched_bf)
+		return false;
+
 	nan_flush_avail_entries(&sched_entries);
 
 	avail_bf = nan_sched_bf_from_avail_and_chan(nan, avail_entries,
-- 
2.49.0




More information about the Hostap mailing list