[RFC 35/56] NAN: Add support for terminating an NDP
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Sun Dec 7 03:18:44 PST 2025
From: Ilan Peer <ilan.peer at intel.com>
Add support for locally terminating an NDP.
Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
src/nan/nan.c | 7 ++--
src/nan/nan_i.h | 2 ++
src/nan/nan_ndp.c | 90 ++++++++++++++++++++++++++++++++++++++++-------
3 files changed, 85 insertions(+), 14 deletions(-)
diff --git a/src/nan/nan.c b/src/nan/nan.c
index 8869bd8b29..b99d3ca8ac 100644
--- a/src/nan/nan.c
+++ b/src/nan/nan.c
@@ -1595,9 +1595,12 @@ int nan_handle_ndp_setup(struct nan_data *nan, struct nan_ndp_params *params)
break;
case NAN_NDP_ACTION_TERM:
- wpa_printf(MSG_DEBUG, "TODO: Support terminate");
naf_oui = NAN_SUBTYPE_DATA_PATH_TERMINATION;
- return -1;
+ timeout = NAN_NDP_SETUP_TIMEOUT_SHORT;
+ ret = nan_ndp_term_req(nan, peer, ¶ms->ndp_id);
+ if (ret)
+ return ret;
+ break;
default:
wpa_printf(MSG_DEBUG, "NAN: Unsupported NDP setup type=%u",
params->type);
diff --git a/src/nan/nan_i.h b/src/nan/nan_i.h
index 632e68b765..6733870cf1 100644
--- a/src/nan/nan_i.h
+++ b/src/nan/nan_i.h
@@ -406,6 +406,8 @@ int nan_ndp_naf_sent(struct nan_data *nan, struct nan_peer *peer,
enum nan_subtype subtype);
int nan_parse_device_attrs(struct nan_data *nan, struct nan_peer *peer,
const u8 *attrs_data, size_t attrs_len);
+int nan_ndp_term_req(struct nan_data *nan, struct nan_peer *peer,
+ struct nan_ndp_id *ndp_id);
int nan_ndl_setup(struct nan_data *nan, struct nan_peer *peer,
struct nan_ndp_params *params);
void nan_ndl_setup_failure(struct nan_data *nan, struct nan_peer *peer,
diff --git a/src/nan/nan_ndp.c b/src/nan/nan_ndp.c
index 51a2b60854..3a37751a7a 100644
--- a/src/nan/nan_ndp.c
+++ b/src/nan/nan_ndp.c
@@ -469,6 +469,21 @@ static int nan_ndp_attr_handle_confirm(struct nan_data *nan,
}
+static struct nan_ndp * nan_ndp_find_ndp(struct nan_peer *peer,
+ u8 ndp_id, u8 *init_ndi)
+{
+ struct nan_ndp *pndp;
+
+ dl_list_for_each(pndp, &peer->ndps, struct nan_ndp, list) {
+ if (pndp->ndp_id == ndp_id &&
+ os_memcmp(pndp->init_ndi, init_ndi, ETH_ALEN) == 0)
+ return pndp;
+ }
+
+ return NULL;
+}
+
+
static int nan_ndp_attr_handle_term(struct nan_data *nan, struct nan_peer *peer,
struct ieee80211_ndp *ndp_attr, u8 status)
{
@@ -476,7 +491,6 @@ static int nan_ndp_attr_handle_term(struct nan_data *nan, struct nan_peer *peer,
struct nan_ndp_id ndp_id;
const u8 *local_ndi, *peer_ndi;
struct nan_ndp *pndp;
- bool found;
wpa_printf(MSG_DEBUG,
"NAN: NDP: Termination peer=" MACSTR " ndp_id=%u, init_ndi=" MACSTR,
@@ -501,17 +515,9 @@ static int nan_ndp_attr_handle_term(struct nan_data *nan, struct nan_peer *peer,
}
/* Find the NDP in the list of active NDPs */
- found = false;
- dl_list_for_each(pndp, &peer->ndps, struct nan_ndp, list) {
- if (pndp->ndp_id == ndp_attr->ndp_id &&
- os_memcmp(pndp->init_ndi, ndp_attr->initiator_ndi,
- ETH_ALEN) == 0) {
- found = 1;
- break;
- }
- }
-
- if (!found) {
+ pndp = nan_ndp_find_ndp(peer, ndp_attr->ndp_id,
+ ndp_attr->initiator_ndi);
+ if (!pndp) {
wpa_printf(MSG_DEBUG, "NAN: NDP: termination but NDP does not exist");
return 1;
}
@@ -653,6 +659,11 @@ int nan_ndp_add_ndp_attr(struct nan_data *nan, struct nan_peer *peer,
type = NAN_NDP_TYPE_SECURITY_INSTALL;
break;
case NAN_NDP_STATE_NONE:
+ if (ndp_setup->status == NAN_NDP_STATUS_REJECTED)
+ type = NAN_NDP_TYPE_TERMINATE;
+ else
+ return -1;
+ break;
case NAN_NDP_STATE_REQ_SENT:
case NAN_NDP_STATE_RES_SENT:
case NAN_NDP_STATE_CON_SENT:
@@ -805,3 +816,58 @@ int nan_ndp_naf_sent(struct nan_data *nan, struct nan_peer *peer,
return 0;
}
+
+
+/*
+ * nan_ndp_term_req - Handle local NDP termination request
+ *
+ * @nan: NAN module context from nan_init()
+ * @peer: The peer with whom the NDP is being setup
+ * @ndp_id: NDP identifier
+ */
+int nan_ndp_term_req(struct nan_data *nan, struct nan_peer *peer,
+ struct nan_ndp_id *ndp_id)
+{
+ struct nan_ndp_setup *ndp_setup = &peer->ndp_setup;
+ struct nan_ndp *pndp;
+
+ wpa_printf(MSG_DEBUG,
+ "NAN: NDP: terminate request with peer=" MACSTR " ndp_id=%u, init_ndi=" MACSTR,
+ MAC2STR(peer->nmi_addr), ndp_id->id,
+ MAC2STR(ndp_id->init_ndi));
+
+ if (ndp_setup->ndp) {
+ if (ndp_setup->ndp->ndp_id == ndp_id->id &&
+ os_memcmp(ndp_setup->ndp->init_ndi, ndp_id->init_ndi,
+ ETH_ALEN) == 0) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: NDP: WIP with peer. Terminate");
+
+ nan_ndp_set_state(nan, &peer->ndp_setup,
+ NAN_NDP_STATE_DONE);
+ ndp_setup->status = NAN_NDP_STATUS_REJECTED;
+ ndp_setup->reason = NAN_REASON_UNSPECIFIED_REASON;
+ return 0;
+ }
+
+ wpa_printf(MSG_DEBUG,
+ "NAN: NDP: cannot terminate NDP while NDP establishment is WIP");
+ return -1;
+ }
+
+ /* Find the NDP in the list of active NDPs */
+ pndp = nan_ndp_find_ndp(peer, ndp_id->id, ndp_id->init_ndi);
+ if (!pndp) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: NDP: termination request for unknown NDP");
+ return -1;
+ }
+
+ /* Remove the NDP from the list and setup data for the termination */
+ dl_list_del(&pndp->list);
+
+ peer->ndp_setup.ndp = pndp;
+ peer->ndp_setup.status = NAN_NDP_STATUS_REJECTED;
+ peer->ndp_setup.reason = NAN_REASON_UNSPECIFIED_REASON;
+ return 0;
+}
--
2.49.0
More information about the Hostap
mailing list