[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