[RFC 09/34] Add support for NAN start/stop callbacks.

Andrei Otcheretianski andrei.otcheretianski at intel.com
Wed Aug 13 10:38:53 PDT 2025


In addition, support bringing down/up NAN interface and send
EVENT_INTERFACE_ENABLED/DISABLED when rfkill is unblocked or blocked.

Signed-off-by: Ilan Peer <ilan.peer at intel.com>
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
---
 src/drivers/driver_nl80211.c | 107 +++++++++++++++++++++++++++++++++--
 src/drivers/driver_nl80211.h |   4 ++
 2 files changed, 105 insertions(+), 6 deletions(-)

diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index ad98f3292d..71ddb7664a 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -201,6 +201,9 @@ static int nl80211_put_mesh_config(struct nl_msg *msg,
 static int i802_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
 			     u16 reason, int link_id);
 
+#ifdef CONFIG_NAN
+static void wpa_driver_nl80211_nan_stop(void *priv);
+#endif /* CONFIG_NAN */
 
 /* Converts nl80211_chan_width to a common format */
 enum chan_width convert2width(int width)
@@ -2172,8 +2175,8 @@ static void wpa_driver_nl80211_rfkill_blocked(void *ctx)
 	wpa_printf(MSG_DEBUG, "nl80211: RFKILL blocked");
 
 	/*
-	 * rtnetlink ifdown handler will report interfaces other than the P2P
-	 * Device interface as disabled.
+	 * rtnetlink ifdown handler will report interfaces other than the
+	 * P2P/NAN Device interfaces as disabled.
 	 */
 	if (!nl80211_is_netdev_iftype(drv->nlmode))
 		wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_DISABLED, NULL);
@@ -2194,8 +2197,8 @@ static void wpa_driver_nl80211_rfkill_unblocked(void *ctx)
 		nl80211_disable_11b_rates(drv, drv->ifindex, 1);
 
 	/*
-	 * rtnetlink ifup handler will report interfaces other than the P2P
-	 * Device interface as enabled.
+	 * rtnetlink ifup handler will report interfaces other than the P2P/NAN
+	 * Device interfaces as enabled.
 	 */
 	if (!nl80211_is_netdev_iftype(drv->nlmode))
 		wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED, NULL);
@@ -2996,9 +2999,21 @@ static int nl80211_set_p2pdev(struct i802_bss *bss, int start)
 }
 
 
-int nl80211_set_nandev(struct i802_bss *bss, int start)
+static int nl80211_set_nandev(struct i802_bss *bss, int start)
 {
-	/* TODO: This will be implemented once NAN start/stop APIs are added */
+#ifdef CONFIG_NAN
+	/*
+	 * We don't implicitly start NAN.
+	 * NAN is started through a dedicated API, however we do need to
+	 * stop it.
+	 * For rfkill, we rely on ENABLED/DISABLED events.
+	 */
+	if (start)
+		return 0;
+
+	wpa_driver_nl80211_nan_stop(bss);
+
+#endif /* CONFIG_NAN */
 	return 0;
 }
 
@@ -14997,6 +15012,82 @@ wpa_driver_get_multi_hw_info(void *priv, unsigned int *num_multi_hws)
 }
 
 
+#ifdef CONFIG_NAN
+
+static int wpa_driver_nl80211_nan_start(void *priv,
+					struct nan_cluster_config *params)
+{
+	struct i802_bss *bss = priv;
+	struct wpa_driver_nl80211_data *drv = bss->drv;
+	struct nl_msg *msg;
+	u32 bands = 0;
+	int ret;
+
+	if (drv->nlmode != NL80211_IFTYPE_NAN)
+		return -EOPNOTSUPP;
+
+	if (drv->nan_started)
+		return -EALREADY;
+
+	wpa_printf(MSG_DEBUG, "nl80211: Start/Join NAN cluster");
+
+	if (params->dual_band > 1)
+		return -EINVAL;
+
+	bands |= BIT(NL80211_BAND_2GHZ);
+
+	if (params->dual_band) {
+		if (drv->capa.nan_flags &
+		    WPA_DRIVER_FLAGS_NAN_SUPPORT_DUAL_BAND) {
+			bands |= BIT(NL80211_BAND_5GHZ);
+		} else {
+			wpa_printf(MSG_DEBUG,
+				   "nl80211: Driver doesn't support NAN dual band operation");
+			return -EINVAL;
+		}
+	}
+
+	msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_START_NAN);
+	if (!msg || nla_put_u8(msg, NL80211_ATTR_NAN_MASTER_PREF,
+			       params->master_pref) ||
+	    (bands && nla_put_u32(msg, NL80211_ATTR_BANDS, bands))) {
+		wpa_printf(MSG_ERROR, "Failed to build start NAN command");
+		goto fail;
+	}
+
+	ret = send_and_recv_resp(drv, msg, NULL, NULL);
+	if (!ret)
+		drv->nan_started = 1;
+
+	return ret;
+fail:
+	nlmsg_free(msg);
+	return -1;
+}
+
+static void wpa_driver_nl80211_nan_stop(void *priv)
+{
+	struct i802_bss *bss = priv;
+	struct wpa_driver_nl80211_data *drv = bss->drv;
+	struct nl_msg *msg;
+
+	if (drv->nlmode != NL80211_IFTYPE_NAN || !drv->nan_started)
+		return;
+
+	msg = nl80211_cmd_msg(bss, 0, NL80211_CMD_STOP_NAN);
+	if (!msg) {
+		wpa_printf(MSG_ERROR, "Failed to alloc NAN stop command");
+		return;
+	}
+
+	if (send_and_recv_resp(bss->drv, msg, NULL, NULL))
+		wpa_printf(MSG_ERROR, "Failed to send NAN stop command");
+
+	drv->nan_started = 0;
+}
+
+#endif /* CONFIG_NAN */
+
 const struct wpa_driver_ops wpa_driver_nl80211_ops = {
 	.name = "nl80211",
 	.desc = "Linux nl80211/cfg80211",
@@ -15168,4 +15259,8 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
 	.radio_disable = testing_nl80211_radio_disable,
 #endif /* CONFIG_TESTING_OPTIONS */
 	.get_multi_hw_info = wpa_driver_get_multi_hw_info,
+#ifdef CONFIG_NAN
+	.nan_start = wpa_driver_nl80211_nan_start,
+	.nan_stop = wpa_driver_nl80211_nan_stop,
+#endif /*CONFIG_NAN */
 };
diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
index d8b3157c6c..17d3a938f9 100644
--- a/src/drivers/driver_nl80211.h
+++ b/src/drivers/driver_nl80211.h
@@ -272,6 +272,10 @@ struct wpa_driver_nl80211_data {
 	u8 *pending_link_reconfig_data;
 	size_t pending_link_reconfig_data_len;
 #endif /* CONFIG_DRIVER_NL80211_QCA */
+
+#ifdef CONFIG_NAN
+	unsigned int nan_started:1;
+#endif /* CONFIG_NAN */
 };
 
 struct nl_msg;
-- 
2.49.0




More information about the Hostap mailing list