[PATCH 83/97] wpa_supplicant: Send response when pairing is aborted
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Tue Apr 28 13:06:24 PDT 2026
From: Avraham Stern <avraham.stern at intel.com>
When the user calls pairing abort, send a response to the peer with
failure so it won't keep waiting for a response.
Modify the pairing abort hwsim test so that only the publisher aborts
the pairing in response to the pairing request. The subscriber should
receive pairing result with failure status.
Signed-off-by: Avraham Stern <avraham.stern at intel.com>
---
src/nan/nan.c | 21 ++++++++
src/nan/nan_i.h | 1 +
src/nan/nan_ndl.c | 6 +--
src/nan/nan_pairing.c | 115 ++++++++++++++++++++++++++++++----------
tests/hwsim/test_nan.py | 9 +++-
5 files changed, 118 insertions(+), 34 deletions(-)
diff --git a/src/nan/nan.c b/src/nan/nan.c
index dafc59e250..7badf419cf 100644
--- a/src/nan/nan.c
+++ b/src/nan/nan.c
@@ -1695,6 +1695,27 @@ int nan_configure_peer_schedule(struct nan_data *nan, struct nan_peer *peer,
}
+int nan_clear_peer_schedule(struct nan_data *nan, struct nan_peer *peer)
+{
+ int ret;
+
+ wpa_printf(MSG_DEBUG, "NAN: Clear peer schedule, peer->configured=%d",
+ peer->configured);
+
+ if (!peer->configured)
+ return 0;
+
+ ret = nan->cfg->set_peer_schedule(nan->cfg->cb_ctx, peer->nmi_addr,
+ false, 0, peer->info.seq_id, 0, NULL,
+ NULL);
+ if (ret)
+ wpa_printf(MSG_DEBUG, "NAN: Failed to clear peer schedule");
+
+ peer->configured = false;
+ return 0;
+}
+
+
/**
* nan_process_followup - Process a received NAN Follow-up Action frame
* @nan: NAN module context from nan_init()
diff --git a/src/nan/nan_i.h b/src/nan/nan_i.h
index 9ce0b99789..501d5f17f9 100644
--- a/src/nan/nan_i.h
+++ b/src/nan/nan_i.h
@@ -847,6 +847,7 @@ int nan_configure_peer_schedule(struct nan_data *nan, struct nan_peer *peer,
const struct nan_schedule *local_sched);
bool nan_is_ndpe_supported(struct nan_data *nan, struct nan_peer *peer);
void nan_add_kde_hdr(struct wpabuf *buf, u32 kde, size_t data_len);
+int nan_clear_peer_schedule(struct nan_data *nan, struct nan_peer *peer);
#ifdef CONFIG_PASN
int nan_nira_get_tag_nonce(const struct nan_config *nan, u8 *nonce, u8 *tag);
void nan_pairing_deinit_peer(struct nan_peer *peer);
diff --git a/src/nan/nan_ndl.c b/src/nan/nan_ndl.c
index 0eb7c798fb..c09b1f9fba 100644
--- a/src/nan/nan_ndl.c
+++ b/src/nan/nan_ndl.c
@@ -119,11 +119,7 @@ static void nan_ndl_clear(struct nan_data *nan, struct nan_peer *peer)
MAC2STR(peer->nmi_addr),
nan_ndl_state_str(peer->ndl->state), peer->ndl->state);
- if (peer->configured) {
- nan->cfg->set_peer_schedule(nan->cfg->cb_ctx, peer->nmi_addr,
- false, 0, 0, 0, NULL, NULL);
- peer->configured = false;
- }
+ nan_clear_peer_schedule(nan, peer);
os_free(ndl->ndc_sched);
ndl->ndc_sched = NULL;
diff --git a/src/nan/nan_pairing.c b/src/nan/nan_pairing.c
index 00df9d5b96..f201cbe7aa 100644
--- a/src/nan/nan_pairing.c
+++ b/src/nan/nan_pairing.c
@@ -93,32 +93,6 @@ void nan_pairing_deinit_peer(struct nan_peer *peer)
}
-int nan_pairing_abort(struct nan_data *nan_data, const u8 *peer_addr)
-{
- struct nan_peer *peer;
-
- peer = nan_get_peer(nan_data, peer_addr);
- if (!peer) {
- wpa_printf(MSG_DEBUG,
- "NAN: Pairing abort: Peer " MACSTR " not found",
- MAC2STR(peer_addr));
- return -1;
- }
-
- if (!peer->pairing.pasn && !peer->pairing.pending_auth1) {
- wpa_printf(MSG_DEBUG,
- "NAN: Pairing abort: No PASN in progress with peer "
- MACSTR, MAC2STR(peer_addr));
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "NAN: Aborting pairing with peer " MACSTR,
- MAC2STR(peer_addr));
- nan_pairing_deinit_peer(peer);
- return 0;
-}
-
-
static bool nan_pairing_is_supported(struct nan_data *nan_data,
struct nan_peer *peer, u8 auth_mode)
{
@@ -846,12 +820,20 @@ int nan_pairing_pasn_auth_tx_status(struct nan_data *nan, const u8 *data,
return -1;
peer = nan_get_peer(nan, mgmt->da);
- if (!peer || !peer->pairing.pasn) {
+ if (!peer) {
wpa_printf(MSG_DEBUG, "NAN: Pairing: Peer not found " MACSTR,
MAC2STR(mgmt->da));
return -1;
}
+ /* Pairing was rejected. Clear peer schedule if no active NDPs */
+ if (!peer->pairing.pasn) {
+ if (dl_list_empty(&peer->ndps) && !peer->ndp_setup.ndp)
+ nan_clear_peer_schedule(nan, peer);
+
+ return 0;
+ }
+
pasn = peer->pairing.pasn;
ret = wpa_pasn_auth_tx_status(pasn, data, data_len, acked);
@@ -1548,3 +1530,82 @@ void nan_pairing_unpair_peer(struct nan_data *nan_data, const u8 *peer_addr)
peer->pairing.flags &= ~NAN_PAIRING_FLAG_PAIRED;
nan_pairing_deinit_peer(peer);
}
+
+
+int nan_pairing_abort(struct nan_data *nan_data, const u8 *peer_addr)
+{
+ struct nan_peer *peer;
+ int cipher;
+ struct wpabuf *extra_ies;
+ int ret = -1;
+
+ peer = nan_get_peer(nan_data, peer_addr);
+ if (!peer) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Pairing abort: Peer " MACSTR " not found",
+ MAC2STR(peer_addr));
+ return -1;
+ }
+
+ if (!peer->pairing.pasn && !peer->pairing.pending_auth1) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Pairing abort: No PASN in progress with peer "
+ MACSTR, MAC2STR(peer_addr));
+ return -1;
+ }
+
+ wpa_printf(MSG_DEBUG, "NAN: Aborting pairing with peer " MACSTR,
+ MAC2STR(peer_addr));
+
+ if (!peer->pairing.pending_auth1) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Pairing abort: No pending Auth1 frame for peer "
+ MACSTR, MAC2STR(peer_addr));
+ ret = 0;
+ goto done;
+ }
+
+ /* The auth mode and cipher are not important when rejecting.
+ * Just make sure to use a supported cipher so
+ * nan_pairing_pasn_initialize won't fail.
+ */
+ cipher = (nan_data->cfg->pairing_cfg.cipher_suites &
+ NAN_PAIRING_PASN_128) ? WPA_CIPHER_CCMP : WPA_CIPHER_GCMP_256;
+
+ if (nan_pairing_pasn_initialize(nan_data, peer, NAN_PASN_AUTH_MODE_PASN,
+ cipher, "",
+ NAN_PAIRING_ROLE_RESPONDER)) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Pairing: Initialize failed");
+ goto done;
+ }
+
+ extra_ies = wpabuf_alloc(NAN_ELEMENT_MAX_SIZE);
+ if (!extra_ies) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Pairing: Failed to allocate buffer for extra IEs");
+ goto done;
+ }
+
+ nan_pairing_prepare_pasn_elems(nan_data, peer, extra_ies,
+ peer->pairing.peer_instance_id,
+ NAN_PASN_AUTH_MODE_PASN);
+ pasn_set_extra_ies(peer->pairing.pasn, wpabuf_head_u8(extra_ies),
+ wpabuf_len(extra_ies));
+ wpabuf_free(extra_ies);
+
+ nan_configure_peer_schedule(nan_data, peer, &nan_data->sched);
+
+ ret = handle_auth_pasn_resp(peer->pairing.pasn, nan_data->cfg->nmi_addr,
+ peer_addr, NULL,
+ WLAN_STATUS_UNSPECIFIED_FAILURE);
+ if (ret < 0) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Pairing abort: Failed to send response");
+ nan_clear_peer_schedule(nan_data, peer);
+ }
+
+done:
+ nan_pairing_deinit_peer(peer);
+ return ret;
+}
diff --git a/tests/hwsim/test_nan.py b/tests/hwsim/test_nan.py
index 53ceb3bad9..8b3dff57d8 100644
--- a/tests/hwsim/test_nan.py
+++ b/tests/hwsim/test_nan.py
@@ -1534,11 +1534,16 @@ def test_nan_pair_abort(dev, apdev, params):
if ev_pub is None:
raise Exception("PASN pairing request not seen on publisher")
- if "OK" not in sub.pair_abort(paddr):
- raise Exception("NAN_PAIR_ABORT failed on subscriber")
if "OK" not in pub.pair_abort(saddr):
raise Exception("NAN_PAIR_ABORT failed on publisher")
+ # The subscriber should get a failure result
+ ev_sub = sub.wpas.wait_event(["NAN-PAIRING-STATUS"], timeout=5)
+ if ev_sub is None:
+ raise Exception("PASN result not seen on subscriber")
+ if "status=failure" not in ev_sub:
+ raise Exception("NAN pairing failed status not seen on subscriber after abort")
+
# After abort, we should be able to restart pairing successfully
sub.pairing_request(pub, sid, pid, "SAE", responder=False, password="password123")
ev_pub = pub.wpas.wait_event(["NAN-PAIRING-REQUEST"], timeout=2)
--
2.53.0
More information about the Hostap
mailing list