[PATCH 09/15] tests: NAN: Add a sync Cluster ID mismatch test
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Thu Oct 8 09:05:18 PDT 2026
From: Ilan Peer <ilan.peer at intel.com>
Add nan_sync_cluster_id_mismatch, which overrides the subscriber
Discovery Engine Cluster ID via NAN_SET test_cluster_id, verifies that
the unsolicited Publish SDFs are no longer reported, and then restores
the real Cluster ID to confirm that the same Publish is accepted again.
Add nan_check_same_cluster() to verify that the devices converged into a
single cluster and use it in the synchronized discovery tests.
Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
tests/hwsim/test_nan.py | 63 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 62 insertions(+), 1 deletion(-)
diff --git a/tests/hwsim/test_nan.py b/tests/hwsim/test_nan.py
index e4db147a5f..5f10d1cc49 100644
--- a/tests/hwsim/test_nan.py
+++ b/tests/hwsim/test_nan.py
@@ -52,6 +52,7 @@ class NanDevice:
self.ndi_name = ndi_name
self.nmi_addr = nmi_addr
self.mgmt_group_cipher = mgmt_group_cipher
+ self.cluster_id = None
def __enter__(self):
self.start()
@@ -79,13 +80,21 @@ class NanDevice:
if ev is None:
raise Exception(f"NAN-CLUSTER-JOIN event not received on {self.ifname}")
- logger.info(f"NAN device started on {self.ifname}")
+ self.cluster_id = split_nan_event(ev)['cluster_id']
+ logger.info(f"NAN device started on {self.ifname} cluster_id={self.cluster_id}")
# Add NDI
if self.ndi_name is not None:
self.dev.interface_add(self.ndi_name, if_type="nan_data",
create=True)
+ def update_cluster_id(self):
+ """Pick up the Cluster ID of a cluster joined after the initial one."""
+ ev = self.wpas.wait_event(["NAN-CLUSTER-JOIN"], timeout=0)
+ if ev:
+ self.cluster_id = split_nan_event(ev)['cluster_id']
+ return self.cluster_id
+
def stop(self):
logger.info(f"NAN device stopping on {self.ifname}")
@@ -432,10 +441,27 @@ def nan_ndp_verify_event(ev, peer_nmi, publish_inst_id=None, init_ndi=None,
if data['csid'] != str(csid):
raise Exception(f"Unexpected csid: got {data['csid']}, expected {str(csid)} in event: {ev}")
+def nan_check_same_cluster(*nan_devs, timeout=1):
+ """Verify that the NAN devices converged into a single cluster """
+ start = time.time()
+ while True:
+ cluster_ids = {nan_dev.update_cluster_id() for nan_dev in nan_devs}
+ if len(cluster_ids) == 1:
+ logger.info(f"NAN devices are in cluster {cluster_ids.pop()}")
+ return
+
+ if time.time() - start >= timeout:
+ raise Exception("NAN devices did not join the same cluster: " +
+ str([nan_dev.cluster_id for nan_dev in nan_devs]))
+
+ time.sleep(0.1)
+
def nan_sync_discovery(pub, sub, service_name, pssi, sssi,
unsolicited=1, solicited=1, active=1,
expect_discovery=True,
timeout=2, cipher_suites=None):
+ nan_check_same_cluster(pub, sub)
+
paddr = pub.wpas.own_addr()
saddr = sub.wpas.own_addr()
@@ -473,6 +499,35 @@ def test_nan_sync_active_subscribe(dev, apdev, params):
pssi="aabbccdd", sssi="ddbbccaa",
unsolicited=0)
+def test_nan_sync_cluster_id_mismatch(dev, apdev, params):
+ """NAN synchronized discovery ignored on Cluster ID mismatch"""
+ with hwsim_nan_radios(count=2) as [wpas1, wpas2], \
+ NanDevice(wpas1, "nan0") as pub, NanDevice(wpas2, "nan1") as sub:
+ nan_check_same_cluster(pub, sub)
+
+ cluster_id = sub.cluster_id.replace(":", "")[-4:]
+ other_cluster_id = f"{int(cluster_id, 16) ^ 0xffff:04x}"
+
+ # Override the subscriber Cluster ID, so that the unsolicited Publish
+ # SDFs are still received but carry a non-matching Cluster ID in A3.
+ sub.set("test_cluster_id", other_cluster_id)
+
+ pid = pub.publish("test_service", ssi="aabbccdd", solicited=0, ttl=60)
+ sid = sub.subscribe("test_service", ssi="ddbbccaa", active=0)
+ logger.info(f"Publish ID: {pid}, Subscribe ID: {sid}")
+
+ ev = sub.wpas.wait_event(["NAN-DISCOVERY-RESULT"], timeout=5)
+ if ev is not None:
+ raise Exception("Unexpected NAN-DISCOVERY-RESULT on Cluster ID mismatch: " + ev)
+
+ # Restore the real Cluster ID and verify successful discovery
+ sub.set("test_cluster_id", cluster_id)
+
+ ev = sub.wpas.wait_event(["NAN-DISCOVERY-RESULT"], timeout=5)
+ if ev is None:
+ raise Exception("NAN-DISCOVERY-RESULT not seen after restoring the Cluster ID")
+ nan_sync_verify_event(ev, pub.wpas.own_addr(), pid, sid, "aabbccdd")
+
def test_nan_sync_with_nmi_addresses(dev, apdev, params):
"""NAN synchronized active subscribe and solicited publish with NMI addresses"""
pnmi_addr = "40:00:00:00:17:00"
@@ -613,6 +668,8 @@ def _nan_sync_publisher_match_filter(sub_tx_filter=None, pub_rx_filter=None,
match=True):
with hwsim_nan_radios(count=2) as [wpas1, wpas2], \
NanDevice(wpas1, "nan0") as pub, NanDevice(wpas2, "nan1") as sub:
+ nan_check_same_cluster(pub, sub)
+
paddr = pub.wpas.own_addr()
saddr = sub.wpas.own_addr()
@@ -725,6 +782,8 @@ def _nan_sync_subscriber_match_filter(pub_tx_filter=None, sub_rx_filter=None,
match=True):
with hwsim_nan_radios(count=2) as [wpas1, wpas2], \
NanDevice(wpas1, "nan0") as pub, NanDevice(wpas2, "nan1") as sub:
+ nan_check_same_cluster(pub, sub)
+
paddr = pub.wpas.own_addr()
saddr = sub.wpas.own_addr()
@@ -1316,6 +1375,8 @@ def test_nan_sched(dev, apdev, params):
def _nan_discover_service(pub, sub, service_name, pssi, sssi, ttl=None,
csid=None, gtk_csid=None, data_path=False):
+ nan_check_same_cluster(pub, sub)
+
paddr = pub.wpas.own_addr()
saddr = sub.wpas.own_addr()
--
2.53.0
More information about the Hostap
mailing list