[PATCH 19/97] NAN: Support configuration and notification of IPv6 local identifier

Andrei Otcheretianski andrei.otcheretianski at intel.com
Tue Apr 28 13:05:20 PDT 2026


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

Add support for configuring NAN IPv6 local identifier in the NDP
request/response and indicating the peer IPv6 local identifier
in NDP connected notification.

Finally, indicate support for NDPE in the device capabilities
attribute.

Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
 wpa_supplicant/nan_supplicant.c | 35 ++++++++++++++++++++++++++++++---
 wpa_supplicant/notify.c         | 26 +++++++++++++++++++-----
 wpa_supplicant/notify.h         |  3 ++-
 3 files changed, 55 insertions(+), 9 deletions(-)

diff --git a/wpa_supplicant/nan_supplicant.c b/wpa_supplicant/nan_supplicant.c
index a1fff99aba..b53670174c 100644
--- a/wpa_supplicant/nan_supplicant.c
+++ b/wpa_supplicant/nan_supplicant.c
@@ -628,7 +628,8 @@ static int wpas_nan_ndp_connected_cb(void *ctx,
 	wpas_notify_nan_ndp_connected(wpa_s, params->ndp_id.peer_nmi,
 				      params->ndp_id.id,
 				      params->local_ndi, params->peer_ndi,
-				      params->ssi, params->ssi_len);
+				      params->ssi, params->ssi_len,
+				      params->interface_id);
 
        return 0;
 }
@@ -1157,6 +1158,7 @@ int wpas_nan_init(struct wpa_supplicant *wpa_s)
 	nan.dev_capa.channel_switch_time =
 		wpa_s->nan_capa.max_channel_switch_time;
 	nan.dev_capa.capa = wpa_s->nan_capa.dev_capa;
+	nan.dev_capa.capa |= NAN_DEV_CAPA_NDPE_ATTR_SUPP;
 
 	nan.supported_bootstrap_methods = DEFAULT_NAN_SUPP_PBM;
 	nan.auto_accept_bootstrap_methods = DEFAULT_NAN_AUTO_ACCEPT_PBM;
