]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
NAN: Integrate the NAN module with wpa_supplicant
authorIlan Peer <ilan.peer@intel.com>
Tue, 23 Dec 2025 11:45:56 +0000 (13:45 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 29 Jan 2026 10:31:55 +0000 (12:31 +0200)
Introduce a new NAN device interface that can be used for NAN management
flows. Support creating this interface dynamically.

Support setting NAN configuration, and support starting/stopping NAN
Device operation.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
wpa_supplicant/Android.mk
wpa_supplicant/Makefile
wpa_supplicant/ctrl_iface.c
wpa_supplicant/defconfig
wpa_supplicant/driver_i.h
wpa_supplicant/events.c
wpa_supplicant/nan_supplicant.c [new file with mode: 0644]
wpa_supplicant/nan_supplicant.h [new file with mode: 0644]
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant_i.h

index b8bda48d8f99a9681775361e84ec539441b8f539..7f927126080ebb70f5975a869d599209d88310ea 100644 (file)
@@ -283,6 +283,12 @@ L_CFLAGS += -DCONFIG_DPP3
 endif
 endif
 
+ifdef CONFIG_NAN
+OBJS += nan_supplicant.c
+OBJS += src/nan/nan.c
+CFLAGS += -DCONFIG_NAN
+endif
+
 ifdef CONFIG_NAN_USD
 OBJS += src/common/nan_de.c
 OBJS += nan_usd.c
index b92b1e3f29bfee5f278ef8cbdbf84598620a870e..9c7658c7a58c2e3d39b88663794973e9fc1d1c46 100644 (file)
@@ -317,6 +317,12 @@ CFLAGS += -DCONFIG_DPP3
 endif
 endif
 
+ifdef CONFIG_NAN
+OBJS += nan_supplicant.o
+OBJS += ../src/nan/nan.o
+CFLAGS += -DCONFIG_NAN
+endif
+
 ifdef CONFIG_NAN_USD
 OBJS += ../src/common/nan_de.o
 OBJS += nan_usd.o
index 92ab86fc06e8171150e6a25ad9488ed101dcdad3..8d5683c52fff204087071110bb964ba1c74d90cb 100644 (file)
@@ -14379,6 +14379,9 @@ static int wpa_supplicant_global_iface_add(struct wpa_global *global,
                                type = WPA_IF_STATION;
                        } else if (os_strcmp(pos, "ap") == 0) {
                                type = WPA_IF_AP_BSS;
+                       } else if (os_strcmp(pos, "nan") == 0) {
+                               type = WPA_IF_NAN;
+                               iface.nan_mgmt = true;
                        } else {
                                wpa_printf(MSG_DEBUG,
                                           "INTERFACE_ADD unsupported interface type: '%s'",
index 84ac8ba12c62281ccc869a280668696d71df83ea..fb603aa78109663fc83db3cd1eaf1165ac546a02 100644 (file)
@@ -682,3 +682,6 @@ CONFIG_DPP2=y
 
 # Wi-Fi Aware unsynchronized service discovery (NAN USD)
 #CONFIG_NAN_USD=y
+
+# Wi-Fi Aware (NAN) support
+#CONFIG_NAN=y
index f259ac36f8549240ed488ed17ca890e96700dda6..4c07085b557d3c0852cb776a9d939b91f7c56e2a 100644 (file)
@@ -1277,4 +1277,24 @@ wpas_drv_nan_cancel_subscribe(struct wpa_supplicant *wpa_s, int subscribe_id)
                                                   subscribe_id);
 }
 
+
+#ifdef CONFIG_NAN
+
+static inline int wpa_drv_nan_start(struct wpa_supplicant *wpa_s,
+                                   struct nan_cluster_config *conf)
+{
+       if (!wpa_s->driver->nan_start)
+               return -1;
+       return wpa_s->driver->nan_start(wpa_s->drv_priv, conf);
+}
+
+static inline void wpa_drv_nan_stop(struct wpa_supplicant *wpa_s)
+{
+       if (!wpa_s->driver->nan_stop)
+               return;
+       wpa_s->driver->nan_stop(wpa_s->drv_priv);
+}
+
+#endif /* CONFIG_NAN */
+
 #endif /* DRIVER_I_H */
index 4ad6c5138d9ec8559bba8d35e74f6917a1074d83..b9ae7fa5c5d09f47f9d6297debaff11894e6dbd6 100644 (file)
@@ -54,6 +54,7 @@
 #include "nan_usd.h"
 #include "dpp_supplicant.h"
 #include "pr_supplicant.h"
+#include "nan_supplicant.h"
 
 
 #define MAX_OWE_TRANSITION_BSS_SELECT_COUNT 5
@@ -7041,7 +7042,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                        else
                                wpa_sm_pmksa_cache_reconfig(wpa_s->wpa);
                        wpa_supplicant_set_default_scan_ies(wpa_s);
-                       if (wpa_s->p2p_mgmt) {
+                       if (wpa_s->p2p_mgmt || wpa_s->nan_mgmt) {
                                wpa_supplicant_set_state(wpa_s,
                                                         WPA_DISCONNECTED);
                                break;
@@ -7064,6 +7065,12 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                break;
        case EVENT_INTERFACE_DISABLED:
                wpa_dbg(wpa_s, MSG_DEBUG, "Interface was disabled");
+               if (wpa_s->nan_mgmt) {
+                       wpas_nan_flush(wpa_s);
+                       wpa_supplicant_set_state(wpa_s,
+                                                WPA_INTERFACE_DISABLED);
+                       break;
+               }
 #ifdef CONFIG_P2P
                if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_GO ||
                    (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group &&
diff --git a/wpa_supplicant/nan_supplicant.c b/wpa_supplicant/nan_supplicant.c
new file mode 100644 (file)
index 0000000..dc37e4c
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * wpa_supplicant - NAN
+ * Copyright (C) 2025 Intel Corporation
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "wpa_supplicant_i.h"
+#include "driver_i.h"
+#include "nan/nan.h"
+#include "config.h"
+
+#define DEFAULT_NAN_MASTER_PREF 2
+#define DEFAULT_NAN_DUAL_BAND   0
+
+
+static int wpas_nan_start_cb(void *ctx, struct nan_cluster_config *config)
+{
+       struct wpa_supplicant *wpa_s = ctx;
+
+       return wpa_drv_nan_start(wpa_s, config);
+}
+
+
+static void wpas_nan_stop_cb(void *ctx)
+{
+       struct wpa_supplicant *wpa_s = ctx;
+
+       wpa_drv_nan_stop(wpa_s);
+}
+
+
+int wpas_nan_init(struct wpa_supplicant *wpa_s)
+{
+       struct nan_config nan;
+
+       if (!(wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SUPPORT_NAN)) {
+               wpa_printf(MSG_INFO, "NAN: Driver does not support NAN");
+               return -1;
+       }
+
+       os_memset(&nan, 0, sizeof(nan));
+       nan.cb_ctx = wpa_s;
+
+       nan.start = wpas_nan_start_cb;
+       nan.stop = wpas_nan_stop_cb;
+
+       wpa_s->nan = nan_init(&nan);
+       if (!wpa_s->nan) {
+               wpa_printf(MSG_INFO, "NAN: Failed to init");
+               return -1;
+       }
+
+       return 0;
+}
+
+
+void wpas_nan_deinit(struct wpa_supplicant *wpa_s)
+{
+       if (!wpa_s || !wpa_s->nan)
+               return;
+
+       nan_deinit(wpa_s->nan);
+       wpa_s->nan = NULL;
+}
+
+
+static int wpas_nan_ready(struct wpa_supplicant *wpa_s)
+{
+       return wpa_s->nan_mgmt && wpa_s->nan &&
+               wpa_s->wpa_state != WPA_INTERFACE_DISABLED;
+}
+
+
+/* Join a cluster using current configuration */
+int wpas_nan_start(struct wpa_supplicant *wpa_s)
+{
+       struct nan_cluster_config cluster_config;
+
+       if (!wpas_nan_ready(wpa_s))
+               return -1;
+
+       cluster_config.master_pref = DEFAULT_NAN_MASTER_PREF;
+       cluster_config.dual_band = DEFAULT_NAN_DUAL_BAND;
+
+       return nan_start(wpa_s->nan, &cluster_config);
+}
+
+
+int wpas_nan_stop(struct wpa_supplicant *wpa_s)
+{
+       if (!wpas_nan_ready(wpa_s))
+               return -1;
+
+       nan_stop(wpa_s->nan);
+
+       return 0;
+}
+
+
+void wpas_nan_flush(struct wpa_supplicant *wpa_s)
+{
+       if (!wpas_nan_ready(wpa_s))
+               return;
+
+       nan_flush(wpa_s->nan);
+}
diff --git a/wpa_supplicant/nan_supplicant.h b/wpa_supplicant/nan_supplicant.h
new file mode 100644 (file)
index 0000000..615c6f6
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * wpa_supplicant - NAN
+ * Copyright (C) 2025 Intel Corporation
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef NAN_SUPPLICANT_H
+#define NAN_SUPPLICANT_H
+
+#ifdef CONFIG_NAN
+
+int wpas_nan_init(struct wpa_supplicant *wpa_s);
+void wpas_nan_deinit(struct wpa_supplicant *wpa_s);
+int wpas_nan_start(struct wpa_supplicant *wpa_s);
+int wpas_nan_stop(struct wpa_supplicant *wpa_s);
+void wpas_nan_flush(struct wpa_supplicant *wpa_s);
+
+#else /* CONFIG_NAN */
+
+static inline int wpas_nan_init(struct wpa_supplicant *wpa_s)
+{
+       return -1;
+}
+
+static inline void wpas_nan_deinit(struct wpa_supplicant *wpa_s)
+{}
+
+static inline int wpas_nan_start(struct wpa_supplicant *wpa_s)
+{
+       return -1;
+}
+
+static inline int wpas_nan_stop(struct wpa_supplicant *wpa_s)
+{
+       return -1;
+}
+
+static inline void wpas_nan_flush(struct wpa_supplicant *wpa_s)
+{}
+
+#endif /* CONFIG_NAN */
+
+#endif /* NAN_SUPPLICANT_H */
index 500ee97a40482ac1e69cdc1faeaef4b2a754cd04..0c4abaafbaf3cb31009df1ab68a47962fe28ec7a 100644 (file)
@@ -68,6 +68,7 @@
 #include "dpp_supplicant.h"
 #include "nan_usd.h"
 #include "pr_supplicant.h"
+#include "nan_supplicant.h"
 #ifdef CONFIG_MESH
 #include "ap/ap_config.h"
 #include "ap/hostapd.h"
@@ -6226,7 +6227,8 @@ int wpa_supplicant_update_mac_addr(struct wpa_supplicant *wpa_s)
 
        if ((!wpa_s->p2p_mgmt ||
             !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)) &&
-           !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE)) {
+           !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE) &&
+           !wpa_s->nan_mgmt) {
                l2_packet_deinit(wpa_s->l2);
                wpa_s->l2 = l2_packet_init(wpa_s->ifname,
                                           wpa_drv_get_mac_addr(wpa_s),
@@ -7928,6 +7930,8 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
        if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE)
                wpa_s->p2p_mgmt = iface->p2p_mgmt;
 
+       wpa_s->nan_mgmt = iface->nan_mgmt;
+
        if (wpa_s->num_multichan_concurrent == 0)
                wpa_s->num_multichan_concurrent = 1;
 
@@ -7935,7 +7939,7 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
                return -1;
 
 #ifdef CONFIG_TDLS
-       if (!iface->p2p_mgmt && wpa_tdls_init(wpa_s->wpa))
+       if (!iface->p2p_mgmt && !iface->nan_mgmt && wpa_tdls_init(wpa_s->wpa))
                return -1;
 #endif /* CONFIG_TDLS */
 
@@ -8085,6 +8089,11 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
 
        wpa_supplicant_set_default_scan_ies(wpa_s);
 
+       if (wpa_s->nan_mgmt && wpas_nan_init(wpa_s) < 0) {
+               wpa_msg(wpa_s, MSG_ERROR, "Failed to init NAN");
+               return -1;
+       }
+
        return 0;
 }
 
@@ -8136,6 +8145,8 @@ static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s,
        wpa_supplicant_cleanup(wpa_s);
        wpas_p2p_deinit_iface(wpa_s);
 
+       wpas_nan_deinit(wpa_s);
+
        wpas_ctrl_radio_work_flush(wpa_s);
        radio_remove_interface(wpa_s);
 
@@ -8303,7 +8314,7 @@ struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
                return NULL;
        }
 
