[RFC 24/56] NAN: Add validation of peer availability
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Sun Dec 7 03:18:33 PST 2025
From: Ilan Peer <ilan.peer at intel.com>
After processing the NDL related attributes, and before
the flow continues to handle the data, validate that the
availability information is valid:
1. Parse the availability attributes.
2. Validate that the immutable schedule is covered by the
availability attributes.
3. Validate that the NDC schedule is covered by the
availability attributes.
Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
src/nan/nan_i.h | 4 ++
src/nan/nan_ndl.c | 55 +++++++++++++++++++++++++-
src/nan/nan_util.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 155 insertions(+), 2 deletions(-)
diff --git a/src/nan/nan_i.h b/src/nan/nan_i.h
index 90d6cec654..6f3cfdb77b 100644
--- a/src/nan/nan_i.h
+++ b/src/nan/nan_i.h
@@ -446,4 +446,8 @@ bool nan_sched_covered_by_avail_entry(struct nan_data *nan,
struct nan_avail_entry *avail,
struct bitfield *sched_bf,
u8 map_id);
+int nan_sched_covered_by_avail_entries(struct nan_data *nan,
+ struct dl_list *avail_entries,
+ u8 *sched,
+ u8 sched_len);
#endif
diff --git a/src/nan/nan_ndl.c b/src/nan/nan_ndl.c
index ec0d6e2283..db03cda12f 100644
--- a/src/nan/nan_ndl.c
+++ b/src/nan/nan_ndl.c
@@ -190,6 +190,38 @@ 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)
+{
+ struct nan_ndl *ndl = peer->ndl;
+ int 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) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Peer avail: Immutable is not covered by avail");
+ return -1;
+ }
+
+ /* 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) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Peer avail: NDC is not covered by avail");
+ return -1;
+ }
+
+ wpa_printf(MSG_DEBUG,
+ "NAN: NDL: peer NDC and immutable are covered by avail");
+ return 0;
+}
+
+
static enum nan_ndl_status nan_ndl_res_status(struct nan_data *nan,
struct nan_peer *peer)
{
@@ -399,6 +431,7 @@ static int nan_ndl_attr_handle_req(struct nan_data *nan, struct nan_peer *peer,
const struct ndl_attr_params *params)
{
struct nan_ndl *ndl;
+ int ret;
wpa_printf(MSG_DEBUG, "NAN: NDL: Handle request");
@@ -460,6 +493,10 @@ static int nan_ndl_attr_handle_req(struct nan_data *nan, struct nan_peer *peer,
ndl->immut_sched_len = params->immut_sched_len;
}
+ ret = nan_ndl_validate_peer_avail(nan, peer);
+ if (!ret)
+ goto fail;
+
nan_ndl_set_state(nan, ndl, NAN_NDL_STATE_REQ_RECV);
wpa_printf(MSG_DEBUG, "NAN: NDL: Handle request done");
@@ -474,6 +511,7 @@ static int nan_ndl_attr_handle_resp(struct nan_data *nan, struct nan_peer *peer,
const struct ndl_attr_params *params)
{
struct nan_ndl *ndl = peer->ndl;
+ int ret;
wpa_printf(MSG_DEBUG, "NAN: NDL: Handle response");
@@ -548,6 +586,7 @@ static int nan_ndl_attr_handle_resp(struct nan_data *nan, struct nan_peer *peer,
if (!ndl->ndc_sched) {
wpa_printf(MSG_DEBUG,
"NAN: NDL: Resp: Failed to allocate NDC schedule");
+ ret = -1;
goto fail;
}
@@ -568,11 +607,16 @@ static int nan_ndl_attr_handle_resp(struct nan_data *nan, struct nan_peer *peer,
if (!ndl->immut_sched) {
wpa_printf(MSG_DEBUG,
"NAN: NDL: Resp: fail allocate immutable schedule");
+ ret = -1;
goto fail;
}
ndl->immut_sched_len = params->immut_sched_len;
}
+ ret = nan_ndl_validate_peer_avail(nan, peer);
+ if (!ret)
+ goto fail;
+
wpa_printf(MSG_DEBUG, "NAN: NDL: Resp: status=%u", params->status);
ndl->status = params->status;
@@ -585,7 +629,7 @@ fail:
ndl->status = NAN_NDL_STATUS_REJECTED;
ndl->reason = NAN_REASON_RESOURCE_LIMITATION;
ndl->send_naf_on_error = 1;
- return 0;
+ return ret;
}
@@ -593,6 +637,7 @@ static int nan_ndl_attr_handle_conf(struct nan_data *nan, struct nan_peer *peer,
const struct ndl_attr_params *params)
{
struct nan_ndl *ndl = peer->ndl;
+ int ret;
if (!ndl) {
wpa_printf(MSG_DEBUG,
@@ -660,6 +705,7 @@ static int nan_ndl_attr_handle_conf(struct nan_data *nan, struct nan_peer *peer,
if (!ndl->ndc_sched) {
wpa_printf(MSG_DEBUG,
"NAN: NDL: Failed to allocate NDC schedule");
+ ret = -1;
goto fail;
}
ndl->ndc_sched_len = params->ndc_sched_len;
@@ -677,18 +723,23 @@ static int nan_ndl_attr_handle_conf(struct nan_data *nan, struct nan_peer *peer,
if (!ndl->immut_sched) {
wpa_printf(MSG_DEBUG,
"NAN: NDL: Failed to allocate immutable schedule");
+ ret = -1;
goto fail;
}
ndl->immut_sched_len = params->immut_sched_len;
}
+ ret = nan_ndl_validate_peer_avail(nan, peer);
+ if (!ret)
+ goto fail;
+
nan_ndl_set_state(nan, ndl, NAN_NDL_STATE_DONE);
return 0;
fail:
ndl->reason = NAN_REASON_RESOURCE_LIMITATION;
ndl->send_naf_on_error = 1;
- return -1;
+ return ret;
}
diff --git a/src/nan/nan_util.c b/src/nan/nan_util.c
index 946aed0412..ced188fc47 100644
--- a/src/nan/nan_util.c
+++ b/src/nan/nan_util.c
@@ -1135,3 +1135,101 @@ bool nan_sched_covered_by_avail_entry(struct nan_data *nan,
return ret == 1;
}
+
+
+static int nan_sched_bf_covered_by_avail_entries(struct nan_data *nan,
+ struct dl_list *avail_entries,
+ struct bitfield *sched_bf,
+ u8 map_id)
+{
+ struct nan_avail_entry *avail;
+ struct bitfield *res_bf = NULL;
+ int ret = 0;
+
+ dl_list_for_each(avail, avail_entries, struct nan_avail_entry,
+ list) {
+ struct bitfield *avail_bf;
+
+ if (avail->map_id != map_id)
+ continue;
+
+ /* schedule can only be covered by committed/conditional */
+ if (avail->type != NAN_AVAIL_ENTRY_CTRL_TYPE_COMMITTED &&
+ avail->type != NAN_AVAIL_ENTRY_CTRL_TYPE_COND)
+ continue;
+
+ /* convert the availability entry to bf */
+ avail_bf = nan_tbm_to_bf(nan, &avail->tbm);
+ if (!avail_bf) {
+ ret = -1;
+ goto fail;
+ }
+
+ bitfield_dump(avail_bf, "NAN: Availability entry bitmap");
+ if (!res_bf) {
+ res_bf = avail_bf;
+ } else {
+ struct bitfield *tmp_bf;
+
+ tmp_bf = bitfield_union(res_bf, avail_bf);
+ bitfield_free(avail_bf);
+
+ if (!tmp_bf) {
+ ret = -1;
+ goto fail;
+ }
+
+ bitfield_free(res_bf);
+ res_bf = tmp_bf;
+ }
+ }
+
+ ret = bitfield_is_subset(res_bf, sched_bf);
+fail:
+ wpa_printf(MSG_DEBUG,
+ "NAN: Is bitfield schedule subset of entries=%d", ret);
+ bitfield_free(res_bf);
+ return ret;
+}
+
+
+/**
+ * nan_sched_covered_by_avail_entries - Check if schedule is covered by the
+ * list of availability attributes
+ *
+ * @nan: NAN module context from nan_init()
+ * @avail_entries: A list of availability entries (see &struct nan_avail_entry)
+ * @sched: An array with 0 or more &struct nan_sched_entry entries
+ * @sched_len: Length of the &sched array
+ * Returns 1 of schedule is covered by the entries; 0 if not and -1 on error
+ */
+int nan_sched_covered_by_avail_entries(struct nan_data *nan,
+ struct dl_list *avail_entries,
+ u8 *sched,
+ u8 sched_len)
+{
+ struct dl_list sched_entries;
+ struct bitfield *sched_bf;
+ u8 map_id;
+ int ret;
+
+ if (!sched || !sched_len)
+ return 1;
+
+ dl_list_init(&sched_entries);
+ ret = nan_sched_entries_to_avail_entries(nan,
+ &sched_entries,
+ sched, sched_len);
+
+ sched_bf = nan_sched_to_bf(nan, &sched_entries, &map_id);
+ nan_flush_avail_entries(&sched_entries);
+
+ ret = nan_sched_bf_covered_by_avail_entries(nan, avail_entries,
+ sched_bf, map_id);
+
+ wpa_printf(MSG_DEBUG,
+ "NAN: NDC schedule is %s a subset of entries",
+ ret == 1 ? "" : "NOT");
+ bitfield_free(sched_bf);
+ return ret;
+}
--
2.49.0
More information about the Hostap
mailing list