[PATCH 01/18] NAN: Counter or reject a peer NDC that spans multiple channels
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Mon Oct 12 08:46:35 PDT 2026
The NDC attribute carries a time bitmap only, without any channel. As
the bitmaps of different channels of an availability attribute may not
intersect, every NDC slot belongs to exactly one channel and the NDC
channels can be reconstructed from the peer availability.
Only a single channel NDC is supported. Until now a peer proposing an
NDC that spans several channels was silently reduced to the first one,
so the rest of its channels were not treated as NDC at all.
Counter such a proposal, so that the NDC can still be moved to a single
channel, and reject it when countering is not possible.
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
---
src/nan/nan_ndl.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 101 insertions(+)
diff --git a/src/nan/nan_ndl.c b/src/nan/nan_ndl.c
index 1511f55931..fe3367d708 100644
--- a/src/nan/nan_ndl.c
+++ b/src/nan/nan_ndl.c
@@ -378,6 +378,97 @@ bool nan_ndl_meets_qos(struct nan_data *nan, const struct nan_peer *peer,
}
+/*
+ * The NDC attribute carries a time bitmap only. Since the bitmaps of different
+ * channels of an availability attribute may not intersect, the channels used
+ * by the NDC can be reconstructed from the peer availability. Only a single
+ * channel NDC is supported.
+ */
+static bool nan_ndl_ndc_single_chan(struct nan_data *nan,
+ const struct nan_peer *peer)
+{
+ enum nan_reason reason = NAN_REASON_RESERVED;
+ const struct nan_ndl *ndl = peer->ndl;
+ const struct nan_chan_entry *ndc_chan = NULL;
+ struct nan_avail_entry *avail;
+ struct dl_list sched_entries;
+ struct bitfield *ndc_bf;
+ bool single_chan = true;
+ u8 ndc_map_id;
+
+ if (!ndl->ndc_sched || !ndl->ndc_sched_len)
+ return true;
+
+ if (nan_sched_entries_to_avail_entries(nan, &sched_entries,
+ ndl->ndc_sched,
+ ndl->ndc_sched_len))
+ return false;
+
+ ndc_bf = nan_sched_to_bf(nan, &sched_entries, &ndc_map_id, &reason);
+ nan_flush_avail_entries(&sched_entries);
+ if (!ndc_bf) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: NDL: Failed to convert the NDC schedule: reason=%u",
+ reason);
+ return false;
+ }
+
+ dl_list_for_each(avail, &peer->info.avail_entries,
+ struct nan_avail_entry, list) {
+ const struct nan_chan_entry *chan;
+ struct bitfield *avail_bf;
+
+ if (avail->map_id != ndc_map_id ||
+ avail->band_chan_type != NAN_TYPE_CHANNEL ||
+ avail->n_band_chan < 1)
+ continue;
+
+ if (avail->type != NAN_AVAIL_ENTRY_CTRL_TYPE_COMMITTED &&
+ avail->type != NAN_AVAIL_ENTRY_CTRL_TYPE_COND)
+ continue;
+
+ avail_bf = nan_tbm_to_bf(nan, &avail->tbm);
+ if (!avail_bf) {
+ wpa_printf(MSG_INFO,
+ "NAN: NDL: Failed to convert a peer availability time bitmap");
+ bitfield_free(ndc_bf);
+ return false;
+ }
+
+ /*
+ * A committed and a conditional entry may advertise the same
+ * channel for complementing slots, so the intersecting entries
+ * cannot simply be counted. Compare the channel of each one to
+ * the channel of the first intersecting entry instead.
+ */
+ chan = &avail->band_chan[0].u.chan;
+
+ if (bitfield_intersects(ndc_bf, avail_bf)) {
+ if (!ndc_chan)
+ ndc_chan = chan;
+ else if (chan->op_class != ndc_chan->op_class ||
+ chan->chan_bitmap != ndc_chan->chan_bitmap ||
+ chan->pri_chan_bitmap !=
+ ndc_chan->pri_chan_bitmap)
+ single_chan = false;
+ }
+
+ bitfield_free(avail_bf);
+
+ if (!single_chan)
+ break;
+ }
+
+ bitfield_free(ndc_bf);
+
+ if (!single_chan)
+ wpa_printf(MSG_INFO,
+ "NAN: NDL: NDC spans multiple channels - not supported");
+
+ return single_chan;
+}
+
+
static enum nan_ndl_status nan_ndl_determine_status(struct nan_data *nan,
struct nan_peer *peer,
bool can_counter,
@@ -558,6 +649,16 @@ static enum nan_ndl_status nan_ndl_determine_status(struct nan_data *nan,
goto out;
}
+ /*
+ * Only a single channel NDC is supported. Counter such a proposal, so
+ * that the NDC can be moved to a single channel.
+ */
+ if (!nan_ndl_ndc_single_chan(nan, peer)) {
+ *reason = NAN_REASON_NDL_UNACCEPTABLE;
+ ret = NAN_NDL_STATUS_CONTINUED;
+ goto out;
+ }
+
/*
* In case the peer included an NDC, check if it is identical to
* the locally generated one.
--
2.53.0
More information about the Hostap
mailing list