-       if (iface->p2p_mgmt == 0) {
+       if (iface->p2p_mgmt == 0 && !iface->nan_mgmt) {
                /* Notify the control interfaces about new iface */
                if (wpas_notify_iface_added(wpa_s)) {
                        wpa_supplicant_deinit_iface(wpa_s, 1, 0);
@@ -8321,7 +8332,7 @@ struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
        wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
 
 #ifdef CONFIG_P2P
-       if (wpa_s->global->p2p == NULL &&
+       if (!wpa_s->global->p2p && !iface->nan_mgmt &&
            !wpa_s->global->p2p_disabled && !wpa_s->conf->p2p_disabled &&
            (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
            wpas_p2p_add_p2pdev_interface(
index 968c777d7eaf3f90ecbf5560fee8ba2aaab455e9..5371f5b6e9ce7d8cda64ee751eb211cecb22e790 100644 (file)
@@ -135,6 +135,11 @@ struct wpa_interface {
                WPA_IFACE_MATCHED
        } matched;
 #endif /* CONFIG_MATCH_IFACE */
+
+       /**
+        * nan_mgmt - Interface used for NAN management (NAN Device operations)
+        */
+       bool nan_mgmt;
 };
 
 /**
@@ -1661,6 +1666,12 @@ struct wpa_supplicant {
        bool ext_auth_to_same_bss; /* Whether external authentication has been
                                    * completed successfully with the BSS that
                                    * we are already associated with. */
+
+       bool nan_mgmt;
+
+#ifdef CONFIG_NAN
+       struct nan_data *nan;
+#endif /* CONFIG_NAN */
 };