[PATCH 54/71] wpa_supplicant: Manage NDI operstate using per-interface NDP refcount
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Wed Apr 1 15:02:03 PDT 2026
From: Daniel Gabay <daniel.gabay at intel.com>
A single NDI can maintain NDPs with multiple peers concurrently.
Introduce a per-NDI reference count to track active NDPs across all
peers, ensuring correct operstate transitions:
- Set UP when the first NDP connects (refcount 0 -> 1)
- Set DORMANT when the last NDP disconnects (refcount 1 -> 0)
- Maintain operstate UP while any NDP remains active (refcount > 1)
Signed-off-by: Daniel Gabay <daniel.gabay at intel.com>
---
wpa_supplicant/nan_supplicant.c | 41 ++++++++++++++++++++++++++++---
wpa_supplicant/wpa_supplicant_i.h | 1 +
2 files changed, 39 insertions(+), 3 deletions(-)
diff --git a/wpa_supplicant/nan_supplicant.c b/wpa_supplicant/nan_supplicant.c
index 3a5337bc7b..a00d92cb68 100644
--- a/wpa_supplicant/nan_supplicant.c
+++ b/wpa_supplicant/nan_supplicant.c
@@ -493,7 +493,7 @@ static int wpas_nan_add_ndi_sta(struct wpa_supplicant *wpa_s,
wpa_printf(MSG_DEBUG,
"NAN: NDI station added without keys for peer "
MACSTR, MAC2STR(peer_ndi));
- return 0;
+ goto out_success;
}
if (nan_peer_get_tk(wpa_s->nan, peer_nmi, peer_ndi, local_ndi, tk,
@@ -512,8 +512,28 @@ static int wpas_nan_add_ndi_sta(struct wpa_supplicant *wpa_s,
return -1;
}
- return wpa_drv_sta_set_flags(ndi_wpa_s, peer_ndi, WPA_STA_AUTHORIZED,
- WPA_STA_AUTHORIZED, ~0);
+ if (wpa_drv_sta_set_flags(ndi_wpa_s, peer_ndi, WPA_STA_AUTHORIZED,
+ WPA_STA_AUTHORIZED, ~0)) {
+ wpa_printf(MSG_ERROR,
+ "NAN: Failed to set authorize for NDI station");
+ wpas_nan_remove_ndi_keys(ndi_wpa_s, peer_ndi);
+ wpa_drv_sta_remove(ndi_wpa_s, peer_ndi);
+ return -1;
+ }
+
+out_success:
+ ndi_wpa_s->nan_ndi_ndp_refcount++;
+ wpa_printf(MSG_DEBUG,
+ "NAN: NDP refcount incremented to %u (peer_ndi=" MACSTR
+ " peer_nmi=" MACSTR ")",
+ ndi_wpa_s->nan_ndi_ndp_refcount,
+ MAC2STR(peer_ndi), MAC2STR(peer_nmi));
+
+ /* Set operstate UP only when first NDP is established on this NDI */
+ if (ndi_wpa_s->nan_ndi_ndp_refcount == 1)
+ wpa_drv_set_operstate(ndi_wpa_s, 1);
+
+ return 0;
}
@@ -538,6 +558,21 @@ static void wpas_nan_remove_ndi_sta(struct wpa_supplicant *wpa_s,
wpas_nan_remove_ndi_keys(ndi_wpa_s, peer_ndi);
wpa_drv_sta_remove(ndi_wpa_s, peer_ndi);
+
+ if (!ndi_wpa_s->nan_ndi_ndp_refcount)
+ return;
+
+ ndi_wpa_s->nan_ndi_ndp_refcount--;
+ wpa_printf(MSG_DEBUG, "NAN: NDP refcount decremented to %u (peer_ndi="
+ MACSTR ")", ndi_wpa_s->nan_ndi_ndp_refcount,
+ MAC2STR(peer_ndi));
+
+ /* Set operstate DORMANT only when last NDP is removed from
+ * this NDI
+ */
+ if (!ndi_wpa_s->nan_ndi_ndp_refcount)
+ wpa_drv_set_operstate(ndi_wpa_s, 0);
+
}
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 44a7f58c28..22e7c7b4fc 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1737,6 +1737,7 @@ struct wpa_supplicant {
u16 nan_supported_csids;
struct wpa_freq_range_list nan_disallowed_freqs;
u16 nan_max_bw;
+ unsigned int nan_ndi_ndp_refcount; /* Active NDP count on this NDI */
#endif /* CONFIG_NAN */
#ifdef CONFIG_ENC_ASSOC
bool assoc_resp_encrypted; /* Whether (Re)Association Response frame
--
2.53.0
More information about the Hostap
mailing list