[PATCH 3/5] NAN: Handle removal of NAN interfaces

Andrei Otcheretianski andrei.otcheretianski at intel.com
Tue May 12 23:59:05 PDT 2026


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

When the driver notifies that a NAN Data interface is
removed, terminate all the NDPs which are associated
with the interface. If the interface was dynamically
added by upper layers, remove it.

If a NAN management interface that was dynamically
added is removed, remove it (NAN functionality is
stopped when the interface is disabled).

Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
 src/nan/nan.c                   | 28 ++++++++++++++++++++++++++++
 src/nan/nan.h                   |  2 ++
 wpa_supplicant/events.c         | 24 ++++++++++++++++++++++++
 wpa_supplicant/nan_supplicant.c | 15 +++++++++++++++
 wpa_supplicant/nan_supplicant.h |  1 +
 5 files changed, 70 insertions(+)

diff --git a/src/nan/nan.c b/src/nan/nan.c
index 29c6eed457..cacbb2c869 100644
--- a/src/nan/nan.c
+++ b/src/nan/nan.c
@@ -3622,3 +3622,31 @@ int nan_peer_dump_ndps_to_buf(struct nan_data *nan, const u8 *addr,
 
 	return pos - buf;
 }
+
+
+/**
+ * nan_terminate_ndi_ndps - Terminate all NDPs with a given NDI address
+ * @nan: NAN module context from nan_init()
+ * @ndi_addr: NDI address for which all NDPs should be terminated
+ *
+ * This function terminates all NDPs that have the given NDI address as either
+ * initiator or responder NDI.
+ */
+void nan_terminate_ndi_ndps(struct nan_data *nan, const u8 *ndi_addr)
+{
+	struct nan_peer *peer;
+
+	if (!nan)
+		return;
+
+	dl_list_for_each(peer, &nan->peer_list, struct nan_peer, list) {
+		/*
+		 * It is possible that an NDP setup in progress
+		 * is not on the NDI that is being removed. However,
+		 * to simplify things, stop the setup, so the other
+		 * NDPs could be cleanly removed.
+		 */
+		nan_ndp_setup_stop(nan, peer);
+		nan_terminate_ndps_for_ndi(nan, peer, ndi_addr);
+	}
+}
diff --git a/src/nan/nan.h b/src/nan/nan.h
index 4d5f6fc0ef..ae3c3032ab 100644
--- a/src/nan/nan.h
+++ b/src/nan/nan.h
@@ -876,6 +876,8 @@ bool nan_has_active_ndp(struct nan_data *nan);
 int nan_get_status(struct nan_data *nan, char *buf, size_t buflen);
 int nan_peer_dump_ndps_to_buf(struct nan_data *nan, const u8 *addr,
 			      char *buf, size_t buflen);
+void nan_terminate_ndi_ndps(struct nan_data *nan, const u8 *ndi_addr);
+
 #ifdef CONFIG_PASN
 int nan_pairing_add_attrs(struct nan_data *nan_data, struct wpabuf *buf);
 int nan_pairing_initiate_pasn_auth(struct nan_data *nan_data, const u8 *addr,
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 0684ada719..4bac52dc01 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -5344,6 +5344,30 @@ wpa_supplicant_event_interface_status(struct wpa_supplicant *wpa_s,
 		}
 #endif /* CONFIG_P2P */
 
+#ifdef CONFIG_NAN
+		if (wpa_s->nan_data) {
+			wpa_printf(MSG_DEBUG, "%s: NAN data interface removed",
+				   wpa_s->ifname);
+
+			wpas_nan_data_interface_removed(wpa_s);
+			wpa_supplicant_remove_iface(wpa_s->global, wpa_s, 0);
+			break;
+		}
+
+		if (wpa_s->nan_mgmt) {
+			wpa_printf(MSG_DEBUG,
+				   "%s: NAN management interface removed",
+				   wpa_s->ifname);
+
+			/*
+			 * Note: NAN is stopped when the interface is
+			 * disabled
+			 */
+			wpa_supplicant_remove_iface(wpa_s->global, wpa_s, 0);
+			break;
+		}
+
+#endif /* CONFIG_NAN */
 #ifdef CONFIG_MATCH_IFACE
 		if (wpa_s->matched) {
 			wpa_supplicant_remove_iface(wpa_s->global, wpa_s, 0);
diff --git a/wpa_supplicant/nan_supplicant.c b/wpa_supplicant/nan_supplicant.c
index bc9baa4b7f..1f0de12e1b 100644
--- a/wpa_supplicant/nan_supplicant.c
+++ b/wpa_supplicant/nan_supplicant.c
@@ -4916,3 +4916,18 @@ void wpas_nan_rx_naf(struct wpa_supplicant *wpa_s,
 	nan_action_rx(wpa_s->nan, mgmt, len);
 }
 #endif /* CONFIG_NAN */
+
+
+void wpas_nan_data_interface_removed(struct wpa_supplicant *wpa_s)
+{
+	struct wpa_supplicant *nan_dev_wpas = wpas_nan_get_mgmt_iface(wpa_s);
+
+	wpa_printf(MSG_DEBUG,
+		   "NAN: Data interface removed (%s) terminate NDPs on " MACSTR,
+		   wpa_s->ifname, MAC2STR(wpa_s->own_addr));
+
+	if (!nan_dev_wpas)
+		return;
+
+	nan_terminate_ndi_ndps(nan_dev_wpas->nan, wpa_s->own_addr);
+}
diff --git a/wpa_supplicant/nan_supplicant.h b/wpa_supplicant/nan_supplicant.h
index b8676a86c1..492ac7f58f 100644
--- a/wpa_supplicant/nan_supplicant.h
+++ b/wpa_supplicant/nan_supplicant.h
@@ -43,6 +43,7 @@ int wpas_nan_status(struct wpa_supplicant *wpa_s, char *reply,
 int wpas_nan_bootstrap_request(struct wpa_supplicant *wpa_s, char *cmd);
 int wpas_nan_bootstrap_reset(struct wpa_supplicant *wpa_s, char *cmd);
 bool wpas_nan_is_peer_paired(struct wpa_supplicant *wpa_s, const u8 *peer_addr);
+void wpas_nan_data_interface_removed(struct wpa_supplicant *wpa_s);
 
 int wpas_nan_pair(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
 		  u8 auth_mode, int cipher, int handle, u8 peer_instance_id,
-- 
2.53.0




More information about the Hostap mailing list