3 # wpa_supplicant mesh mode tests
4 # Copyright (c) 2014, cozybit Inc.
6 # This software may be distributed under the terms of the BSD license.
7 # See README for more details.
10 logger = logging.getLogger()
14 from wpasupplicant import WpaSupplicant
15 from utils import HwsimSkip
17 def check_mesh_support(dev):
18 flags = int(dev.get_driver_status_field('capa.flags'), 16)
19 if flags & 0x100000000 == 0:
20 raise HwsimSkip("Driver does not support mesh")
22 def check_mesh_scan(dev, params, other_started=False, beacon_int=0):
25 id = dev.request("SCAN " + params)
27 raise Exception("Failed to start scan")
31 ev = dev.wait_event(["CTRL-EVENT-SCAN-STARTED"])
33 raise Exception("Other scan did not start")
34 if "id=" + str(id) in ev:
35 raise Exception("Own scan id unexpectedly included in start event")
37 ev = dev.wait_event(["CTRL-EVENT-SCAN-RESULTS"])
39 raise Exception("Other scan did not complete")
40 if "id=" + str(id) in ev:
42 "Own scan id unexpectedly included in completed event")
44 ev = dev.wait_event(["CTRL-EVENT-SCAN-STARTED"])
46 raise Exception("Scan did not start")
47 if "id=" + str(id) not in ev:
48 raise Exception("Scan id not included in start event")
50 ev = dev.wait_event(["CTRL-EVENT-SCAN-RESULTS"])
52 raise Exception("Scan did not complete")
53 if "id=" + str(id) not in ev:
54 raise Exception("Scan id not included in completed event")
56 res = dev.request("SCAN_RESULTS")
58 if res.find("[MESH]") < 0:
59 raise Exception("Scan did not contain a MESH network")
61 bssid = res.splitlines()[1].split(' ')[0]
62 bss = dev.get_bss(bssid)
64 raise Exception("Could not get BSS entry for mesh")
65 if 'mesh_capability' not in bss:
66 raise Exception("mesh_capability missing from BSS entry")
68 if 'beacon_int' not in bss:
69 raise Exception("beacon_int missing from BSS entry")
70 if str(beacon_int) != bss['beacon_int']:
71 raise Exception("Unexpected beacon_int in BSS entry: " + bss['beacon_int'])
73 def check_mesh_group_added(dev):
74 ev = dev.wait_event(["MESH-GROUP-STARTED"])
76 raise Exception("Test exception: Couldn't join mesh")
79 def check_mesh_group_removed(dev):
80 ev = dev.wait_event(["MESH-GROUP-REMOVED"])
82 raise Exception("Test exception: Couldn't leave mesh")
85 def check_mesh_peer_connected(dev, timeout=10):
86 ev = dev.wait_event(["MESH-PEER-CONNECTED"], timeout=timeout)
88 raise Exception("Test exception: Remote peer did not connect.")
91 def check_mesh_peer_disconnected(dev):
92 ev = dev.wait_event(["MESH-PEER-DISCONNECTED"])
94 raise Exception("Test exception: Peer disconnect event not detected.")
97 def test_wpas_add_set_remove_support(dev):
98 """wpa_supplicant MESH add/set/remove network support"""
99 id = dev[0].add_network()
100 dev[0].set_network(id, "mode", "5")
101 dev[0].remove_network(id)
103 def add_open_mesh_network(dev, freq="2412", start=True, beacon_int=0):
104 id = dev.add_network()
105 dev.set_network(id, "mode", "5")
106 dev.set_network_quoted(id, "ssid", "wpas-mesh-open")
107 dev.set_network(id, "key_mgmt", "NONE")
108 dev.set_network(id, "frequency", freq)
110 dev.set_network(id, "beacon_int", str(beacon_int))
112 dev.mesh_group_add(id)
115 def test_wpas_mesh_group_added(dev):
116 """wpa_supplicant MESH group add"""
117 check_mesh_support(dev[0])
118 add_open_mesh_network(dev[0])
120 # Check for MESH-GROUP-STARTED event
121 check_mesh_group_added(dev[0])
124 def test_wpas_mesh_group_remove(dev):
125 """wpa_supplicant MESH group remove"""
126 check_mesh_support(dev[0])
127 add_open_mesh_network(dev[0])
128 # Check for MESH-GROUP-STARTED event
129 check_mesh_group_added(dev[0])
130 dev[0].mesh_group_remove()
131 # Check for MESH-GROUP-REMOVED event
132 check_mesh_group_removed(dev[0])
133 dev[0].mesh_group_remove()
135 def test_wpas_mesh_peer_connected(dev):
136 """wpa_supplicant MESH peer connected"""
137 check_mesh_support(dev[0])
138 add_open_mesh_network(dev[0], beacon_int=160)
139 add_open_mesh_network(dev[1], beacon_int=160)
141 # Check for mesh joined
142 check_mesh_group_added(dev[0])
143 check_mesh_group_added(dev[1])
145 # Check for peer connected
146 check_mesh_peer_connected(dev[0])
147 check_mesh_peer_connected(dev[1])
150 def test_wpas_mesh_peer_disconnected(dev):
151 """wpa_supplicant MESH peer disconnected"""
152 check_mesh_support(dev[0])
153 add_open_mesh_network(dev[0])
154 add_open_mesh_network(dev[1])
156 # Check for mesh joined
157 check_mesh_group_added(dev[0])
158 check_mesh_group_added(dev[1])
160 # Check for peer connected
161 check_mesh_peer_connected(dev[0])
162 check_mesh_peer_connected(dev[1])
164 # Remove group on dev 1
165 dev[1].mesh_group_remove()
166 # Device 0 should get a disconnection event
167 check_mesh_peer_disconnected(dev[0])
170 def test_wpas_mesh_mode_scan(dev):
171 """wpa_supplicant MESH scan support"""
172 check_mesh_support(dev[0])
173 add_open_mesh_network(dev[0])
174 add_open_mesh_network(dev[1], beacon_int=175)
176 # Check for mesh joined
177 check_mesh_group_added(dev[0])
178 check_mesh_group_added(dev[1])
180 # Check for Mesh scan
181 check_mesh_scan(dev[0], "use_id=1", beacon_int=175)
183 def test_wpas_mesh_open(dev, apdev):
184 """wpa_supplicant open MESH network connectivity"""
185 check_mesh_support(dev[0])
186 add_open_mesh_network(dev[0], freq="2462")
187 add_open_mesh_network(dev[1], freq="2462")
189 # Check for mesh joined
190 check_mesh_group_added(dev[0])
191 check_mesh_group_added(dev[1])
193 # Check for peer connected
194 check_mesh_peer_connected(dev[0])
195 check_mesh_peer_connected(dev[1])
197 # Test connectivity 0->1 and 1->0
198 hwsim_utils.test_connectivity(dev[0], dev[1])
200 def test_wpas_mesh_open_no_auto(dev, apdev):
201 """wpa_supplicant open MESH network connectivity"""
202 check_mesh_support(dev[0])
203 id = add_open_mesh_network(dev[0], start=False)
204 dev[0].set_network(id, "dot11MeshMaxRetries", "16")
205 dev[0].set_network(id, "dot11MeshRetryTimeout", "255")
206 dev[0].mesh_group_add(id)
208 id = add_open_mesh_network(dev[1], start=False)
209 dev[1].set_network(id, "no_auto_peer", "1")
210 dev[1].mesh_group_add(id)
212 # Check for mesh joined
213 check_mesh_group_added(dev[0])
214 check_mesh_group_added(dev[1])
216 # Check for peer connected
217 check_mesh_peer_connected(dev[0], timeout=30)
218 check_mesh_peer_connected(dev[1])
220 # Test connectivity 0->1 and 1->0
221 hwsim_utils.test_connectivity(dev[0], dev[1])
223 def add_mesh_secure_net(dev, psk=True):
224 id = dev.add_network()
225 dev.set_network(id, "mode", "5")
226 dev.set_network_quoted(id, "ssid", "wpas-mesh-sec")
227 dev.set_network(id, "key_mgmt", "SAE")
228 dev.set_network(id, "frequency", "2412")
230 dev.set_network_quoted(id, "psk", "thisismypassphrase!")
233 def test_wpas_mesh_secure(dev, apdev):
234 """wpa_supplicant secure MESH network connectivity"""
235 check_mesh_support(dev[0])
236 dev[0].request("SET sae_groups ")
237 id = add_mesh_secure_net(dev[0])
238 dev[0].mesh_group_add(id)
240 dev[1].request("SET sae_groups ")
241 id = add_mesh_secure_net(dev[1])
242 dev[1].mesh_group_add(id)
244 # Check for mesh joined
245 check_mesh_group_added(dev[0])
246 check_mesh_group_added(dev[1])
248 # Check for peer connected
249 check_mesh_peer_connected(dev[0])
250 check_mesh_peer_connected(dev[1])
252 # Test connectivity 0->1 and 1->0
253 hwsim_utils.test_connectivity(dev[0], dev[1])
255 def test_wpas_mesh_secure_sae_group_mismatch(dev, apdev):
256 """wpa_supplicant secure MESH and SAE group mismatch"""
257 check_mesh_support(dev[0])
258 addr0 = dev[0].p2p_interface_addr()
259 addr1 = dev[1].p2p_interface_addr()
260 addr2 = dev[2].p2p_interface_addr()
262 dev[0].request("SET sae_groups 19 25")
263 id = add_mesh_secure_net(dev[0])
264 dev[0].mesh_group_add(id)
266 dev[1].request("SET sae_groups 19")
267 id = add_mesh_secure_net(dev[1])
268 dev[1].mesh_group_add(id)
270 dev[2].request("SET sae_groups 26")
271 id = add_mesh_secure_net(dev[2])
272 dev[2].mesh_group_add(id)
274 check_mesh_group_added(dev[0])
275 check_mesh_group_added(dev[1])
276 check_mesh_group_added(dev[2])
278 ev = dev[0].wait_event(["MESH-PEER-CONNECTED"])
280 raise Exception("Remote peer did not connect")
282 raise Exception("Unexpected peer connected: " + ev)
284 ev = dev[1].wait_event(["MESH-PEER-CONNECTED"])
286 raise Exception("Remote peer did not connect")
288 raise Exception("Unexpected peer connected: " + ev)
290 ev = dev[2].wait_event(["MESH-PEER-CONNECTED"], timeout=1)
292 raise Exception("Unexpected peer connection at dev[2]: " + ev)
294 ev = dev[0].wait_event(["MESH-PEER-CONNECTED"], timeout=0.1)
296 raise Exception("Unexpected peer connection: " + ev)
298 ev = dev[1].wait_event(["MESH-PEER-CONNECTED"], timeout=0.1)
300 raise Exception("Unexpected peer connection: " + ev)
302 dev[0].request("SET sae_groups ")
303 dev[1].request("SET sae_groups ")
304 dev[2].request("SET sae_groups ")
306 def test_wpas_mesh_secure_sae_missing_password(dev, apdev):
307 """wpa_supplicant secure MESH and missing SAE password"""
308 check_mesh_support(dev[0])
309 id = add_mesh_secure_net(dev[0], psk=False)
310 dev[0].set_network(id, "psk", "8f20b381f9b84371d61b5080ad85cac3c61ab3ca9525be5b2d0f4da3d979187a")
311 dev[0].mesh_group_add(id)
312 ev = dev[0].wait_event(["MESH-GROUP-STARTED", "Could not join mesh"],
315 raise Exception("Timeout on mesh start event")
316 if "MESH-GROUP-STARTED" in ev:
317 raise Exception("Unexpected mesh group start")
318 ev = dev[0].wait_event(["MESH-GROUP-STARTED"], timeout=0.1)
320 raise Exception("Unexpected mesh group start")
322 def test_wpas_mesh_secure_no_auto(dev, apdev):
323 """wpa_supplicant secure MESH network connectivity"""
324 check_mesh_support(dev[0])
325 dev[0].request("SET sae_groups 19")
326 id = add_mesh_secure_net(dev[0])
327 dev[0].mesh_group_add(id)
329 dev[1].request("SET sae_groups 19")
330 id = add_mesh_secure_net(dev[1])
331 dev[1].set_network(id, "no_auto_peer", "1")
332 dev[1].mesh_group_add(id)
334 # Check for mesh joined
335 check_mesh_group_added(dev[0])
336 check_mesh_group_added(dev[1])
338 # Check for peer connected
339 check_mesh_peer_connected(dev[0], timeout=30)
340 check_mesh_peer_connected(dev[1])
342 # Test connectivity 0->1 and 1->0
343 hwsim_utils.test_connectivity(dev[0], dev[1])
345 dev[0].request("SET sae_groups ")
346 dev[1].request("SET sae_groups ")
348 def test_wpas_mesh_ctrl(dev):
349 """wpa_supplicant ctrl_iface mesh command error cases"""
350 check_mesh_support(dev[0])
351 if "FAIL" not in dev[0].request("MESH_GROUP_ADD 123"):
352 raise Exception("Unexpected MESH_GROUP_ADD success")
353 id = dev[0].add_network()
354 if "FAIL" not in dev[0].request("MESH_GROUP_ADD %d" % id):
355 raise Exception("Unexpected MESH_GROUP_ADD success")
356 dev[0].set_network(id, "mode", "5")
357 dev[0].set_network(id, "key_mgmt", "WPA-PSK")
358 if "FAIL" not in dev[0].request("MESH_GROUP_ADD %d" % id):
359 raise Exception("Unexpected MESH_GROUP_ADD success")
361 if "FAIL" not in dev[0].request("MESH_GROUP_REMOVE foo"):
362 raise Exception("Unexpected MESH_GROUP_REMOVE success")
364 def test_wpas_mesh_dynamic_interface(dev):
365 """wpa_supplicant mesh with dynamic interface"""
366 check_mesh_support(dev[0])
370 mesh0 = dev[0].request("MESH_INTERFACE_ADD ifname=mesh0")
372 raise Exception("MESH_INTERFACE_ADD failed")
373 mesh1 = dev[1].request("MESH_INTERFACE_ADD")
375 raise Exception("MESH_INTERFACE_ADD failed")
377 wpas0 = WpaSupplicant(ifname=mesh0)
378 wpas1 = WpaSupplicant(ifname=mesh1)
379 logger.info(mesh0 + " address " + wpas0.get_status_field("address"))
380 logger.info(mesh1 + " address " + wpas1.get_status_field("address"))
382 add_open_mesh_network(wpas0)
383 add_open_mesh_network(wpas1)
384 check_mesh_group_added(wpas0)
385 check_mesh_group_added(wpas1)
386 check_mesh_peer_connected(wpas0)
387 check_mesh_peer_connected(wpas1)
388 hwsim_utils.test_connectivity(wpas0, wpas1)
390 # Must not allow MESH_GROUP_REMOVE on dynamic interface
391 if "FAIL" not in wpas0.request("MESH_GROUP_REMOVE " + mesh0):
392 raise Exception("Invalid MESH_GROUP_REMOVE accepted")
393 if "FAIL" not in wpas1.request("MESH_GROUP_REMOVE " + mesh1):
394 raise Exception("Invalid MESH_GROUP_REMOVE accepted")
396 # Must not allow MESH_GROUP_REMOVE on another radio interface
397 if "FAIL" not in wpas0.request("MESH_GROUP_REMOVE " + mesh1):
398 raise Exception("Invalid MESH_GROUP_REMOVE accepted")
399 if "FAIL" not in wpas1.request("MESH_GROUP_REMOVE " + mesh0):
400 raise Exception("Invalid MESH_GROUP_REMOVE accepted")
402 wpas0.remove_ifname()
403 wpas1.remove_ifname()
405 if "OK" not in dev[0].request("MESH_GROUP_REMOVE " + mesh0):
406 raise Exception("MESH_GROUP_REMOVE failed")
407 if "OK" not in dev[1].request("MESH_GROUP_REMOVE " + mesh1):
408 raise Exception("MESH_GROUP_REMOVE failed")
410 if "FAIL" not in dev[0].request("MESH_GROUP_REMOVE " + mesh0):
411 raise Exception("Invalid MESH_GROUP_REMOVE accepted")
412 if "FAIL" not in dev[1].request("MESH_GROUP_REMOVE " + mesh1):
413 raise Exception("Invalid MESH_GROUP_REMOVE accepted")
415 logger.info("Make sure another dynamic group can be added")
416 mesh0 = dev[0].request("MESH_INTERFACE_ADD ifname=mesh0")
418 raise Exception("MESH_INTERFACE_ADD failed")
419 mesh1 = dev[1].request("MESH_INTERFACE_ADD")
421 raise Exception("MESH_INTERFACE_ADD failed")
423 wpas0 = WpaSupplicant(ifname=mesh0)
424 wpas1 = WpaSupplicant(ifname=mesh1)
425 logger.info(mesh0 + " address " + wpas0.get_status_field("address"))
426 logger.info(mesh1 + " address " + wpas1.get_status_field("address"))
428 add_open_mesh_network(wpas0)
429 add_open_mesh_network(wpas1)
430 check_mesh_group_added(wpas0)
431 check_mesh_group_added(wpas1)
432 check_mesh_peer_connected(wpas0)
433 check_mesh_peer_connected(wpas1)
434 hwsim_utils.test_connectivity(wpas0, wpas1)
437 dev[0].request("MESH_GROUP_REMOVE " + mesh0)
439 dev[1].request("MESH_GROUP_REMOVE " + mesh1)
441 def test_wpas_mesh_max_peering(dev, apdev):
442 """Mesh max peering limit"""
443 check_mesh_support(dev[0])
445 dev[0].request("SET max_peer_links 1")
447 # first, connect dev[0] and dev[1]
448 add_open_mesh_network(dev[0])
449 add_open_mesh_network(dev[1])
451 ev = dev[i].wait_event(["MESH-PEER-CONNECTED"])
453 raise Exception("dev%d did not connect with any peer" % i)
455 # add dev[2] which will try to connect with both dev[0] and dev[1],
456 # but can complete connection only with dev[1]
457 add_open_mesh_network(dev[2])
458 for i in range(1, 3):
459 ev = dev[i].wait_event(["MESH-PEER-CONNECTED"])
461 raise Exception("dev%d did not connect the second peer" % i)
463 ev = dev[0].wait_event(["MESH-PEER-CONNECTED"], timeout=1)
465 raise Exception("dev0 connection beyond max peering limit")
467 ev = dev[2].wait_event(["MESH-PEER-CONNECTED"], timeout=0.1)
469 raise Exception("dev2 reported unexpected peering: " + ev)
472 dev[i].mesh_group_remove()
473 check_mesh_group_removed(dev[i])
475 dev[0].request("SET max_peer_links 99")
477 def test_wpas_mesh_open_5ghz(dev, apdev):
478 """wpa_supplicant open MESH network on 5 GHz band"""
480 _test_wpas_mesh_open_5ghz(dev, apdev)
482 subprocess.call(['iw', 'reg', 'set', '00'])
483 dev[0].flush_scan_cache()
484 dev[1].flush_scan_cache()
486 def _test_wpas_mesh_open_5ghz(dev, apdev):
487 check_mesh_support(dev[0])
488 subprocess.call(['iw', 'reg', 'set', 'US'])
491 ev = dev[i].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=5)
493 raise Exception("No regdom change event")
494 if "alpha2=US" in ev:
496 add_open_mesh_network(dev[i], freq="5180")
498 # Check for mesh joined
499 check_mesh_group_added(dev[0])
500 check_mesh_group_added(dev[1])
502 # Check for peer connected
503 check_mesh_peer_connected(dev[0])
504 check_mesh_peer_connected(dev[1])
506 # Test connectivity 0->1 and 1->0
507 hwsim_utils.test_connectivity(dev[0], dev[1])