[PATCH 14/18] wpa_supplicant: Mark NDC channels as non-evac

Andrei Otcheretianski andrei.otcheretianski at intel.com
Mon Oct 12 08:46:48 PDT 2026


Set no_evac flag on NDC channels. This prevents the kernel from
evacuating these channels, which would break existing NDL's.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
---
 wpa_supplicant/driver_i.h       |  9 +++++
 wpa_supplicant/nan_supplicant.c | 67 +++++++++++++++++++++++++++++++++
 2 files changed, 76 insertions(+)

diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index 9122b9353b..27d0255689 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -1360,6 +1360,15 @@ static inline int wpa_drv_nan_config_schedule(struct wpa_supplicant *wpa_s,
 						  conf);
 }
 
+static inline int
+wpa_drv_nan_set_non_evac_channels(struct wpa_supplicant *wpa_s,
+				  struct nan_schedule_config *conf)
+{
+	if (!wpa_s->driver->nan_set_non_evac_channels)
+		return -1;
+	return wpa_s->driver->nan_set_non_evac_channels(wpa_s->drv_priv, conf);
+}
+
 static inline int
 wpa_drv_nan_config_peer_schedule(struct wpa_supplicant *wpa_s, const u8 *peer,
 				 u16 cdw, u8 sequence_id,
diff --git a/wpa_supplicant/nan_supplicant.c b/wpa_supplicant/nan_supplicant.c
index 39b61c84c8..46cae9df97 100644
--- a/wpa_supplicant/nan_supplicant.c
+++ b/wpa_supplicant/nan_supplicant.c
@@ -181,8 +181,70 @@ static void clear_sched_config(struct nan_schedule_config *sched_cfg)
 }
 
 
+static void wpas_nan_set_chan_no_evacuate(struct wpa_supplicant *wpa_s,
+					  int freq, bool no_evacuate)
+{
+	int i, j, ret;
+
+	for (i = 0; i < MAX_NAN_RADIOS; i++) {
+		struct nan_schedule_config *sched_cfg = &wpa_s->nan_sched[i];
+
+		for (j = 0; j < sched_cfg->num_channels; j++) {
+			if (sched_cfg->channels[j].freq != freq)
+				continue;
+
+			if (sched_cfg->channels[j].no_evacuate == no_evacuate)
+				return;
+
+			wpa_printf(MSG_DEBUG,
+				   "NAN: %s channel %d MHz as no_evacuate",
+				   no_evacuate ? "Marking" : "Unmarking",
+				   freq);
+
+			sched_cfg->channels[j].no_evacuate = no_evacuate;
+
+			/*
+			 * The command replaces the entire non-evacuable set,
+			 * so pushing a single map is only correct because the
+			 * callers never mark more than one channel.
+			 */
+			ret = wpa_drv_nan_set_non_evac_channels(wpa_s,
+								sched_cfg);
+			if (ret) {
+				sched_cfg->channels[j].no_evacuate =
+					!no_evacuate;
+				wpa_printf(MSG_ERROR,
+					   "NAN: Failed to %s no_evacuate for %d MHz: %d",
+					   no_evacuate ? "set" : "clear",
+					   freq, ret);
+			}
+
+			return;
+		}
+	}
+
+	wpa_printf(MSG_DEBUG,
+		   "NAN: Channel %d MHz is not part of the local schedule",
+		   freq);
+}
+
+
+/* A local schedule update clears the marking, so set it again for the NDC */
+static void wpas_nan_reapply_ndc_no_evacuate(struct wpa_supplicant *wpa_s)
+{
+	if (wpa_s->nan_ndc.valid)
+		wpas_nan_set_chan_no_evacuate(wpa_s, wpa_s->nan_ndc.freq,
+					      true);
+}
+
+
 static void wpas_nan_release_ndc(struct wpa_supplicant *wpa_s)
 {
+	/* Unmark the channel while the schedule is still configured */
+	if (wpa_s->nan_ndc.valid)
+		wpas_nan_set_chan_no_evacuate(wpa_s, wpa_s->nan_ndc.freq,
+					      false);
+
 	/* Also drops the state of an NDC that was selected but never used */
 	os_memset(&wpa_s->nan_ndc, 0, sizeof(wpa_s->nan_ndc));
 }
@@ -828,6 +890,7 @@ static void wpas_nan_store_peer_ndc(struct wpa_supplicant *wpa_s,
 			   " map_id=%u freq=%d MHz",
 			   MAC2STR(wpa_s->nan_ndc.id), local_map_id, freq);
 
+		wpas_nan_set_chan_no_evacuate(wpa_s, freq, true);
 		return;
 	}
 
@@ -847,6 +910,8 @@ static void wpas_nan_store_peer_ndc(struct wpa_supplicant *wpa_s,
 		   MACSTR " map_id=%u freq=%d MHz",
 		   MAC2STR(wpa_s->nan_ndc.id), wpa_s->nan_ndc.map_id,
 		   wpa_s->nan_ndc.freq);
+
+	wpas_nan_set_chan_no_evacuate(wpa_s, wpa_s->nan_ndc.freq, true);
 }
 
 
@@ -2829,6 +2894,7 @@ int wpas_nan_sched_config_map(struct wpa_supplicant *wpa_s, const char *cmd)
 		os_memcpy(&wpa_s->nan_sched[map_id - 1], sched_cfg,
 			  sizeof(*sched_cfg));
 		os_memset(sched_cfg, 0, sizeof(*sched_cfg));
+		wpas_nan_reapply_ndc_no_evacuate(wpa_s);
 		wpas_nan_update_local_schedule(wpa_s);
 
 		/*
@@ -4532,6 +4598,7 @@ void wpas_nan_sched_update_done(struct wpa_supplicant *wpa_s,
 		  sizeof(wpa_s->nan_sched_update.sched));
 	wpa_s->schedule_sequence_id++;
 
+	wpas_nan_reapply_ndc_no_evacuate(wpa_s);
 	wpas_nan_update_local_schedule(wpa_s);
 }
 
-- 
2.53.0




More information about the Hostap mailing list