[PATCH 12/15] NAN: Block data path operations during a schedule update
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Thu Oct 8 09:05:21 PDT 2026
Setting up a new NDL while schedule update is in progress is not
supported as the schedule is in transient state and can't be used for
NDL negotiation. Since nothing prevented it, it resulted in various
failures and unexpected behaviour.
Reject data path operations until the update completes, and indicate the
completion also for a non-deferred update, so that applications can
always wait for it before proceeding.
Update hwsim tests accordingly.
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
---
tests/hwsim/test_nan.py | 22 ++++++++-------
wpa_supplicant/nan_supplicant.c | 50 +++++++++++++++++++++++++++++++++
2 files changed, 62 insertions(+), 10 deletions(-)
diff --git a/tests/hwsim/test_nan.py b/tests/hwsim/test_nan.py
index e37e5c8d52..6cf84ad42f 100644
--- a/tests/hwsim/test_nan.py
+++ b/tests/hwsim/test_nan.py
@@ -1401,6 +1401,14 @@ def _nan_discover_service(pub, sub, service_name, pssi, sssi, ttl=None,
return pid, sid, paddr, saddr
+def _nan_schedule_config(dev, *chans, map_id=1):
+ """Configure a schedule map and wait until the update completes."""
+ dev.wpas.dump_monitor()
+ if "OK" not in dev.schedule_config(*chans, map_id=map_id):
+ raise Exception("Failed to configure schedule")
+ if dev.wpas.wait_event(["NAN-SCHEDULE-UPDATE-DONE"], timeout=2) is None:
+ raise Exception("NAN-SCHEDULE-UPDATE-DONE event not seen")
+
def _nan_ndp_request_and_accept(pub, sub, pid, sid, paddr, saddr, req_ssi,
resp_ssi, csid=None,
password=None, pwd_hex=None, pmk=None,
@@ -1415,9 +1423,7 @@ def _nan_ndp_request_and_accept(pub, sub, pid, sid, paddr, saddr, req_ssi,
"""
# Configure schedule on subscriber if needed
if configure_schedule:
- if "OK" not in sub.schedule_config((2437, "0e000000"),
- (5180, "f0ffffff")):
- raise Exception("Failed to configure schedule (sub)")
+ _nan_schedule_config(sub, (2437, "0e000000"), (5180, "f0ffffff"))
# NDP request
if "OK" not in sub.ndp_request(sub.ndi_name, sid, paddr, pid, req_ssi,
@@ -1445,12 +1451,9 @@ def _nan_ndp_request_and_accept(pub, sub, pid, sid, paddr, saddr, req_ssi,
if configure_schedule:
if counter:
- if "OK" not in pub.schedule_config((5745, "feffffff")):
- raise Exception("Failed to configure schedule (pub)")
+ _nan_schedule_config(pub, (5745, "feffffff"))
else:
- if "OK" not in pub.schedule_config((2437, "0e000000"),
- (5180, "f0ffffff")):
- raise Exception("Failed to configure schedule (pub)")
+ _nan_schedule_config(pub, (2437, "0e000000"), (5180, "f0ffffff"))
# Accept NDP request
accept_pwd = "WRONG_PWD" if wrong_pwd else password
@@ -1486,8 +1489,7 @@ def _nan_ndp_request_and_accept(pub, sub, pid, sid, paddr, saddr, req_ssi,
ndp_id = data['ndp_id']
init_ndi = data['init_ndi']
- if "OK" not in sub.schedule_config((5745, "feffffff")):
- raise Exception("Failed to configure schedule (sub)")
+ _nan_schedule_config(sub, (5745, "feffffff"))
if "OK" not in sub.ndp_response("accept", paddr, ndi=sub.ndi_name,
ndp_id=ndp_id, handle=sid,
diff --git a/wpa_supplicant/nan_supplicant.c b/wpa_supplicant/nan_supplicant.c
index bcc5c35b5b..4f7dd3e322 100644
--- a/wpa_supplicant/nan_supplicant.c
+++ b/wpa_supplicant/nan_supplicant.c
@@ -181,11 +181,26 @@ static void clear_sched_config(struct nan_schedule_config *sched_cfg)
}
+static void wpas_nan_sched_update_done_timeout(void *eloop_ctx,
+ void *timeout_ctx)
+{
+ struct wpa_supplicant *wpa_s = eloop_ctx;
+
+ wpas_notify_nan_sched_update_done(wpa_s, true);
+}
+
+
static void wpas_nan_stop_cb(void *ctx)
{
struct wpa_supplicant *wpa_s = ctx;
int i;
+ eloop_cancel_timeout(wpas_nan_sched_update_done_timeout, wpa_s, NULL);
+
+ /* A deferred update will never be completed by the driver now */
+ clear_sched_config(&wpa_s->nan_sched_update.sched);
+ nan_set_sched_update_pending(wpa_s->nan, false);
+
for (i = 0; i < MAX_NAN_RADIOS; i++) {
if (wpa_s->nan_sched[i].num_channels) {
wpa_drv_nan_config_schedule(wpa_s, i + 1, NULL);
@@ -1612,6 +1627,8 @@ void wpas_nan_deinit(struct wpa_supplicant *wpa_s)
if (!wpa_s || !wpa_s->nan)
return;
+ eloop_cancel_timeout(wpas_nan_sched_update_done_timeout, wpa_s, NULL);
+
for (i = 0; i < MAX_NAN_RADIOS; i++)
clear_sched_config(&wpa_s->nan_sched[i]);
@@ -2649,6 +2666,15 @@ int wpas_nan_sched_config_map(struct wpa_supplicant *wpa_s, const char *cmd)
sizeof(*sched_cfg));
os_memset(sched_cfg, 0, sizeof(*sched_cfg));
wpas_nan_update_local_schedule(wpa_s);
+
+ /*
+ * Notify about schedule update completion also for
+ * non-deferred case. For deferred updates the driver will
+ * generate the event. This allows the user to unconditionally
+ * wait for the event after configuring the schedule.
+ */
+ eloop_register_timeout(0, 0, wpas_nan_sched_update_done_timeout,
+ wpa_s, NULL);
}
/* Update CDW overwrite map_id for the specified band */
@@ -3183,6 +3209,12 @@ int wpas_nan_ndp_request(struct wpa_supplicant *wpa_s, char *cmd)
if (!wpas_nan_ndp_allowed(wpa_s))
return -1;
+ if (wpa_s->nan_sched_update.sched.deferred) {
+ wpa_printf(MSG_INFO,
+ "NAN: Local schedule update is pending");
+ return -1;
+ }
+
ndp.type = NAN_NDP_ACTION_REQ;
ndp.qos.min_slots = NAN_QOS_MIN_SLOTS_NO_PREF;
ndp.qos.max_latency = NAN_QOS_MAX_LATENCY_NO_PREF;
@@ -3418,6 +3450,12 @@ int wpas_nan_ndp_response(struct wpa_supplicant *wpa_s, char *cmd)
if (!wpas_nan_ndp_allowed(wpa_s))
return -1;
+ if (wpa_s->nan_sched_update.sched.deferred) {
+ wpa_printf(MSG_INFO,
+ "NAN: Local schedule update is pending");
+ return -1;
+ }
+
os_memset(&ndp, 0, sizeof(ndp));
ndp.type = NAN_NDP_ACTION_RESP;
@@ -3930,6 +3968,12 @@ int wpas_nan_bootstrap_request(struct wpa_supplicant *wpa_s, char *cmd)
u16 bootstrap_method = 0;
bool auth = false;
+ if (wpa_s->nan_sched_update.sched.deferred) {
+ wpa_printf(MSG_INFO,
+ "NAN: Local schedule update is pending");
+ return -1;
+ }
+
/* Parse peer address first */
if (hwaddr_aton(cmd, peer_nmi) < 0)
return -1;
@@ -4314,6 +4358,12 @@ int wpas_nan_pairing_start(struct wpa_supplicant *wpa_s, char *cmd)
bool auto_nik_exchange = true;
char *pos;
+ if (wpa_s->nan_sched_update.sched.deferred) {
+ wpa_printf(MSG_INFO,
+ "NAN: Local schedule update is pending");
+ return -1;
+ }
+
/* Parse peer address first */
if (hwaddr_aton(cmd, addr) < 0)
return -1;
--
2.53.0
More information about the Hostap
mailing list