@@ -2213,7 +2215,7 @@ static int wpas_nan_fill_nd_pmk(struct wpa_supplicant *wpa_s,
 
 /* Command format NAN_NDP_REQUEST handle=<id> ndi=<ifname> peer_nmi=<nmi>
    peer_id=<peer_instance_id> ssi=<hexdata> qos=<slots:latency>
-   [csid = <cipher_suite> <password=<string>|pmk=<hex>>] */
+   [csid = <cipher_suite> <password=<string>|pmk=<hex>>] [interface_id=<hex>]*/
 int wpas_nan_ndp_request(struct wpa_supplicant *wpa_s, char *cmd)
 {
 	struct nan_ndp_params ndp;
@@ -2313,6 +2315,18 @@ int wpas_nan_ndp_request(struct wpa_supplicant *wpa_s, char *cmd)
 			pwd = pos;
 		} else if (os_strcmp(token, "pmk") == 0) {
 			pmk = pos;
+		} else if (os_strcmp(token, "interface_id") == 0) {
+			ndp.interface_id = os_malloc(NAN_NDPE_TLV_IPV6_LINK_LOCAL_LEN);
+			if (!ndp.interface_id)
+				goto fail;
+
+			if (hexstr2bin(pos, ndp.interface_id,
+				       NAN_NDPE_TLV_IPV6_LINK_LOCAL_LEN) < 0) {
+				wpa_printf(MSG_DEBUG,
+					   "NAN: Invalid interface_id hex data: %s",
+					   pos);
+				goto fail;
+			}
 		} else {
 			wpa_printf(MSG_INFO, "NAN: Unknown parameter: %s",
 				   token);
@@ -2368,6 +2382,7 @@ int wpas_nan_ndp_request(struct wpa_supplicant *wpa_s, char *cmd)
 fail:
 	wpabuf_free(ndp.sched.elems);
 	wpabuf_free(ssi_buf);
+	os_free(ndp.interface_id);
 
 	return ret;
 }
@@ -2377,7 +2392,7 @@ fail:
    [reason_code=<reject_reason>]
    [ndi=<ifname> handle=<service_handle> init_ndi=<ndi>
    ndp_id=<id> [ssi=<hexdata>] [qos=<slots:latency>]
-   [csid=<csid> <password=<string>|pmk=<hex>]] */
+   [csid=<csid> <password=<string>|pmk=<hex>]] [interface_id=<hex>] */
 int wpas_nan_ndp_response(struct wpa_supplicant *wpa_s, char *cmd)
 {
 	struct nan_ndp_params ndp;
@@ -2490,6 +2505,18 @@ int wpas_nan_ndp_response(struct wpa_supplicant *wpa_s, char *cmd)
 			pwd = pos;
 		} else if (os_strcmp(token, "pmk") == 0) {
 			pmk = pos;
+		} else if (os_strcmp(token, "interface_id") == 0) {
+			ndp.interface_id = os_malloc(NAN_NDPE_TLV_IPV6_LINK_LOCAL_LEN);
+			if (!ndp.interface_id)
+				goto fail;
+
+			if (hexstr2bin(pos, ndp.interface_id,
+				       NAN_NDPE_TLV_IPV6_LINK_LOCAL_LEN) < 0) {
+				wpa_printf(MSG_DEBUG,
+					   "NAN: Invalid interface_id hex data: %s",
+					   pos);
+				goto fail;
+			}
 		} else {
 			wpa_printf(MSG_DEBUG, "NAN: Unknown parameter: %s",
 				   token);
@@ -2572,6 +2599,8 @@ int wpas_nan_ndp_response(struct wpa_supplicant *wpa_s, char *cmd)
 fail:
 	wpabuf_free(ndp.sched.elems);
 	wpabuf_free(ssi_buf);
+	os_free(ndp.interface_id);
+
 	return ret;
 }
 
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index 2881fddab2..ec2c68ea11 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -1409,9 +1409,10 @@ void wpas_notify_nan_ndp_connected(struct wpa_supplicant *wpa_s,
 				   const u8 *peer_nmi, u32 ndp_id,
 				   const u8 *local_ndi,
 				   const u8 *peer_ndi,
-				   const u8 *ssi, size_t ssi_len)
+				   const u8 *ssi, size_t ssi_len,
+				   const u8 *interface_id)
 {
-	char *ssi_hex = NULL;
+	char *ssi_hex = NULL, *interface_id_hex = NULL;
 
 	if (ssi) {
 		ssi_hex = os_zalloc(2 * ssi_len + 1);
@@ -1421,13 +1422,28 @@ void wpas_notify_nan_ndp_connected(struct wpa_supplicant *wpa_s,
 		wpa_snprintf_hex(ssi_hex, 2 * ssi_len + 1, ssi, ssi_len);
 	}
 
+	if (interface_id) {
+		interface_id_hex =
+			os_zalloc(2 * NAN_NDPE_TLV_IPV6_LINK_LOCAL_LEN + 1);
+		if (!interface_id_hex)
+			return;
+
+		wpa_snprintf_hex(interface_id_hex,
+				 2 * NAN_NDPE_TLV_IPV6_LINK_LOCAL_LEN + 1,
+				 interface_id,
+				 NAN_NDPE_TLV_IPV6_LINK_LOCAL_LEN);
+	}
+
 	wpa_msg_global(wpa_s, MSG_INFO, NAN_NDP_CONNECTED "peer=" MACSTR
 		       " ndp_id=%u local_ndi=" MACSTR
-		       " peer_ndi=" MACSTR " ssi=%s",
-		       MAC2STR(peer_nmi), ndp_id, MAC2STR(local_ndi),
-		       MAC2STR(peer_ndi), ssi_hex ? ssi_hex : "");
+		       " peer_ndi=" MACSTR " ssi=%s interface_id=%s",
+		       MAC2STR(peer_nmi), ndp_id,
+		       MAC2STR(local_ndi), MAC2STR(peer_ndi),
+		       ssi_hex ? ssi_hex : "",
+		       interface_id ? interface_id_hex : "");
 
 	os_free(ssi_hex);
+	os_free(interface_id_hex);
 }
 
 
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
index 3c2feece9e..f6d3654e17 100644
--- a/wpa_supplicant/notify.h
+++ b/wpa_supplicant/notify.h
@@ -238,7 +238,8 @@ void wpas_notify_nan_ndp_counter_request(struct wpa_supplicant *wpa_s,
 void wpas_notify_nan_ndp_connected(struct wpa_supplicant *wpa_s,
 				   const u8 *peer_nmi, u32 ndp_id,
 				   const u8 *local_ndi, const u8 *peer_ndi,
-				   const u8 *ssi, size_t ssi_len);
+				   const u8 *ssi, size_t ssi_len,
+				   const u8 *interface_id);
 void wpas_notify_nan_ndp_disconnected(struct wpa_supplicant *wpa_s,
 				      const u8 *peer_nmi, u32 ndp_id,
 				      const u8 *local_ndi, const u8 *peer_ndi,
-- 
2.53.0




More information about the Hostap mailing list