[PATCH 18/97] NAN: Add support for communicating the IPv6 local address
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Tue Apr 28 13:05:19 PDT 2026
From: Ilan Peer <ilan.peer at intel.com>
When both peers support the NAN Data Path Extension (NDPE)
attribute and IPv6 interface identifier is configured,
communicate the information as part of the NDP setup.
Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
src/nan/nan.c | 7 +++++++
src/nan/nan.h | 6 ++++++
src/nan/nan_i.h | 13 +++++++++++++
src/nan/nan_ndp.c | 41 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 67 insertions(+)
diff --git a/src/nan/nan.c b/src/nan/nan.c
index a91fb8c713..5614a7bd89 100644
--- a/src/nan/nan.c
+++ b/src/nan/nan.c
@@ -1508,6 +1508,13 @@ static int nan_ndp_connected(struct nan_data *nan, struct nan_peer *peer)
params.ssi = peer->ndp_setup.ssi;
params.ssi_len = peer->ndp_setup.ssi_len;
+ if (peer->ndp_setup.peer_interface_id_valid) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: NDP connected with peer interface id");
+
+ params.interface_id = peer->ndp_setup.peer_interface_id;
+ }
+
if (peer->ndp_setup.ndp->initiator) {
params.local_ndi = peer->ndp_setup.ndp->init_ndi;
params.peer_ndi = peer->ndp_setup.ndp->resp_ndi;
diff --git a/src/nan/nan.h b/src/nan/nan.h
index 2d9372f014..a999a6582c 100644
--- a/src/nan/nan.h
+++ b/src/nan/nan.h
@@ -223,6 +223,9 @@ struct nan_ndp_sec_params {
* @reason_code: In case of rejected response, the rejection reason.
* @sched_valid: Indicates whether the schedule field is valid
* @sched: The NAN schedule associated with the NDP parameters
+ * @interface_id: The interface identifier to be used for the NDP. The interface
+ * identifier is used to derive the IPv6 link-local address as specified in
+ * Table 90 in WiFi Aware specification v4.0
*/
struct nan_ndp_params {
enum nan_ndp_action type;
@@ -253,6 +256,7 @@ struct nan_ndp_params {
bool sched_valid;
struct nan_schedule sched;
+ u8 *interface_id;
};
/**
@@ -289,6 +293,7 @@ struct nan_channels {
* @first_ndp: Whether this is the first NDP with the peer
* @new_ndi_sta: Whether a new NDI station needs to be added (peer_ndi not
* already used by another NDP with this peer)
+ * @interface_id: The interface identifier to be used by the peer for the NDP
*/
struct nan_ndp_connection_params {
struct nan_ndp_id ndp_id;
@@ -299,6 +304,7 @@ struct nan_ndp_connection_params {
bool install_keys;
bool first_ndp;
bool new_ndi_sta;
+ const u8 *interface_id;
};
/**
diff --git a/src/nan/nan_i.h b/src/nan/nan_i.h
index 3bd01debc0..d01f720be6 100644
--- a/src/nan/nan_i.h
+++ b/src/nan/nan_i.h
@@ -163,6 +163,14 @@ struct nan_ndp {
* @ssi_len: Service specific information length
* @service_id: Service ID of the service used for NDP setup
* @sec: NDP security data
+ * @local_interface_id_valid: Indicates whether the &local_interface_id
+ * field is valid.
+ * @local_interface_id: The local interface identifier to be used for
+ * the NDP
+ * @peer_interface_id_valid: Indicates whether the &peer_interface_id
+ * field is valid.
+ * @peer_interface_id: The peer interface identifier to be used for
+ * the NDP
*/
struct nan_ndp_setup {
struct nan_ndp *ndp;
@@ -177,6 +185,11 @@ struct nan_ndp_setup {
u8 service_id[NAN_SERVICE_ID_LEN];
struct nan_ndp_sec sec;
+
+ bool local_interface_id_valid;
+ u8 local_interface_id[NAN_NDPE_TLV_IPV6_LINK_LOCAL_LEN];
+ bool peer_interface_id_valid;
+ u8 peer_interface_id[NAN_NDPE_TLV_IPV6_LINK_LOCAL_LEN];
};
/**
diff --git a/src/nan/nan_ndp.c b/src/nan/nan_ndp.c
index 91e517115a..5a95005d21 100644
--- a/src/nan/nan_ndp.c
+++ b/src/nan/nan_ndp.c
@@ -147,6 +147,17 @@ int nan_ndp_setup_req(struct nan_data *nan, struct nan_peer *peer,
peer->ndp_setup.publish_inst_id;
}
+ if (params->interface_id) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: NDP setup request with local interface id");
+
+ os_memcpy(peer->ndp_setup.local_interface_id,
+ params->interface_id,
+ NAN_NDPE_TLV_IPV6_LINK_LOCAL_LEN);
+
+ peer->ndp_setup.local_interface_id_valid = true;
+ }
+
nan_ndp_set_state(nan, &peer->ndp_setup, NAN_NDP_STATE_START);
peer->ndp_setup.status = NAN_NDP_STATUS_CONTINUED;
return 0;
@@ -240,6 +251,17 @@ int nan_ndp_setup_resp(struct nan_data *nan, struct nan_peer *peer,
if (ret)
return ret;
+ if (params->interface_id) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: NDP setup response with local interface id");
+
+ os_memcpy(peer->ndp_setup.local_interface_id,
+ params->interface_id,
+ NAN_NDPE_TLV_IPV6_LINK_LOCAL_LEN);
+
+ peer->ndp_setup.local_interface_id_valid = true;
+ }
+
return 0;
}
@@ -264,6 +286,18 @@ static int nan_ndp_attr_handle_tlvs(struct nan_data *nan,
}
switch (tlv_type) {
+ case NAN_NDPE_TLV_IPV6_LINK_LOCAL:
+ if (tlv_len != NAN_NDPE_TLV_IPV6_LINK_LOCAL_LEN) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: NDP: req: Invalid interface ID tlv len=%u",
+ tlv_len);
+ break;
+ }
+
+ peer->ndp_setup.peer_interface_id_valid = true;
+ os_memcpy(peer->ndp_setup.peer_interface_id, tlv_data,
+ NAN_NDPE_TLV_IPV6_LINK_LOCAL_LEN);
+ break;
case NAN_NDPE_TLV_SRV_INFO:
wpa_printf(MSG_DEBUG,
"NAN: NDP: Handle NDP service specific information");
@@ -950,6 +984,13 @@ int nan_ndp_add_ndp_attr(struct nan_data *nan, struct nan_peer *peer,
}
}
+ if (ndpe_supported && ndp_setup->local_interface_id_valid) {
+ wpabuf_put_u8(buf, NAN_NDPE_TLV_IPV6_LINK_LOCAL);
+ wpabuf_put_le16(buf, NAN_NDPE_TLV_IPV6_LINK_LOCAL_LEN);
+ wpabuf_put_data(buf, ndp_setup->local_interface_id,
+ NAN_NDPE_TLV_IPV6_LINK_LOCAL_LEN);
+ }
+
WPA_PUT_LE16(len_ptr, (u8 *) wpabuf_put(buf, 0) - len_ptr - 2);
return 0;
}
--
2.53.0
More information about the Hostap
mailing list