]>
Commit | Line | Data |
---|---|---|
68157c06 JL |
1 | # wpa_supplicant mesh mode tests |
2 | # Copyright (c) 2014, cozybit Inc. | |
3 | # | |
4 | # This software may be distributed under the terms of the BSD license. | |
5 | # See README for more details. | |
6 | ||
7e3614df JM |
7 | import logging |
8 | logger = logging.getLogger() | |
fa7f9570 | 9 | import os |
66bb7d97 | 10 | import struct |
de1d5049 | 11 | import subprocess |
fa7f9570 | 12 | import time |
2cbaf0de | 13 | import json |
7e3614df JM |
14 | |
15 | import hwsim_utils | |
e8739be8 | 16 | import hostapd |
7e3614df | 17 | from wpasupplicant import WpaSupplicant |
58284168 | 18 | from utils import HwsimSkip, alloc_fail, fail_test, wait_fail_trigger |
2cbaf0de | 19 | from tshark import run_tshark, run_tshark_json |
e3b38d6e | 20 | from test_ap_ht import set_world_reg |
f5a270b5 | 21 | from hwsim_utils import set_group_map |
68157c06 | 22 | |
b9749b6a | 23 | def check_mesh_support(dev, secure=False): |
2f034795 | 24 | if "MESH" not in dev.get_capability("modes"): |
81e787b7 | 25 | raise HwsimSkip("Driver does not support mesh") |
b9749b6a JM |
26 | if secure and "SAE" not in dev.get_capability("auth_alg"): |
27 | raise HwsimSkip("SAE not supported") | |
31705bf4 | 28 | |
8b260032 | 29 | def check_mesh_scan(dev, params, other_started=False, beacon_int=0): |
68157c06 JL |
30 | if not other_started: |
31 | dev.dump_monitor() | |
32 | id = dev.request("SCAN " + params) | |
33 | if "FAIL" in id: | |
34 | raise Exception("Failed to start scan") | |
35 | id = int(id) | |
36 | ||
37 | if other_started: | |
38 | ev = dev.wait_event(["CTRL-EVENT-SCAN-STARTED"]) | |
39 | if ev is None: | |
40 | raise Exception("Other scan did not start") | |
41 | if "id=" + str(id) in ev: | |
42 | raise Exception("Own scan id unexpectedly included in start event") | |
43 | ||
44 | ev = dev.wait_event(["CTRL-EVENT-SCAN-RESULTS"]) | |
45 | if ev is None: | |
46 | raise Exception("Other scan did not complete") | |
47 | if "id=" + str(id) in ev: | |
48 | raise Exception( | |
49 | "Own scan id unexpectedly included in completed event") | |
50 | ||
51 | ev = dev.wait_event(["CTRL-EVENT-SCAN-STARTED"]) | |
52 | if ev is None: | |
53 | raise Exception("Scan did not start") | |
54 | if "id=" + str(id) not in ev: | |
55 | raise Exception("Scan id not included in start event") | |
56 | ||
57 | ev = dev.wait_event(["CTRL-EVENT-SCAN-RESULTS"]) | |
58 | if ev is None: | |
59 | raise Exception("Scan did not complete") | |
60 | if "id=" + str(id) not in ev: | |
61 | raise Exception("Scan id not included in completed event") | |
62 | ||
63 | res = dev.request("SCAN_RESULTS") | |
64 | ||
f54b926b | 65 | if res.find("[MESH]") < 0: |
68157c06 JL |
66 | raise Exception("Scan did not contain a MESH network") |
67 | ||
fba65f72 JM |
68 | bssid = res.splitlines()[1].split(' ')[0] |
69 | bss = dev.get_bss(bssid) | |
70 | if bss is None: | |
71 | raise Exception("Could not get BSS entry for mesh") | |
72 | if 'mesh_capability' not in bss: | |
73 | raise Exception("mesh_capability missing from BSS entry") | |
8b260032 JM |
74 | if beacon_int: |
75 | if 'beacon_int' not in bss: | |
76 | raise Exception("beacon_int missing from BSS entry") | |
77 | if str(beacon_int) != bss['beacon_int']: | |
78 | raise Exception("Unexpected beacon_int in BSS entry: " + bss['beacon_int']) | |
f05a893e JM |
79 | if '[MESH]' not in bss['flags']: |
80 | raise Exception("BSS output did not include MESH flag") | |
68157c06 JL |
81 | |
82 | def check_mesh_group_added(dev): | |
83 | ev = dev.wait_event(["MESH-GROUP-STARTED"]) | |
84 | if ev is None: | |
85 | raise Exception("Test exception: Couldn't join mesh") | |
86 | ||
87 | ||
88 | def check_mesh_group_removed(dev): | |
89 | ev = dev.wait_event(["MESH-GROUP-REMOVED"]) | |
90 | if ev is None: | |
91 | raise Exception("Test exception: Couldn't leave mesh") | |
92 | ||
93 | ||
e0cfd223 JM |
94 | def check_mesh_peer_connected(dev, timeout=10): |
95 | ev = dev.wait_event(["MESH-PEER-CONNECTED"], timeout=timeout) | |
68157c06 JL |
96 | if ev is None: |
97 | raise Exception("Test exception: Remote peer did not connect.") | |
98 | ||
99 | ||
100 | def check_mesh_peer_disconnected(dev): | |
101 | ev = dev.wait_event(["MESH-PEER-DISCONNECTED"]) | |
102 | if ev is None: | |
103 | raise Exception("Test exception: Peer disconnect event not detected.") | |
104 | ||
105 | ||
106 | def test_wpas_add_set_remove_support(dev): | |
107 | """wpa_supplicant MESH add/set/remove network support""" | |
0ff7afbc | 108 | check_mesh_support(dev[0]) |
68157c06 JL |
109 | id = dev[0].add_network() |
110 | dev[0].set_network(id, "mode", "5") | |
111 | dev[0].remove_network(id) | |
112 | ||
71a3b85f | 113 | def add_open_mesh_network(dev, freq="2412", start=True, beacon_int=0, |
e91877fb JM |
114 | basic_rates=None, chwidth=0, disable_vht=False, |
115 | disable_ht40=False): | |
7e3614df JM |
116 | id = dev.add_network() |
117 | dev.set_network(id, "mode", "5") | |
118 | dev.set_network_quoted(id, "ssid", "wpas-mesh-open") | |
119 | dev.set_network(id, "key_mgmt", "NONE") | |
2cf6341e JM |
120 | if freq: |
121 | dev.set_network(id, "frequency", freq) | |
a74a1e4e JM |
122 | if chwidth > 0: |
123 | dev.set_network(id, "max_oper_chwidth", str(chwidth)) | |
8b260032 JM |
124 | if beacon_int: |
125 | dev.set_network(id, "beacon_int", str(beacon_int)) | |
71a3b85f JM |
126 | if basic_rates: |
127 | dev.set_network(id, "mesh_basic_rates", basic_rates) | |
e91877fb JM |
128 | if disable_vht: |
129 | dev.set_network(id, "disable_vht", "1") | |
130 | if disable_ht40: | |
131 | dev.set_network(id, "disable_ht40", "1") | |
d48b64ba JM |
132 | if start: |
133 | dev.mesh_group_add(id) | |
7e3614df | 134 | return id |
68157c06 JL |
135 | |
136 | def test_wpas_mesh_group_added(dev): | |
137 | """wpa_supplicant MESH group add""" | |
81e787b7 | 138 | check_mesh_support(dev[0]) |
d48b64ba | 139 | add_open_mesh_network(dev[0]) |
68157c06 JL |
140 | |
141 | # Check for MESH-GROUP-STARTED event | |
142 | check_mesh_group_added(dev[0]) | |
143 | ||
144 | ||
145 | def test_wpas_mesh_group_remove(dev): | |
146 | """wpa_supplicant MESH group remove""" | |
81e787b7 | 147 | check_mesh_support(dev[0]) |
70437ae5 | 148 | add_open_mesh_network(dev[0]) |
68157c06 JL |
149 | # Check for MESH-GROUP-STARTED event |
150 | check_mesh_group_added(dev[0]) | |
151 | dev[0].mesh_group_remove() | |
152 | # Check for MESH-GROUP-REMOVED event | |
153 | check_mesh_group_removed(dev[0]) | |
7e3614df | 154 | dev[0].mesh_group_remove() |
68157c06 JL |
155 | |
156 | def test_wpas_mesh_peer_connected(dev): | |
157 | """wpa_supplicant MESH peer connected""" | |
81e787b7 | 158 | check_mesh_support(dev[0]) |
70437ae5 JM |
159 | add_open_mesh_network(dev[0], beacon_int=160) |
160 | add_open_mesh_network(dev[1], beacon_int=160) | |
68157c06 JL |
161 | |
162 | # Check for mesh joined | |
163 | check_mesh_group_added(dev[0]) | |
164 | check_mesh_group_added(dev[1]) | |
165 | ||
166 | # Check for peer connected | |
167 | check_mesh_peer_connected(dev[0]) | |
168 | check_mesh_peer_connected(dev[1]) | |
169 | ||
170 | ||
171 | def test_wpas_mesh_peer_disconnected(dev): | |
172 | """wpa_supplicant MESH peer disconnected""" | |
81e787b7 | 173 | check_mesh_support(dev[0]) |
d48b64ba JM |
174 | add_open_mesh_network(dev[0]) |
175 | add_open_mesh_network(dev[1]) | |
68157c06 JL |
176 | |
177 | # Check for mesh joined | |
178 | check_mesh_group_added(dev[0]) | |
179 | check_mesh_group_added(dev[1]) | |
180 | ||
181 | # Check for peer connected | |
182 | check_mesh_peer_connected(dev[0]) | |
183 | check_mesh_peer_connected(dev[1]) | |
184 | ||
185 | # Remove group on dev 1 | |
186 | dev[1].mesh_group_remove() | |
187 | # Device 0 should get a disconnection event | |
188 | check_mesh_peer_disconnected(dev[0]) | |
189 | ||
190 | ||
191 | def test_wpas_mesh_mode_scan(dev): | |
192 | """wpa_supplicant MESH scan support""" | |
81e787b7 | 193 | check_mesh_support(dev[0]) |
70437ae5 JM |
194 | add_open_mesh_network(dev[0]) |
195 | add_open_mesh_network(dev[1], beacon_int=175) | |
68157c06 JL |
196 | |
197 | # Check for mesh joined | |
198 | check_mesh_group_added(dev[0]) | |
199 | check_mesh_group_added(dev[1]) | |
200 | ||
201 | # Check for Mesh scan | |
f05a893e | 202 | check_mesh_scan(dev[0], "use_id=1 freq=2412", beacon_int=175) |
68157c06 | 203 | |
4b9481bc JM |
204 | def test_wpas_mesh_open(dev, apdev): |
205 | """wpa_supplicant open MESH network connectivity""" | |
81e787b7 | 206 | check_mesh_support(dev[0]) |
71a3b85f JM |
207 | add_open_mesh_network(dev[0], freq="2462", basic_rates="60 120 240") |
208 | add_open_mesh_network(dev[1], freq="2462", basic_rates="60 120 240") | |
68157c06 JL |
209 | |
210 | # Check for mesh joined | |
211 | check_mesh_group_added(dev[0]) | |
212 | check_mesh_group_added(dev[1]) | |
213 | ||
214 | # Check for peer connected | |
215 | check_mesh_peer_connected(dev[0]) | |
216 | check_mesh_peer_connected(dev[1]) | |
217 | ||
218 | # Test connectivity 0->1 and 1->0 | |
4b9481bc | 219 | hwsim_utils.test_connectivity(dev[0], dev[1]) |
68157c06 | 220 | |
e18d1708 JM |
221 | state = dev[0].get_status_field("wpa_state") |
222 | if state != "COMPLETED": | |
223 | raise Exception("Unexpected wpa_state on dev0: " + state) | |
224 | state = dev[1].get_status_field("wpa_state") | |
225 | if state != "COMPLETED": | |
226 | raise Exception("Unexpected wpa_state on dev1: " + state) | |
227 | ||
5c30a84b JM |
228 | mode = dev[0].get_status_field("mode") |
229 | if mode != "mesh": | |
230 | raise Exception("Unexpected mode: " + mode) | |
231 | ||
4b9481bc | 232 | def test_wpas_mesh_open_no_auto(dev, apdev): |
14637401 | 233 | """wpa_supplicant open MESH network connectivity""" |
81e787b7 | 234 | check_mesh_support(dev[0]) |
d48b64ba | 235 | id = add_open_mesh_network(dev[0], start=False) |
73a2f828 JM |
236 | dev[0].set_network(id, "dot11MeshMaxRetries", "16") |
237 | dev[0].set_network(id, "dot11MeshRetryTimeout", "255") | |
68157c06 JL |
238 | dev[0].mesh_group_add(id) |
239 | ||
d48b64ba | 240 | id = add_open_mesh_network(dev[1], start=False) |
68157c06 JL |
241 | dev[1].set_network(id, "no_auto_peer", "1") |
242 | dev[1].mesh_group_add(id) | |
243 | ||
244 | # Check for mesh joined | |
245 | check_mesh_group_added(dev[0]) | |
246 | check_mesh_group_added(dev[1]) | |
247 | ||
248 | # Check for peer connected | |
e0cfd223 | 249 | check_mesh_peer_connected(dev[0], timeout=30) |
68157c06 JL |
250 | check_mesh_peer_connected(dev[1]) |
251 | ||
252 | # Test connectivity 0->1 and 1->0 | |
4b9481bc | 253 | hwsim_utils.test_connectivity(dev[0], dev[1]) |
68157c06 | 254 | |
d80d8c6f JM |
255 | def test_mesh_open_no_auto2(dev, apdev): |
256 | """Open mesh network connectivity, no_auto on both peers""" | |
257 | check_mesh_support(dev[0]) | |
258 | id = add_open_mesh_network(dev[0], start=False) | |
259 | dev[0].set_network(id, "no_auto_peer", "1") | |
260 | dev[0].mesh_group_add(id) | |
261 | ||
262 | id = add_open_mesh_network(dev[1], start=False) | |
263 | dev[1].set_network(id, "no_auto_peer", "1") | |
264 | dev[1].mesh_group_add(id) | |
265 | ||
266 | check_mesh_group_added(dev[0]) | |
267 | check_mesh_group_added(dev[1]) | |
268 | ||
269 | ev = dev[0].wait_event(["will not initiate new peer link"], timeout=10) | |
270 | if ev is None: | |
271 | raise Exception("Missing no-initiate message") | |
272 | addr1 = dev[1].own_addr() | |
273 | if "OK" not in dev[0].request("MESH_PEER_ADD " + addr1): | |
274 | raise Exception("MESH_PEER_ADD failed") | |
275 | if "FAIL" not in dev[0].request("MESH_PEER_ADD ff:ff:ff:ff:ff:ff"): | |
276 | raise Exception("MESH_PEER_ADD with unknown STA succeeded") | |
277 | check_mesh_peer_connected(dev[0], timeout=30) | |
278 | check_mesh_peer_connected(dev[1]) | |
279 | if "FAIL" not in dev[0].request("MESH_PEER_ADD " + addr1): | |
280 | raise Exception("MESH_PEER_ADD succeeded for connected STA") | |
281 | hwsim_utils.test_connectivity(dev[0], dev[1]) | |
282 | ||
704e9d0f MH |
283 | def test_mesh_open_rssi_threshold(dev, apdev): |
284 | """Open mesh network with RSSI threshold""" | |
285 | check_mesh_support(dev[0]) | |
286 | ||
287 | _test_mesh_open_rssi_threshold(dev, apdev, -255, -255) | |
288 | _test_mesh_open_rssi_threshold(dev, apdev, 0, 0) | |
289 | _test_mesh_open_rssi_threshold(dev, apdev, 1, 0) | |
290 | ||
291 | def _test_mesh_open_rssi_threshold(dev, apdev, value, expected): | |
292 | id = add_open_mesh_network(dev[0], start=False) | |
293 | dev[0].set_network(id, "mesh_rssi_threshold", str(value)) | |
294 | dev[0].mesh_group_add(id) | |
295 | check_mesh_group_added(dev[0]) | |
296 | ||
297 | cmd = subprocess.Popen([ "iw", "dev", dev[0].ifname, "get", "mesh_param", | |
298 | "mesh_rssi_threshold" ], stdout=subprocess.PIPE) | |
299 | mesh_rssi_threshold = int(cmd.stdout.read().split(" ")[0]) | |
300 | ||
301 | dev[0].mesh_group_remove() | |
302 | check_mesh_group_removed(dev[0]) | |
303 | ||
304 | if mesh_rssi_threshold != expected: | |
305 | raise Exception("mesh_rssi_threshold should be " + str(expected) + | |
306 | ": " + str(mesh_rssi_threshold)) | |
307 | ||
f75ed521 | 308 | def add_mesh_secure_net(dev, psk=True, pmf=False, pairwise=None, group=None, |
9a0ae89d | 309 | sae_password=False, sae_password_id=None): |
54cacef5 JM |
310 | id = dev.add_network() |
311 | dev.set_network(id, "mode", "5") | |
312 | dev.set_network_quoted(id, "ssid", "wpas-mesh-sec") | |
313 | dev.set_network(id, "key_mgmt", "SAE") | |
314 | dev.set_network(id, "frequency", "2412") | |
f75ed521 JM |
315 | if sae_password: |
316 | dev.set_network_quoted(id, "sae_password", "thisismypassphrase!") | |
9a0ae89d JM |
317 | if sae_password_id: |
318 | dev.set_network_quoted(id, "sae_password_id", sae_password_id) | |
11ace2ed JM |
319 | if psk: |
320 | dev.set_network_quoted(id, "psk", "thisismypassphrase!") | |
074f7284 JM |
321 | if pmf: |
322 | dev.set_network(id, "ieee80211w", "2") | |
94e8fe90 JM |
323 | if pairwise: |
324 | dev.set_network(id, "pairwise", pairwise) | |
325 | if group: | |
326 | dev.set_network(id, "group", group) | |
54cacef5 | 327 | return id |
68157c06 | 328 | |
4b9481bc JM |
329 | def test_wpas_mesh_secure(dev, apdev): |
330 | """wpa_supplicant secure MESH network connectivity""" | |
b9749b6a | 331 | check_mesh_support(dev[0], secure=True) |
17ffdf39 | 332 | dev[0].request("SET sae_groups ") |
54cacef5 | 333 | id = add_mesh_secure_net(dev[0]) |
68157c06 JL |
334 | dev[0].mesh_group_add(id) |
335 | ||
17ffdf39 | 336 | dev[1].request("SET sae_groups ") |
54cacef5 | 337 | id = add_mesh_secure_net(dev[1]) |
68157c06 JL |
338 | dev[1].mesh_group_add(id) |
339 | ||
340 | # Check for mesh joined | |
341 | check_mesh_group_added(dev[0]) | |
342 | check_mesh_group_added(dev[1]) | |
343 | ||
344 | # Check for peer connected | |
345 | check_mesh_peer_connected(dev[0]) | |
346 | check_mesh_peer_connected(dev[1]) | |
347 | ||
348 | # Test connectivity 0->1 and 1->0 | |
4b9481bc | 349 | hwsim_utils.test_connectivity(dev[0], dev[1]) |
68157c06 | 350 | |
e18d1708 JM |
351 | state = dev[0].get_status_field("wpa_state") |
352 | if state != "COMPLETED": | |
353 | raise Exception("Unexpected wpa_state on dev0: " + state) | |
354 | state = dev[1].get_status_field("wpa_state") | |
355 | if state != "COMPLETED": | |
356 | raise Exception("Unexpected wpa_state on dev1: " + state) | |
357 | ||
f75ed521 JM |
358 | def test_wpas_mesh_secure_sae_password(dev, apdev): |
359 | """wpa_supplicant secure mesh using sae_password""" | |
360 | check_mesh_support(dev[0], secure=True) | |
361 | dev[0].request("SET sae_groups ") | |
362 | id = add_mesh_secure_net(dev[0], psk=False, sae_password=True) | |
363 | dev[0].mesh_group_add(id) | |
364 | ||
365 | dev[1].request("SET sae_groups ") | |
366 | id = add_mesh_secure_net(dev[1]) | |
367 | dev[1].mesh_group_add(id) | |
368 | ||
369 | check_mesh_group_added(dev[0]) | |
370 | check_mesh_group_added(dev[1]) | |
371 | ||
372 | check_mesh_peer_connected(dev[0]) | |
373 | check_mesh_peer_connected(dev[1]) | |
374 | ||
375 | hwsim_utils.test_connectivity(dev[0], dev[1]) | |
376 | ||
9a0ae89d JM |
377 | def test_wpas_mesh_secure_sae_password_id(dev, apdev): |
378 | """Secure mesh using sae_password and password identifier""" | |
379 | check_mesh_support(dev[0], secure=True) | |
380 | dev[0].request("SET sae_groups ") | |
381 | id = add_mesh_secure_net(dev[0], psk=False, sae_password=True, | |
382 | sae_password_id="pw id") | |
383 | dev[0].mesh_group_add(id) | |
384 | ||
385 | dev[1].request("SET sae_groups ") | |
386 | id = add_mesh_secure_net(dev[1], sae_password=True, | |
387 | sae_password_id="pw id") | |
388 | dev[1].mesh_group_add(id) | |
389 | ||
390 | check_mesh_group_added(dev[0]) | |
391 | check_mesh_group_added(dev[1]) | |
392 | ||
393 | check_mesh_peer_connected(dev[0]) | |
394 | check_mesh_peer_connected(dev[1]) | |
395 | ||
396 | hwsim_utils.test_connectivity(dev[0], dev[1]) | |
397 | ||
398 | def test_wpas_mesh_secure_sae_password_id_mismatch(dev, apdev): | |
399 | """Secure mesh using sae_password and password identifier mismatch""" | |
400 | check_mesh_support(dev[0], secure=True) | |
401 | dev[0].request("SET sae_groups ") | |
402 | id = add_mesh_secure_net(dev[0], psk=False, sae_password=True, | |
403 | sae_password_id="pw id") | |
404 | dev[0].mesh_group_add(id) | |
405 | ||
406 | dev[1].request("SET sae_groups ") | |
407 | id = add_mesh_secure_net(dev[1], sae_password=True, | |
408 | sae_password_id="wrong") | |
409 | dev[1].mesh_group_add(id) | |
410 | ||
411 | check_mesh_group_added(dev[0]) | |
412 | check_mesh_group_added(dev[1]) | |
413 | ||
414 | ev = dev[0].wait_event(["CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER"], | |
415 | timeout=10) | |
416 | if ev is None: | |
417 | raise Exception("Unknown Password Identifier not noticed") | |
418 | ||
074f7284 JM |
419 | def test_mesh_secure_pmf(dev, apdev): |
420 | """Secure mesh network connectivity with PMF enabled""" | |
421 | check_mesh_support(dev[0], secure=True) | |
422 | dev[0].request("SET sae_groups ") | |
423 | id = add_mesh_secure_net(dev[0], pmf=True) | |
424 | dev[0].mesh_group_add(id) | |
425 | ||
426 | dev[1].request("SET sae_groups ") | |
427 | id = add_mesh_secure_net(dev[1], pmf=True) | |
428 | dev[1].mesh_group_add(id) | |
429 | ||
430 | # Check for mesh joined | |
431 | check_mesh_group_added(dev[0]) | |
432 | check_mesh_group_added(dev[1]) | |
433 | ||
434 | # Check for peer connected | |
435 | check_mesh_peer_connected(dev[0]) | |
436 | check_mesh_peer_connected(dev[1]) | |
437 | ||
438 | # Test connectivity 0->1 and 1->0 | |
439 | hwsim_utils.test_connectivity(dev[0], dev[1]) | |
440 | ||
94e8fe90 JM |
441 | def run_mesh_secure(dev, cipher): |
442 | if cipher not in dev[0].get_capability("pairwise"): | |
443 | raise HwsimSkip("Cipher %s not supported" % cipher) | |
444 | check_mesh_support(dev[0], secure=True) | |
445 | dev[0].request("SET sae_groups ") | |
446 | id = add_mesh_secure_net(dev[0], pairwise=cipher, group=cipher) | |
447 | dev[0].mesh_group_add(id) | |
448 | ||
449 | dev[1].request("SET sae_groups ") | |
450 | id = add_mesh_secure_net(dev[1], pairwise=cipher, group=cipher) | |
451 | dev[1].mesh_group_add(id) | |
452 | ||
453 | # Check for mesh joined | |
454 | check_mesh_group_added(dev[0]) | |
455 | check_mesh_group_added(dev[1]) | |
456 | ||
457 | # Check for peer connected | |
458 | check_mesh_peer_connected(dev[0]) | |
459 | check_mesh_peer_connected(dev[1]) | |
460 | ||
461 | # Test connectivity 0->1 and 1->0 | |
462 | hwsim_utils.test_connectivity(dev[0], dev[1]) | |
463 | ||
464 | def test_mesh_secure_ccmp(dev, apdev): | |
465 | """Secure mesh with CCMP""" | |
466 | run_mesh_secure(dev, "CCMP") | |
467 | ||
468 | def test_mesh_secure_gcmp(dev, apdev): | |
469 | """Secure mesh with GCMP""" | |
470 | run_mesh_secure(dev, "GCMP") | |
471 | ||
472 | def test_mesh_secure_gcmp_256(dev, apdev): | |
473 | """Secure mesh with GCMP-256""" | |
474 | run_mesh_secure(dev, "GCMP-256") | |
475 | ||
476 | def test_mesh_secure_ccmp_256(dev, apdev): | |
477 | """Secure mesh with CCMP-256""" | |
478 | run_mesh_secure(dev, "CCMP-256") | |
479 | ||
480 | def test_mesh_secure_invalid_pairwise_cipher(dev, apdev): | |
481 | """Secure mesh and invalid group cipher""" | |
482 | check_mesh_support(dev[0], secure=True) | |
483 | dev[0].request("SET sae_groups ") | |
484 | id = add_mesh_secure_net(dev[0], pairwise="TKIP", group="CCMP") | |
485 | if dev[0].mesh_group_add(id) != None: | |
486 | raise Exception("Unexpected group add success") | |
487 | ev = dev[0].wait_event(["mesh: Invalid pairwise cipher"], timeout=1) | |
488 | if ev is None: | |
489 | raise Exception("Invalid pairwise cipher not reported") | |
490 | ||
491 | def test_mesh_secure_invalid_group_cipher(dev, apdev): | |
492 | """Secure mesh and invalid group cipher""" | |
493 | check_mesh_support(dev[0], secure=True) | |
494 | dev[0].request("SET sae_groups ") | |
495 | id = add_mesh_secure_net(dev[0], pairwise="CCMP", group="TKIP") | |
496 | if dev[0].mesh_group_add(id) != None: | |
497 | raise Exception("Unexpected group add success") | |
498 | ev = dev[0].wait_event(["mesh: Invalid group cipher"], timeout=1) | |
499 | if ev is None: | |
500 | raise Exception("Invalid group cipher not reported") | |
501 | ||
54cacef5 JM |
502 | def test_wpas_mesh_secure_sae_group_mismatch(dev, apdev): |
503 | """wpa_supplicant secure MESH and SAE group mismatch""" | |
b9749b6a | 504 | check_mesh_support(dev[0], secure=True) |
54cacef5 JM |
505 | addr0 = dev[0].p2p_interface_addr() |
506 | addr1 = dev[1].p2p_interface_addr() | |
507 | addr2 = dev[2].p2p_interface_addr() | |
68157c06 | 508 | |
54cacef5 JM |
509 | dev[0].request("SET sae_groups 19 25") |
510 | id = add_mesh_secure_net(dev[0]) | |
68157c06 JL |
511 | dev[0].mesh_group_add(id) |
512 | ||
54cacef5 JM |
513 | dev[1].request("SET sae_groups 19") |
514 | id = add_mesh_secure_net(dev[1]) | |
515 | dev[1].mesh_group_add(id) | |
516 | ||
517 | dev[2].request("SET sae_groups 26") | |
518 | id = add_mesh_secure_net(dev[2]) | |
519 | dev[2].mesh_group_add(id) | |
520 | ||
521 | check_mesh_group_added(dev[0]) | |
522 | check_mesh_group_added(dev[1]) | |
523 | check_mesh_group_added(dev[2]) | |
524 | ||
525 | ev = dev[0].wait_event(["MESH-PEER-CONNECTED"]) | |
526 | if ev is None: | |
527 | raise Exception("Remote peer did not connect") | |
528 | if addr1 not in ev: | |
529 | raise Exception("Unexpected peer connected: " + ev) | |
530 | ||
531 | ev = dev[1].wait_event(["MESH-PEER-CONNECTED"]) | |
532 | if ev is None: | |
533 | raise Exception("Remote peer did not connect") | |
534 | if addr0 not in ev: | |
535 | raise Exception("Unexpected peer connected: " + ev) | |
536 | ||
537 | ev = dev[2].wait_event(["MESH-PEER-CONNECTED"], timeout=1) | |
538 | if ev is not None: | |
539 | raise Exception("Unexpected peer connection at dev[2]: " + ev) | |
540 | ||
541 | ev = dev[0].wait_event(["MESH-PEER-CONNECTED"], timeout=0.1) | |
542 | if ev is not None: | |
543 | raise Exception("Unexpected peer connection: " + ev) | |
544 | ||
545 | ev = dev[1].wait_event(["MESH-PEER-CONNECTED"], timeout=0.1) | |
546 | if ev is not None: | |
547 | raise Exception("Unexpected peer connection: " + ev) | |
548 | ||
549 | dev[0].request("SET sae_groups ") | |
17ffdf39 | 550 | dev[1].request("SET sae_groups ") |
54cacef5 | 551 | dev[2].request("SET sae_groups ") |
9ec916e9 JM |
552 | |
553 | def test_wpas_mesh_secure_sae_group_negotiation(dev, apdev): | |
554 | """wpa_supplicant secure MESH and SAE group negotiation""" | |
555 | check_mesh_support(dev[0], secure=True) | |
556 | addr0 = dev[0].own_addr() | |
557 | addr1 = dev[1].own_addr() | |
558 | ||
559 | #dev[0].request("SET sae_groups 21 20 25 26") | |
a680f4ef | 560 | dev[0].request("SET sae_groups 26") |
9ec916e9 JM |
561 | id = add_mesh_secure_net(dev[0]) |
562 | dev[0].mesh_group_add(id) | |
563 | ||
a680f4ef | 564 | dev[1].request("SET sae_groups 19 26") |
9ec916e9 JM |
565 | id = add_mesh_secure_net(dev[1]) |
566 | dev[1].mesh_group_add(id) | |
567 | ||
568 | check_mesh_group_added(dev[0]) | |
569 | check_mesh_group_added(dev[1]) | |
570 | ||
571 | check_mesh_peer_connected(dev[0]) | |
572 | check_mesh_peer_connected(dev[1]) | |
573 | ||
574 | dev[0].request("SET sae_groups ") | |
575 | dev[1].request("SET sae_groups ") | |
54cacef5 | 576 | |
11ace2ed JM |
577 | def test_wpas_mesh_secure_sae_missing_password(dev, apdev): |
578 | """wpa_supplicant secure MESH and missing SAE password""" | |
b9749b6a | 579 | check_mesh_support(dev[0], secure=True) |
11ace2ed JM |
580 | id = add_mesh_secure_net(dev[0], psk=False) |
581 | dev[0].set_network(id, "psk", "8f20b381f9b84371d61b5080ad85cac3c61ab3ca9525be5b2d0f4da3d979187a") | |
582 | dev[0].mesh_group_add(id) | |
583 | ev = dev[0].wait_event(["MESH-GROUP-STARTED", "Could not join mesh"], | |
584 | timeout=5) | |
585 | if ev is None: | |
586 | raise Exception("Timeout on mesh start event") | |
587 | if "MESH-GROUP-STARTED" in ev: | |
588 | raise Exception("Unexpected mesh group start") | |
589 | ev = dev[0].wait_event(["MESH-GROUP-STARTED"], timeout=0.1) | |
590 | if ev is not None: | |
591 | raise Exception("Unexpected mesh group start") | |
592 | ||
4b9481bc JM |
593 | def test_wpas_mesh_secure_no_auto(dev, apdev): |
594 | """wpa_supplicant secure MESH network connectivity""" | |
b9749b6a | 595 | check_mesh_support(dev[0], secure=True) |
54cacef5 JM |
596 | dev[0].request("SET sae_groups 19") |
597 | id = add_mesh_secure_net(dev[0]) | |
598 | dev[0].mesh_group_add(id) | |
599 | ||
600 | dev[1].request("SET sae_groups 19") | |
601 | id = add_mesh_secure_net(dev[1]) | |
68157c06 JL |
602 | dev[1].set_network(id, "no_auto_peer", "1") |
603 | dev[1].mesh_group_add(id) | |
604 | ||
605 | # Check for mesh joined | |
606 | check_mesh_group_added(dev[0]) | |
607 | check_mesh_group_added(dev[1]) | |
608 | ||
609 | # Check for peer connected | |
e0cfd223 | 610 | check_mesh_peer_connected(dev[0], timeout=30) |
68157c06 JL |
611 | check_mesh_peer_connected(dev[1]) |
612 | ||
613 | # Test connectivity 0->1 and 1->0 | |
4b9481bc | 614 | hwsim_utils.test_connectivity(dev[0], dev[1]) |
68157c06 | 615 | |
54cacef5 JM |
616 | dev[0].request("SET sae_groups ") |
617 | dev[1].request("SET sae_groups ") | |
68157c06 | 618 | |
df49b90e JM |
619 | def test_wpas_mesh_secure_dropped_frame(dev, apdev): |
620 | """Secure mesh network connectivity when the first plink Open is dropped""" | |
621 | check_mesh_support(dev[0], secure=True) | |
622 | ||
623 | dev[0].request("SET ext_mgmt_frame_handling 1") | |
624 | dev[0].request("SET sae_groups ") | |
625 | id = add_mesh_secure_net(dev[0]) | |
626 | dev[0].mesh_group_add(id) | |
627 | ||
628 | dev[1].request("SET sae_groups ") | |
629 | id = add_mesh_secure_net(dev[1]) | |
630 | dev[1].mesh_group_add(id) | |
631 | ||
632 | # Check for mesh joined | |
633 | check_mesh_group_added(dev[0]) | |
634 | check_mesh_group_added(dev[1]) | |
635 | ||
636 | # Drop the first Action frame (plink Open) to test unexpected order of | |
637 | # Confirm/Open messages. | |
638 | count = 0 | |
639 | while True: | |
640 | count += 1 | |
641 | if count > 10: | |
642 | raise Exception("Did not see Action frames") | |
643 | rx_msg = dev[0].mgmt_rx() | |
644 | if rx_msg is None: | |
645 | raise Exception("MGMT-RX timeout") | |
646 | if rx_msg['subtype'] == 13: | |
647 | logger.info("Drop the first Action frame") | |
648 | break | |
649 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(rx_msg['freq'], rx_msg['datarate'], rx_msg['ssi_signal'], rx_msg['frame'].encode('hex'))): | |
650 | raise Exception("MGMT_RX_PROCESS failed") | |
651 | ||
652 | dev[0].request("SET ext_mgmt_frame_handling 0") | |
653 | ||
654 | # Check for peer connected | |
655 | check_mesh_peer_connected(dev[0]) | |
656 | check_mesh_peer_connected(dev[1]) | |
657 | ||
658 | # Test connectivity 0->1 and 1->0 | |
659 | hwsim_utils.test_connectivity(dev[0], dev[1]) | |
660 | ||
09d554d1 JM |
661 | def test_mesh_secure_fail(dev, apdev): |
662 | """Secure mesh network connectivity failure""" | |
663 | check_mesh_support(dev[0], secure=True) | |
664 | dev[0].request("SET sae_groups ") | |
665 | id = add_mesh_secure_net(dev[0], pmf=True) | |
666 | dev[0].mesh_group_add(id) | |
667 | ||
668 | dev[1].request("SET sae_groups ") | |
669 | id = add_mesh_secure_net(dev[1], pmf=True) | |
670 | ||
671 | with fail_test(dev[0], 1, "wpa_driver_nl80211_sta_add;mesh_mpm_auth_peer"): | |
672 | dev[1].mesh_group_add(id) | |
673 | ||
674 | check_mesh_group_added(dev[0]) | |
675 | check_mesh_group_added(dev[1]) | |
676 | ||
677 | check_mesh_peer_connected(dev[0]) | |
678 | check_mesh_peer_connected(dev[1]) | |
679 | ||
5e2a8ec9 JM |
680 | def test_wpas_mesh_ctrl(dev): |
681 | """wpa_supplicant ctrl_iface mesh command error cases""" | |
81e787b7 | 682 | check_mesh_support(dev[0]) |
5e2a8ec9 JM |
683 | if "FAIL" not in dev[0].request("MESH_GROUP_ADD 123"): |
684 | raise Exception("Unexpected MESH_GROUP_ADD success") | |
685 | id = dev[0].add_network() | |
686 | if "FAIL" not in dev[0].request("MESH_GROUP_ADD %d" % id): | |
687 | raise Exception("Unexpected MESH_GROUP_ADD success") | |
688 | dev[0].set_network(id, "mode", "5") | |
689 | dev[0].set_network(id, "key_mgmt", "WPA-PSK") | |
690 | if "FAIL" not in dev[0].request("MESH_GROUP_ADD %d" % id): | |
691 | raise Exception("Unexpected MESH_GROUP_ADD success") | |
692 | ||
693 | if "FAIL" not in dev[0].request("MESH_GROUP_REMOVE foo"): | |
694 | raise Exception("Unexpected MESH_GROUP_REMOVE success") | |
7e3614df JM |
695 | |
696 | def test_wpas_mesh_dynamic_interface(dev): | |
697 | """wpa_supplicant mesh with dynamic interface""" | |
81e787b7 | 698 | check_mesh_support(dev[0]) |
7e3614df JM |
699 | mesh0 = None |
700 | mesh1 = None | |
701 | try: | |
702 | mesh0 = dev[0].request("MESH_INTERFACE_ADD ifname=mesh0") | |
703 | if "FAIL" in mesh0: | |
704 | raise Exception("MESH_INTERFACE_ADD failed") | |
705 | mesh1 = dev[1].request("MESH_INTERFACE_ADD") | |
706 | if "FAIL" in mesh1: | |
707 | raise Exception("MESH_INTERFACE_ADD failed") | |
708 | ||
709 | wpas0 = WpaSupplicant(ifname=mesh0) | |
710 | wpas1 = WpaSupplicant(ifname=mesh1) | |
711 | logger.info(mesh0 + " address " + wpas0.get_status_field("address")) | |
712 | logger.info(mesh1 + " address " + wpas1.get_status_field("address")) | |
713 | ||
714 | add_open_mesh_network(wpas0) | |
715 | add_open_mesh_network(wpas1) | |
716 | check_mesh_group_added(wpas0) | |
717 | check_mesh_group_added(wpas1) | |
718 | check_mesh_peer_connected(wpas0) | |
719 | check_mesh_peer_connected(wpas1) | |
720 | hwsim_utils.test_connectivity(wpas0, wpas1) | |
721 | ||
722 | # Must not allow MESH_GROUP_REMOVE on dynamic interface | |
723 | if "FAIL" not in wpas0.request("MESH_GROUP_REMOVE " + mesh0): | |
724 | raise Exception("Invalid MESH_GROUP_REMOVE accepted") | |
725 | if "FAIL" not in wpas1.request("MESH_GROUP_REMOVE " + mesh1): | |
726 | raise Exception("Invalid MESH_GROUP_REMOVE accepted") | |
727 | ||
728 | # Must not allow MESH_GROUP_REMOVE on another radio interface | |
729 | if "FAIL" not in wpas0.request("MESH_GROUP_REMOVE " + mesh1): | |
730 | raise Exception("Invalid MESH_GROUP_REMOVE accepted") | |
731 | if "FAIL" not in wpas1.request("MESH_GROUP_REMOVE " + mesh0): | |
732 | raise Exception("Invalid MESH_GROUP_REMOVE accepted") | |
733 | ||
734 | wpas0.remove_ifname() | |
735 | wpas1.remove_ifname() | |
736 | ||
737 | if "OK" not in dev[0].request("MESH_GROUP_REMOVE " + mesh0): | |
738 | raise Exception("MESH_GROUP_REMOVE failed") | |
739 | if "OK" not in dev[1].request("MESH_GROUP_REMOVE " + mesh1): | |
740 | raise Exception("MESH_GROUP_REMOVE failed") | |
741 | ||
742 | if "FAIL" not in dev[0].request("MESH_GROUP_REMOVE " + mesh0): | |
743 | raise Exception("Invalid MESH_GROUP_REMOVE accepted") | |
744 | if "FAIL" not in dev[1].request("MESH_GROUP_REMOVE " + mesh1): | |
745 | raise Exception("Invalid MESH_GROUP_REMOVE accepted") | |
746 | ||
747 | logger.info("Make sure another dynamic group can be added") | |
748 | mesh0 = dev[0].request("MESH_INTERFACE_ADD ifname=mesh0") | |
749 | if "FAIL" in mesh0: | |
750 | raise Exception("MESH_INTERFACE_ADD failed") | |
751 | mesh1 = dev[1].request("MESH_INTERFACE_ADD") | |
752 | if "FAIL" in mesh1: | |
753 | raise Exception("MESH_INTERFACE_ADD failed") | |
754 | ||
755 | wpas0 = WpaSupplicant(ifname=mesh0) | |
756 | wpas1 = WpaSupplicant(ifname=mesh1) | |
757 | logger.info(mesh0 + " address " + wpas0.get_status_field("address")) | |
758 | logger.info(mesh1 + " address " + wpas1.get_status_field("address")) | |
759 | ||
760 | add_open_mesh_network(wpas0) | |
761 | add_open_mesh_network(wpas1) | |
762 | check_mesh_group_added(wpas0) | |
763 | check_mesh_group_added(wpas1) | |
764 | check_mesh_peer_connected(wpas0) | |
765 | check_mesh_peer_connected(wpas1) | |
766 | hwsim_utils.test_connectivity(wpas0, wpas1) | |
767 | finally: | |
768 | if mesh0: | |
769 | dev[0].request("MESH_GROUP_REMOVE " + mesh0) | |
770 | if mesh1: | |
771 | dev[1].request("MESH_GROUP_REMOVE " + mesh1) | |
9be2b811 | 772 | |
5edd0519 JM |
773 | def test_wpas_mesh_dynamic_interface_remove(dev): |
774 | """wpa_supplicant mesh with dynamic interface and removal""" | |
775 | wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') | |
776 | wpas.interface_add("wlan5") | |
777 | check_mesh_support(wpas) | |
778 | mesh5 = wpas.request("MESH_INTERFACE_ADD ifname=mesh5") | |
779 | if "FAIL" in mesh5: | |
780 | raise Exception("MESH_INTERFACE_ADD failed") | |
781 | ||
782 | wpas5 = WpaSupplicant(ifname=mesh5) | |
783 | logger.info(mesh5 + " address " + wpas5.get_status_field("address")) | |
784 | add_open_mesh_network(wpas5) | |
785 | add_open_mesh_network(dev[0]) | |
786 | check_mesh_group_added(wpas5) | |
787 | check_mesh_group_added(dev[0]) | |
788 | check_mesh_peer_connected(wpas5) | |
789 | check_mesh_peer_connected(dev[0]) | |
790 | hwsim_utils.test_connectivity(wpas5, dev[0]) | |
791 | ||
792 | # Remove the main interface while mesh interface is in use | |
793 | wpas.interface_remove("wlan5") | |
794 | ||
0b1b2044 | 795 | def test_wpas_mesh_max_peering(dev, apdev, params): |
9be2b811 | 796 | """Mesh max peering limit""" |
81e787b7 | 797 | check_mesh_support(dev[0]) |
9be2b811 JM |
798 | try: |
799 | dev[0].request("SET max_peer_links 1") | |
9be2b811 | 800 | |
ce8ca2f9 JM |
801 | # first, connect dev[0] and dev[1] |
802 | add_open_mesh_network(dev[0]) | |
803 | add_open_mesh_network(dev[1]) | |
804 | for i in range(2): | |
9be2b811 JM |
805 | ev = dev[i].wait_event(["MESH-PEER-CONNECTED"]) |
806 | if ev is None: | |
807 | raise Exception("dev%d did not connect with any peer" % i) | |
808 | ||
ce8ca2f9 JM |
809 | # add dev[2] which will try to connect with both dev[0] and dev[1], |
810 | # but can complete connection only with dev[1] | |
811 | add_open_mesh_network(dev[2]) | |
9be2b811 JM |
812 | for i in range(1, 3): |
813 | ev = dev[i].wait_event(["MESH-PEER-CONNECTED"]) | |
814 | if ev is None: | |
815 | raise Exception("dev%d did not connect the second peer" % i) | |
816 | ||
817 | ev = dev[0].wait_event(["MESH-PEER-CONNECTED"], timeout=1) | |
818 | if ev is not None: | |
819 | raise Exception("dev0 connection beyond max peering limit") | |
820 | ||
ce8ca2f9 JM |
821 | ev = dev[2].wait_event(["MESH-PEER-CONNECTED"], timeout=0.1) |
822 | if ev is not None: | |
823 | raise Exception("dev2 reported unexpected peering: " + ev) | |
824 | ||
9be2b811 JM |
825 | for i in range(3): |
826 | dev[i].mesh_group_remove() | |
827 | check_mesh_group_removed(dev[i]) | |
828 | finally: | |
829 | dev[0].request("SET max_peer_links 99") | |
de1d5049 | 830 | |
0b1b2044 JM |
831 | addr0 = dev[0].own_addr() |
832 | addr1 = dev[1].own_addr() | |
833 | addr2 = dev[2].own_addr() | |
834 | ||
835 | capfile = os.path.join(params['logdir'], "hwsim0.pcapng") | |
836 | filt = "wlan.fc.type_subtype == 8" | |
837 | out = run_tshark(capfile, filt, [ "wlan.sa", "wlan.mesh.config.cap" ]) | |
838 | pkts = out.splitlines() | |
839 | one = [ 0, 0, 0 ] | |
840 | zero = [ 0, 0, 0 ] | |
2cbaf0de | 841 | all_cap_one = True |
0b1b2044 JM |
842 | for pkt in pkts: |
843 | addr, cap = pkt.split('\t') | |
844 | cap = int(cap, 16) | |
2cbaf0de JM |
845 | if cap != 1: |
846 | all_cap_one = False | |
0b1b2044 JM |
847 | if addr == addr0: |
848 | idx = 0 | |
849 | elif addr == addr1: | |
850 | idx = 1 | |
851 | elif addr == addr2: | |
852 | idx = 2 | |
853 | else: | |
854 | continue | |
855 | if cap & 0x01: | |
856 | one[idx] += 1 | |
857 | else: | |
858 | zero[idx] += 1 | |
859 | logger.info("one: " + str(one)) | |
860 | logger.info("zero: " + str(zero)) | |
2cbaf0de JM |
861 | if all_cap_one: |
862 | # It looks like tshark parser was broken at some point for | |
863 | # wlan.mesh.config.cap which is now (tshark 2.6.3) pointing to incorrect | |
864 | # field (same as wlan.mesh.config.ps_protocol). This used to work with | |
865 | # tshark 2.2.6. | |
866 | # | |
867 | # For now, assume the capability field ends up being the last octet of | |
868 | # the frame. | |
869 | one = [ 0, 0, 0 ] | |
870 | zero = [ 0, 0, 0 ] | |
871 | addrs = [ addr0, addr1, addr2 ] | |
872 | for idx in range(3): | |
873 | addr = addrs[idx] | |
874 | out = run_tshark_json(capfile, filt + " && wlan.sa == " + addr) | |
875 | pkts = json.loads(out) | |
876 | for pkt in pkts: | |
877 | frame = pkt["_source"]["layers"]["frame_raw"][0] | |
878 | cap = int(frame[-2:], 16) | |
879 | if cap & 0x01: | |
880 | one[idx] += 1 | |
881 | else: | |
882 | zero[idx] += 1 | |
883 | logger.info("one: " + str(one)) | |
884 | logger.info("zero: " + str(zero)) | |
0b1b2044 JM |
885 | if zero[0] == 0: |
886 | raise Exception("Accepting Additional Mesh Peerings not cleared") | |
887 | if one[0] == 0: | |
888 | raise Exception("Accepting Additional Mesh Peerings was not set in the first Beacon frame") | |
889 | if zero[1] > 0 or zero[2] > 0 or one[1] == 0 or one[2] == 0: | |
890 | raise Exception("Unexpected value in Accepting Additional Mesh Peerings from other STAs") | |
891 | ||
de1d5049 JM |
892 | def test_wpas_mesh_open_5ghz(dev, apdev): |
893 | """wpa_supplicant open MESH network on 5 GHz band""" | |
894 | try: | |
895 | _test_wpas_mesh_open_5ghz(dev, apdev) | |
896 | finally: | |
3ca71202 JM |
897 | dev[0].request("MESH_GROUP_REMOVE " + dev[0].ifname) |
898 | dev[1].request("MESH_GROUP_REMOVE " + dev[1].ifname) | |
de1d5049 JM |
899 | subprocess.call(['iw', 'reg', 'set', '00']) |
900 | dev[0].flush_scan_cache() | |
901 | dev[1].flush_scan_cache() | |
902 | ||
903 | def _test_wpas_mesh_open_5ghz(dev, apdev): | |
904 | check_mesh_support(dev[0]) | |
905 | subprocess.call(['iw', 'reg', 'set', 'US']) | |
906 | for i in range(2): | |
907 | for j in range(5): | |
908 | ev = dev[i].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=5) | |
909 | if ev is None: | |
910 | raise Exception("No regdom change event") | |
911 | if "alpha2=US" in ev: | |
912 | break | |
913 | add_open_mesh_network(dev[i], freq="5180") | |
914 | ||
915 | # Check for mesh joined | |
916 | check_mesh_group_added(dev[0]) | |
917 | check_mesh_group_added(dev[1]) | |
918 | ||
919 | # Check for peer connected | |
920 | check_mesh_peer_connected(dev[0]) | |
921 | check_mesh_peer_connected(dev[1]) | |
922 | ||
923 | # Test connectivity 0->1 and 1->0 | |
924 | hwsim_utils.test_connectivity(dev[0], dev[1]) | |
f77d6d4b | 925 | |
3ca71202 JM |
926 | dev[0].mesh_group_remove() |
927 | dev[1].mesh_group_remove() | |
928 | check_mesh_group_removed(dev[0]) | |
929 | check_mesh_group_removed(dev[1]) | |
930 | dev[0].dump_monitor() | |
931 | dev[1].dump_monitor() | |
932 | ||
e3b38d6e JM |
933 | def test_wpas_mesh_open_5ghz_coex(dev, apdev): |
934 | """Mesh network on 5 GHz band and 20/40 coex change""" | |
935 | try: | |
936 | _test_wpas_mesh_open_5ghz_coex(dev, apdev) | |
937 | finally: | |
3ca71202 JM |
938 | dev[0].request("MESH_GROUP_REMOVE " + dev[0].ifname) |
939 | dev[1].request("MESH_GROUP_REMOVE " + dev[1].ifname) | |
e3b38d6e JM |
940 | set_world_reg(apdev0=apdev[0], dev0=dev[0]) |
941 | dev[0].flush_scan_cache() | |
942 | dev[1].flush_scan_cache() | |
943 | ||
944 | def _test_wpas_mesh_open_5ghz_coex(dev, apdev): | |
945 | check_mesh_support(dev[0]) | |
946 | subprocess.call(['iw', 'reg', 'set', 'US']) | |
947 | ||
948 | # Start a 20 MHz BSS on channel 40 that would be the secondary channel of | |
949 | # HT40+ mesh on channel 36. | |
950 | params = { "ssid": "test-ht40", | |
951 | "hw_mode": "a", | |
952 | "channel": "40", | |
953 | "country_code": "US" } | |
954 | hapd = hostapd.add_ap(apdev[0], params) | |
955 | bssid = hapd.own_addr() | |
956 | ||
957 | for i in range(2): | |
958 | for j in range(5): | |
959 | ev = dev[i].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=5) | |
960 | if ev is None: | |
961 | raise Exception("No regdom change event") | |
962 | if "alpha2=US" in ev: | |
963 | break | |
964 | dev[i].scan_for_bss(bssid, freq=5200) | |
965 | add_open_mesh_network(dev[i], freq="5180") | |
966 | ||
967 | check_mesh_group_added(dev[0]) | |
968 | check_mesh_group_added(dev[1]) | |
969 | check_mesh_peer_connected(dev[0]) | |
970 | check_mesh_peer_connected(dev[1]) | |
971 | ||
972 | freq = dev[0].get_status_field("freq") | |
973 | if freq != "5200": | |
974 | raise Exception("Unexpected STATUS freq=" + freq) | |
975 | sig = dev[0].request("SIGNAL_POLL").splitlines() | |
976 | if "FREQUENCY=5200" not in sig: | |
977 | raise Exception("Unexpected SIGNAL_POLL output: " + str(sig)) | |
978 | ||
979 | hapd.disable() | |
3ca71202 JM |
980 | dev[0].mesh_group_remove() |
981 | dev[1].mesh_group_remove() | |
982 | check_mesh_group_removed(dev[0]) | |
983 | check_mesh_group_removed(dev[1]) | |
984 | dev[0].dump_monitor() | |
985 | dev[1].dump_monitor() | |
e3b38d6e | 986 | |
e91877fb JM |
987 | def test_wpas_mesh_open_ht40(dev, apdev): |
988 | """Mesh and HT40 support difference""" | |
989 | try: | |
990 | _test_wpas_mesh_open_ht40(dev, apdev) | |
991 | finally: | |
992 | dev[0].request("MESH_GROUP_REMOVE " + dev[0].ifname) | |
993 | dev[1].request("MESH_GROUP_REMOVE " + dev[1].ifname) | |
994 | dev[2].request("MESH_GROUP_REMOVE " + dev[2].ifname) | |
995 | subprocess.call(['iw', 'reg', 'set', '00']) | |
996 | dev[0].flush_scan_cache() | |
997 | dev[1].flush_scan_cache() | |
998 | dev[2].flush_scan_cache() | |
999 | ||
1000 | def _test_wpas_mesh_open_ht40(dev, apdev): | |
1001 | check_mesh_support(dev[0]) | |
1002 | subprocess.call(['iw', 'reg', 'set', 'US']) | |
1003 | for i in range(3): | |
1004 | for j in range(5): | |
1005 | ev = dev[i].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=5) | |
1006 | if ev is None: | |
1007 | raise Exception("No regdom change event") | |
1008 | if "alpha2=US" in ev: | |
1009 | break | |
1010 | add_open_mesh_network(dev[i], freq="5180", disable_vht=True, | |
1011 | disable_ht40=(i == 2)) | |
1012 | ||
1013 | check_mesh_group_added(dev[0]) | |
1014 | check_mesh_group_added(dev[1]) | |
1015 | check_mesh_group_added(dev[2]) | |
1016 | ||
1017 | check_mesh_peer_connected(dev[0]) | |
1018 | check_mesh_peer_connected(dev[1]) | |
1019 | check_mesh_peer_connected(dev[2]) | |
1020 | ||
1021 | hwsim_utils.test_connectivity(dev[0], dev[1]) | |
1022 | hwsim_utils.test_connectivity(dev[0], dev[2]) | |
1023 | hwsim_utils.test_connectivity(dev[1], dev[2]) | |
1024 | ||
1025 | dev[0].mesh_group_remove() | |
1026 | dev[1].mesh_group_remove() | |
1027 | dev[2].mesh_group_remove() | |
1028 | check_mesh_group_removed(dev[0]) | |
1029 | check_mesh_group_removed(dev[1]) | |
1030 | check_mesh_group_removed(dev[2]) | |
1031 | dev[0].dump_monitor() | |
1032 | dev[1].dump_monitor() | |
1033 | dev[2].dump_monitor() | |
1034 | ||
a74a1e4e JM |
1035 | def test_wpas_mesh_open_vht_80p80(dev, apdev): |
1036 | """wpa_supplicant open MESH network on VHT 80+80 MHz channel""" | |
1037 | try: | |
1038 | _test_wpas_mesh_open_vht_80p80(dev, apdev) | |
1039 | finally: | |
3ca71202 JM |
1040 | dev[0].request("MESH_GROUP_REMOVE " + dev[0].ifname) |
1041 | dev[1].request("MESH_GROUP_REMOVE " + dev[1].ifname) | |
a74a1e4e JM |
1042 | subprocess.call(['iw', 'reg', 'set', '00']) |
1043 | dev[0].flush_scan_cache() | |
1044 | dev[1].flush_scan_cache() | |
1045 | ||
1046 | def _test_wpas_mesh_open_vht_80p80(dev, apdev): | |
1047 | check_mesh_support(dev[0]) | |
1048 | subprocess.call(['iw', 'reg', 'set', 'US']) | |
1049 | for i in range(2): | |
1050 | for j in range(5): | |
1051 | ev = dev[i].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=5) | |
1052 | if ev is None: | |
1053 | raise Exception("No regdom change event") | |
1054 | if "alpha2=US" in ev: | |
1055 | break | |
1056 | add_open_mesh_network(dev[i], freq="5180", chwidth=3) | |
1057 | ||
1058 | # Check for mesh joined | |
1059 | check_mesh_group_added(dev[0]) | |
1060 | check_mesh_group_added(dev[1]) | |
1061 | ||
1062 | # Check for peer connected | |
1063 | check_mesh_peer_connected(dev[0]) | |
1064 | check_mesh_peer_connected(dev[1]) | |
1065 | ||
1066 | # Test connectivity 0->1 and 1->0 | |
1067 | hwsim_utils.test_connectivity(dev[0], dev[1]) | |
1068 | ||
1069 | sig = dev[0].request("SIGNAL_POLL").splitlines() | |
1070 | if "WIDTH=80+80 MHz" not in sig: | |
1071 | raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig)) | |
1072 | if "CENTER_FRQ1=5210" not in sig: | |
1073 | raise Exception("Unexpected SIGNAL_POLL value(3): " + str(sig)) | |
1074 | if "CENTER_FRQ2=5775" not in sig: | |
1075 | raise Exception("Unexpected SIGNAL_POLL value(4): " + str(sig)) | |
1076 | ||
1077 | sig = dev[1].request("SIGNAL_POLL").splitlines() | |
1078 | if "WIDTH=80+80 MHz" not in sig: | |
1079 | raise Exception("Unexpected SIGNAL_POLL value(2b): " + str(sig)) | |
1080 | if "CENTER_FRQ1=5210" not in sig: | |
1081 | raise Exception("Unexpected SIGNAL_POLL value(3b): " + str(sig)) | |
1082 | if "CENTER_FRQ2=5775" not in sig: | |
1083 | raise Exception("Unexpected SIGNAL_POLL value(4b): " + str(sig)) | |
1084 | ||
3ca71202 JM |
1085 | dev[0].mesh_group_remove() |
1086 | dev[1].mesh_group_remove() | |
1087 | check_mesh_group_removed(dev[0]) | |
1088 | check_mesh_group_removed(dev[1]) | |
1089 | dev[0].dump_monitor() | |
1090 | dev[1].dump_monitor() | |
1091 | ||
56d62fc3 JM |
1092 | def test_mesh_open_vht_160(dev, apdev): |
1093 | """Open mesh network on VHT 160 MHz channel""" | |
1094 | try: | |
1095 | _test_mesh_open_vht_160(dev, apdev) | |
1096 | finally: | |
3ca71202 JM |
1097 | dev[0].request("MESH_GROUP_REMOVE " + dev[0].ifname) |
1098 | dev[1].request("MESH_GROUP_REMOVE " + dev[1].ifname) | |
56d62fc3 JM |
1099 | subprocess.call(['iw', 'reg', 'set', '00']) |
1100 | dev[0].flush_scan_cache() | |
1101 | dev[1].flush_scan_cache() | |
1102 | ||
1103 | def _test_mesh_open_vht_160(dev, apdev): | |
1104 | check_mesh_support(dev[0]) | |
1105 | subprocess.call(['iw', 'reg', 'set', 'ZA']) | |
1106 | for i in range(2): | |
1107 | for j in range(5): | |
1108 | ev = dev[i].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=5) | |
1109 | if ev is None: | |
1110 | raise Exception("No regdom change event") | |
1111 | if "alpha2=ZA" in ev: | |
1112 | break | |
1113 | ||
1114 | cmd = subprocess.Popen(["iw", "reg", "get"], stdout=subprocess.PIPE) | |
1115 | reg = cmd.stdout.read() | |
963041c3 JM |
1116 | found = False |
1117 | for entry in reg.splitlines(): | |
1118 | if "@ 160)" in entry and "DFS" not in entry: | |
1119 | found = True | |
1120 | break | |
1121 | if not found: | |
1122 | raise HwsimSkip("160 MHz channel without DFS not supported in regulatory information") | |
56d62fc3 JM |
1123 | |
1124 | add_open_mesh_network(dev[i], freq="5520", chwidth=2) | |
1125 | ||
1126 | # Check for mesh joined | |
1127 | check_mesh_group_added(dev[0]) | |
1128 | check_mesh_group_added(dev[1]) | |
1129 | ||
1130 | # Check for peer connected | |
1131 | check_mesh_peer_connected(dev[0]) | |
1132 | check_mesh_peer_connected(dev[1]) | |
3ca71202 JM |
1133 | dev[0].dump_monitor() |
1134 | dev[1].dump_monitor() | |
56d62fc3 JM |
1135 | |
1136 | # Test connectivity 0->1 and 1->0 | |
1137 | hwsim_utils.test_connectivity(dev[0], dev[1]) | |
1138 | ||
1139 | sig = dev[0].request("SIGNAL_POLL").splitlines() | |
1140 | if "WIDTH=160 MHz" not in sig: | |
1141 | raise Exception("Unexpected SIGNAL_POLL value(2): " + str(sig)) | |
1142 | if "FREQUENCY=5520" not in sig: | |
1143 | raise Exception("Unexpected SIGNAL_POLL value(3): " + str(sig)) | |
1144 | ||
1145 | sig = dev[1].request("SIGNAL_POLL").splitlines() | |
1146 | if "WIDTH=160 MHz" not in sig: | |
1147 | raise Exception("Unexpected SIGNAL_POLL value(2b): " + str(sig)) | |
1148 | if "FREQUENCY=5520" not in sig: | |
1149 | raise Exception("Unexpected SIGNAL_POLL value(3b): " + str(sig)) | |
1150 | ||
3ca71202 JM |
1151 | dev[0].mesh_group_remove() |
1152 | dev[1].mesh_group_remove() | |
1153 | check_mesh_group_removed(dev[0]) | |
1154 | check_mesh_group_removed(dev[1]) | |
1155 | dev[0].dump_monitor() | |
1156 | dev[1].dump_monitor() | |
1157 | ||
f77d6d4b JM |
1158 | def test_wpas_mesh_password_mismatch(dev, apdev): |
1159 | """Mesh network and one device with mismatching password""" | |
1160 | check_mesh_support(dev[0], secure=True) | |
1161 | dev[0].request("SET sae_groups ") | |
1162 | id = add_mesh_secure_net(dev[0]) | |
1163 | dev[0].mesh_group_add(id) | |
1164 | ||
1165 | dev[1].request("SET sae_groups ") | |
1166 | id = add_mesh_secure_net(dev[1]) | |
1167 | dev[1].mesh_group_add(id) | |
1168 | ||
1169 | dev[2].request("SET sae_groups ") | |
1170 | id = add_mesh_secure_net(dev[2]) | |
1171 | dev[2].set_network_quoted(id, "psk", "wrong password") | |
1172 | dev[2].mesh_group_add(id) | |
1173 | ||
1174 | # The two peers with matching password need to be able to connect | |
1175 | check_mesh_group_added(dev[0]) | |
1176 | check_mesh_group_added(dev[1]) | |
1177 | check_mesh_peer_connected(dev[0]) | |
1178 | check_mesh_peer_connected(dev[1]) | |
1179 | ||
1180 | ev = dev[2].wait_event(["MESH-SAE-AUTH-FAILURE"], timeout=20) | |
1181 | if ev is None: | |
1182 | raise Exception("dev2 did not report auth failure (1)") | |
1183 | ev = dev[2].wait_event(["MESH-SAE-AUTH-FAILURE"], timeout=20) | |
1184 | if ev is None: | |
1185 | raise Exception("dev2 did not report auth failure (2)") | |
d283f7ae | 1186 | dev[2].dump_monitor() |
f77d6d4b | 1187 | |
792eafa0 | 1188 | count = 0 |
d283f7ae | 1189 | ev = dev[0].wait_event(["MESH-SAE-AUTH-FAILURE"], timeout=5) |
f77d6d4b | 1190 | if ev is None: |
792eafa0 JM |
1191 | logger.info("dev0 did not report auth failure") |
1192 | else: | |
1193 | if "addr=" + dev[2].own_addr() not in ev: | |
1194 | raise Exception("Unexpected peer address in dev0 event: " + ev) | |
1195 | count += 1 | |
d283f7ae | 1196 | dev[0].dump_monitor() |
f77d6d4b | 1197 | |
d283f7ae | 1198 | ev = dev[1].wait_event(["MESH-SAE-AUTH-FAILURE"], timeout=5) |
f77d6d4b | 1199 | if ev is None: |
792eafa0 JM |
1200 | logger.info("dev1 did not report auth failure") |
1201 | else: | |
1202 | if "addr=" + dev[2].own_addr() not in ev: | |
1203 | raise Exception("Unexpected peer address in dev1 event: " + ev) | |
1204 | count += 1 | |
d283f7ae | 1205 | dev[1].dump_monitor() |
f77d6d4b JM |
1206 | |
1207 | hwsim_utils.test_connectivity(dev[0], dev[1]) | |
1208 | ||
1209 | for i in range(2): | |
1210 | try: | |
1211 | hwsim_utils.test_connectivity(dev[i], dev[2], timeout=1) | |
1212 | raise Exception("Data connectivity test passed unexpectedly") | |
1213 | except Exception, e: | |
1214 | if "data delivery failed" not in str(e): | |
1215 | raise | |
1216 | ||
792eafa0 JM |
1217 | if count == 0: |
1218 | raise Exception("Neither dev0 nor dev1 reported auth failure") | |
1219 | ||
f77d6d4b JM |
1220 | def test_wpas_mesh_password_mismatch_retry(dev, apdev, params): |
1221 | """Mesh password mismatch and retry [long]""" | |
1222 | if not params['long']: | |
1223 | raise HwsimSkip("Skip test case with long duration due to --long not specified") | |
1224 | check_mesh_support(dev[0], secure=True) | |
1225 | dev[0].request("SET sae_groups ") | |
1226 | id = add_mesh_secure_net(dev[0]) | |
1227 | dev[0].mesh_group_add(id) | |
1228 | ||
1229 | dev[1].request("SET sae_groups ") | |
1230 | id = add_mesh_secure_net(dev[1]) | |
1231 | dev[1].set_network_quoted(id, "psk", "wrong password") | |
1232 | dev[1].mesh_group_add(id) | |
1233 | ||
1234 | # Check for mesh joined | |
1235 | check_mesh_group_added(dev[0]) | |
1236 | check_mesh_group_added(dev[1]) | |
1237 | ||
1238 | for i in range(4): | |
1239 | ev = dev[0].wait_event(["MESH-SAE-AUTH-FAILURE"], timeout=20) | |
1240 | if ev is None: | |
1241 | raise Exception("dev0 did not report auth failure (%d)" % i) | |
1242 | ev = dev[1].wait_event(["MESH-SAE-AUTH-FAILURE"], timeout=20) | |
1243 | if ev is None: | |
1244 | raise Exception("dev1 did not report auth failure (%d)" % i) | |
1245 | ||
1246 | ev = dev[0].wait_event(["MESH-SAE-AUTH-BLOCKED"], timeout=10) | |
1247 | if ev is None: | |
1248 | raise Exception("dev0 did not report auth blocked") | |
1249 | ev = dev[1].wait_event(["MESH-SAE-AUTH-BLOCKED"], timeout=10) | |
1250 | if ev is None: | |
1251 | raise Exception("dev1 did not report auth blocked") | |
2fca1f67 JM |
1252 | |
1253 | def test_mesh_wpa_auth_init_oom(dev, apdev): | |
1254 | """Secure mesh network setup failing due to wpa_init() OOM""" | |
1255 | check_mesh_support(dev[0], secure=True) | |
1256 | dev[0].request("SET sae_groups ") | |
1257 | with alloc_fail(dev[0], 1, "wpa_init"): | |
1258 | id = add_mesh_secure_net(dev[0]) | |
1259 | dev[0].mesh_group_add(id) | |
1260 | ev = dev[0].wait_event(["MESH-GROUP-STARTED"], timeout=0.2) | |
1261 | if ev is not None: | |
1262 | raise Exception("Unexpected mesh group start during OOM") | |
fe28ed3f | 1263 | |
58284168 JM |
1264 | def test_mesh_wpa_init_fail(dev, apdev): |
1265 | """Secure mesh network setup local failure""" | |
1266 | check_mesh_support(dev[0], secure=True) | |
1267 | dev[0].request("SET sae_groups ") | |
1268 | ||
1269 | with fail_test(dev[0], 1, "os_get_random;=__mesh_rsn_auth_init"): | |
1270 | id = add_mesh_secure_net(dev[0]) | |
1271 | dev[0].mesh_group_add(id) | |
1272 | wait_fail_trigger(dev[0], "GET_FAIL") | |
1273 | ||
98628b7f | 1274 | dev[0].dump_monitor() |
58284168 JM |
1275 | with alloc_fail(dev[0], 1, "mesh_rsn_auth_init"): |
1276 | id = add_mesh_secure_net(dev[0]) | |
1277 | dev[0].mesh_group_add(id) | |
1278 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") | |
1279 | ||
98628b7f JM |
1280 | dev[0].dump_monitor() |
1281 | with fail_test(dev[0], 1, "os_get_random;mesh_rsn_init_ampe_sta"): | |
1282 | id = add_mesh_secure_net(dev[0]) | |
1283 | dev[0].mesh_group_add(id) | |
1284 | dev[1].request("SET sae_groups ") | |
1285 | id = add_mesh_secure_net(dev[1]) | |
1286 | dev[1].mesh_group_add(id) | |
1287 | wait_fail_trigger(dev[0], "GET_FAIL") | |
1288 | ||
fe28ed3f JM |
1289 | def test_wpas_mesh_reconnect(dev, apdev): |
1290 | """Secure mesh network plink counting during reconnection""" | |
1291 | check_mesh_support(dev[0]) | |
1292 | try: | |
1293 | _test_wpas_mesh_reconnect(dev) | |
1294 | finally: | |
1295 | dev[0].request("SET max_peer_links 99") | |
1296 | ||
1297 | def _test_wpas_mesh_reconnect(dev): | |
1298 | dev[0].request("SET max_peer_links 2") | |
1299 | dev[0].request("SET sae_groups ") | |
1300 | id = add_mesh_secure_net(dev[0]) | |
1301 | dev[0].set_network(id, "beacon_int", "100") | |
1302 | dev[0].mesh_group_add(id) | |
1303 | dev[1].request("SET sae_groups ") | |
1304 | id = add_mesh_secure_net(dev[1]) | |
1305 | dev[1].mesh_group_add(id) | |
1306 | check_mesh_group_added(dev[0]) | |
1307 | check_mesh_group_added(dev[1]) | |
1308 | check_mesh_peer_connected(dev[0]) | |
1309 | check_mesh_peer_connected(dev[1]) | |
1310 | ||
1311 | for i in range(3): | |
1312 | # Drop incoming management frames to avoid handling link close | |
1313 | dev[0].request("SET ext_mgmt_frame_handling 1") | |
1314 | dev[1].mesh_group_remove() | |
1315 | check_mesh_group_removed(dev[1]) | |
1316 | dev[1].request("FLUSH") | |
1317 | dev[0].request("SET ext_mgmt_frame_handling 0") | |
1318 | id = add_mesh_secure_net(dev[1]) | |
1319 | dev[1].mesh_group_add(id) | |
1320 | check_mesh_group_added(dev[1]) | |
1321 | check_mesh_peer_connected(dev[1]) | |
1322 | dev[0].dump_monitor() | |
1323 | dev[1].dump_monitor() | |
fa7f9570 BC |
1324 | |
1325 | def test_wpas_mesh_gate_forwarding(dev, apdev, p): | |
1326 | """Mesh forwards traffic to unknown sta to mesh gates""" | |
1327 | addr0 = dev[0].own_addr() | |
1328 | addr1 = dev[1].own_addr() | |
1329 | addr2 = dev[2].own_addr() | |
1330 | external_sta = '02:11:22:33:44:55' | |
1331 | ||
1332 | # start 3 node connected mesh | |
1333 | check_mesh_support(dev[0]) | |
1334 | for i in range(3): | |
1335 | add_open_mesh_network(dev[i]) | |
1336 | check_mesh_group_added(dev[i]) | |
1337 | for i in range(3): | |
1338 | check_mesh_peer_connected(dev[i]) | |
1339 | ||
1340 | hwsim_utils.test_connectivity(dev[0], dev[1]) | |
1341 | hwsim_utils.test_connectivity(dev[1], dev[2]) | |
1342 | hwsim_utils.test_connectivity(dev[0], dev[2]) | |
1343 | ||
1344 | # dev0 and dev1 are mesh gates | |
1345 | subprocess.call(['iw', 'dev', dev[0].ifname, 'set', 'mesh_param', | |
1346 | 'mesh_gate_announcements=1']) | |
1347 | subprocess.call(['iw', 'dev', dev[1].ifname, 'set', 'mesh_param', | |
1348 | 'mesh_gate_announcements=1']) | |
1349 | ||
1350 | # wait for gate announcement frames | |
1351 | time.sleep(1) | |
1352 | ||
1353 | # data frame from dev2 -> external sta should be sent to both gates | |
1354 | dev[2].request("DATA_TEST_CONFIG 1") | |
1355 | dev[2].request("DATA_TEST_TX {} {} 0".format(external_sta, addr2)) | |
1356 | dev[2].request("DATA_TEST_CONFIG 0") | |
1357 | ||
1358 | capfile = os.path.join(p['logdir'], "hwsim0.pcapng") | |
1359 | filt = "wlan.sa==%s && wlan_mgt.fixed.mesh_addr5==%s" % (addr2, | |
1360 | external_sta) | |
1361 | for i in range(15): | |
1362 | da = run_tshark(capfile, filt, [ "wlan.da" ]) | |
1363 | if addr0 in da and addr1 in da: | |
1364 | logger.debug("Frames seen in tshark iteration %d" % i) | |
1365 | break | |
1366 | time.sleep(0.3) | |
1367 | ||
1368 | if addr0 not in da: | |
1369 | raise Exception("Frame to gate %s not observed" % addr0) | |
1370 | if addr1 not in da: | |
1371 | raise Exception("Frame to gate %s not observed" % addr1) | |
5a34d359 JM |
1372 | |
1373 | def test_wpas_mesh_pmksa_caching(dev, apdev): | |
1374 | """Secure mesh network and PMKSA caching""" | |
1375 | check_mesh_support(dev[0], secure=True) | |
1376 | dev[0].request("SET sae_groups ") | |
1377 | id = add_mesh_secure_net(dev[0]) | |
1378 | dev[0].mesh_group_add(id) | |
1379 | ||
1380 | dev[1].request("SET sae_groups ") | |
1381 | id = add_mesh_secure_net(dev[1]) | |
1382 | dev[1].mesh_group_add(id) | |
1383 | ||
1384 | # Check for mesh joined | |
1385 | check_mesh_group_added(dev[0]) | |
1386 | check_mesh_group_added(dev[1]) | |
1387 | ||
1388 | # Check for peer connected | |
1389 | check_mesh_peer_connected(dev[0]) | |
1390 | check_mesh_peer_connected(dev[1]) | |
1391 | ||
1392 | addr0 = dev[0].own_addr() | |
1393 | addr1 = dev[1].own_addr() | |
1394 | pmksa0 = dev[0].get_pmksa(addr1) | |
1395 | pmksa1 = dev[1].get_pmksa(addr0) | |
1396 | if pmksa0 is None or pmksa1 is None: | |
1397 | raise Exception("No PMKSA cache entry created") | |
1398 | if pmksa0['pmkid'] != pmksa1['pmkid']: | |
1399 | raise Exception("PMKID mismatch in PMKSA cache entries") | |
1400 | ||
1401 | if "OK" not in dev[0].request("MESH_PEER_REMOVE " + addr1): | |
1402 | raise Exception("Failed to remove peer") | |
1403 | pmksa0b = dev[0].get_pmksa(addr1) | |
1404 | if pmksa0b is None: | |
1405 | raise Exception("PMKSA cache entry not maintained") | |
1406 | time.sleep(0.1) | |
1407 | ||
1408 | if "FAIL" not in dev[0].request("MESH_PEER_ADD " + addr1): | |
1409 | raise Exception("MESH_PEER_ADD unexpectedly succeeded in no_auto_peer=0 case") | |
1410 | ||
1411 | def test_wpas_mesh_pmksa_caching2(dev, apdev): | |
1412 | """Secure mesh network and PMKSA caching with no_auto_peer=1""" | |
1413 | check_mesh_support(dev[0], secure=True) | |
1414 | addr0 = dev[0].own_addr() | |
1415 | addr1 = dev[1].own_addr() | |
1416 | dev[0].request("SET sae_groups ") | |
1417 | id = add_mesh_secure_net(dev[0]) | |
1418 | dev[0].set_network(id, "no_auto_peer", "1") | |
1419 | dev[0].mesh_group_add(id) | |
1420 | ||
1421 | dev[1].request("SET sae_groups ") | |
1422 | id = add_mesh_secure_net(dev[1]) | |
1423 | dev[1].set_network(id, "no_auto_peer", "1") | |
1424 | dev[1].mesh_group_add(id) | |
1425 | ||
1426 | # Check for mesh joined | |
1427 | check_mesh_group_added(dev[0]) | |
1428 | check_mesh_group_added(dev[1]) | |
1429 | ||
1430 | # Check for peer connected | |
1431 | ev = dev[0].wait_event(["will not initiate new peer link"], timeout=10) | |
1432 | if ev is None: | |
1433 | raise Exception("Missing no-initiate message") | |
1434 | if "OK" not in dev[0].request("MESH_PEER_ADD " + addr1): | |
1435 | raise Exception("MESH_PEER_ADD failed") | |
1436 | check_mesh_peer_connected(dev[0]) | |
1437 | check_mesh_peer_connected(dev[1]) | |
1438 | ||
1439 | pmksa0 = dev[0].get_pmksa(addr1) | |
1440 | pmksa1 = dev[1].get_pmksa(addr0) | |
1441 | if pmksa0 is None or pmksa1 is None: | |
1442 | raise Exception("No PMKSA cache entry created") | |
1443 | if pmksa0['pmkid'] != pmksa1['pmkid']: | |
1444 | raise Exception("PMKID mismatch in PMKSA cache entries") | |
1445 | ||
1446 | if "OK" not in dev[0].request("MESH_PEER_REMOVE " + addr1): | |
1447 | raise Exception("Failed to remove peer") | |
1448 | pmksa0b = dev[0].get_pmksa(addr1) | |
1449 | if pmksa0b is None: | |
1450 | raise Exception("PMKSA cache entry not maintained") | |
1451 | ||
1452 | ev = dev[0].wait_event(["will not initiate new peer link"], timeout=10) | |
1453 | if ev is None: | |
1454 | raise Exception("Missing no-initiate message (2)") | |
1455 | if "OK" not in dev[0].request("MESH_PEER_ADD " + addr1): | |
1456 | raise Exception("MESH_PEER_ADD failed (2)") | |
1457 | check_mesh_peer_connected(dev[0]) | |
1458 | check_mesh_peer_connected(dev[1]) | |
1459 | ||
1460 | pmksa0c = dev[0].get_pmksa(addr1) | |
1461 | pmksa1c = dev[1].get_pmksa(addr0) | |
1462 | if pmksa0c is None or pmksa1c is None: | |
1463 | raise Exception("No PMKSA cache entry created (2)") | |
1464 | if pmksa0c['pmkid'] != pmksa1c['pmkid']: | |
1465 | raise Exception("PMKID mismatch in PMKSA cache entries") | |
1466 | if pmksa0['pmkid'] != pmksa0c['pmkid']: | |
1467 | raise Exception("PMKID changed") | |
1468 | ||
1469 | hwsim_utils.test_connectivity(dev[0], dev[1]) | |
1470 | ||
1471 | def test_wpas_mesh_pmksa_caching_no_match(dev, apdev): | |
1472 | """Secure mesh network and PMKSA caching with no PMKID match""" | |
1473 | check_mesh_support(dev[0], secure=True) | |
1474 | addr0 = dev[0].own_addr() | |
1475 | addr1 = dev[1].own_addr() | |
1476 | dev[0].request("SET sae_groups ") | |
1477 | id = add_mesh_secure_net(dev[0]) | |
1478 | dev[0].set_network(id, "no_auto_peer", "1") | |
1479 | dev[0].mesh_group_add(id) | |
1480 | ||
1481 | dev[1].request("SET sae_groups ") | |
1482 | id = add_mesh_secure_net(dev[1]) | |
1483 | dev[1].set_network(id, "no_auto_peer", "1") | |
1484 | dev[1].mesh_group_add(id) | |
1485 | ||
1486 | # Check for mesh joined | |
1487 | check_mesh_group_added(dev[0]) | |
1488 | check_mesh_group_added(dev[1]) | |
1489 | ||
1490 | # Check for peer connected | |
1491 | ev = dev[0].wait_event(["will not initiate new peer link"], timeout=10) | |
1492 | if ev is None: | |
1493 | raise Exception("Missing no-initiate message") | |
1494 | if "OK" not in dev[0].request("MESH_PEER_ADD " + addr1): | |
1495 | raise Exception("MESH_PEER_ADD failed") | |
1496 | check_mesh_peer_connected(dev[0]) | |
1497 | check_mesh_peer_connected(dev[1]) | |
1498 | ||
1499 | pmksa0 = dev[0].get_pmksa(addr1) | |
1500 | pmksa1 = dev[1].get_pmksa(addr0) | |
1501 | if pmksa0 is None or pmksa1 is None: | |
1502 | raise Exception("No PMKSA cache entry created") | |
1503 | if pmksa0['pmkid'] != pmksa1['pmkid']: | |
1504 | raise Exception("PMKID mismatch in PMKSA cache entries") | |
1505 | ||
1506 | if "OK" not in dev[0].request("MESH_PEER_REMOVE " + addr1): | |
1507 | raise Exception("Failed to remove peer") | |
1508 | ||
1509 | if "OK" not in dev[1].request("PMKSA_FLUSH"): | |
1510 | raise Exception("Failed to flush PMKSA cache") | |
1511 | ||
1512 | ev = dev[0].wait_event(["will not initiate new peer link"], timeout=10) | |
1513 | if ev is None: | |
1514 | raise Exception("Missing no-initiate message (2)") | |
1515 | if "OK" not in dev[0].request("MESH_PEER_ADD " + addr1): | |
1516 | raise Exception("MESH_PEER_ADD failed (2)") | |
1517 | check_mesh_peer_connected(dev[0]) | |
1518 | check_mesh_peer_connected(dev[1]) | |
1519 | ||
1520 | pmksa0c = dev[0].get_pmksa(addr1) | |
1521 | pmksa1c = dev[1].get_pmksa(addr0) | |
1522 | if pmksa0c is None or pmksa1c is None: | |
1523 | raise Exception("No PMKSA cache entry created (2)") | |
1524 | if pmksa0c['pmkid'] != pmksa1c['pmkid']: | |
1525 | raise Exception("PMKID mismatch in PMKSA cache entries") | |
1526 | if pmksa0['pmkid'] == pmksa0c['pmkid']: | |
1527 | raise Exception("PMKID did not change") | |
1528 | ||
1529 | hwsim_utils.test_connectivity(dev[0], dev[1]) | |
b15acadc | 1530 | |
044d739b JM |
1531 | def test_mesh_pmksa_caching_oom(dev, apdev): |
1532 | """Secure mesh network and PMKSA caching failing due to OOM""" | |
1533 | check_mesh_support(dev[0], secure=True) | |
1534 | addr0 = dev[0].own_addr() | |
1535 | addr1 = dev[1].own_addr() | |
1536 | dev[0].request("SET sae_groups ") | |
1537 | id = add_mesh_secure_net(dev[0]) | |
1538 | dev[0].set_network(id, "no_auto_peer", "1") | |
1539 | dev[0].mesh_group_add(id) | |
1540 | ||
1541 | dev[1].request("SET sae_groups ") | |
1542 | id = add_mesh_secure_net(dev[1]) | |
1543 | dev[1].set_network(id, "no_auto_peer", "1") | |
1544 | dev[1].mesh_group_add(id) | |
1545 | ||
1546 | # Check for mesh joined | |
1547 | check_mesh_group_added(dev[0]) | |
1548 | check_mesh_group_added(dev[1]) | |
1549 | ||
1550 | # Check for peer connected | |
1551 | ev = dev[0].wait_event(["will not initiate new peer link"], timeout=10) | |
1552 | if ev is None: | |
1553 | raise Exception("Missing no-initiate message") | |
1554 | if "OK" not in dev[0].request("MESH_PEER_ADD " + addr1): | |
1555 | raise Exception("MESH_PEER_ADD failed") | |
1556 | check_mesh_peer_connected(dev[0]) | |
1557 | check_mesh_peer_connected(dev[1]) | |
1558 | ||
1559 | if "OK" not in dev[0].request("MESH_PEER_REMOVE " + addr1): | |
1560 | raise Exception("Failed to remove peer") | |
1561 | pmksa0b = dev[0].get_pmksa(addr1) | |
1562 | if pmksa0b is None: | |
1563 | raise Exception("PMKSA cache entry not maintained") | |
1564 | ||
1565 | ev = dev[0].wait_event(["will not initiate new peer link"], timeout=10) | |
1566 | if ev is None: | |
1567 | raise Exception("Missing no-initiate message (2)") | |
1568 | ||
1569 | with alloc_fail(dev[0], 1, "wpa_auth_sta_init;mesh_rsn_auth_sae_sta"): | |
1570 | if "OK" not in dev[0].request("MESH_PEER_ADD " + addr1): | |
1571 | raise Exception("MESH_PEER_ADD failed (2)") | |
1572 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") | |
1573 | ||
63633963 JM |
1574 | def test_wpas_mesh_pmksa_caching_ext(dev, apdev): |
1575 | """Secure mesh network and PMKSA caching and external storage""" | |
1576 | check_mesh_support(dev[0], secure=True) | |
1577 | dev[0].request("SET sae_groups ") | |
1578 | id = add_mesh_secure_net(dev[0]) | |
1579 | dev[0].mesh_group_add(id) | |
1580 | ||
1581 | dev[1].request("SET sae_groups ") | |
1582 | id = add_mesh_secure_net(dev[1]) | |
1583 | dev[1].mesh_group_add(id) | |
1584 | ||
1585 | # Check for mesh joined | |
1586 | check_mesh_group_added(dev[0]) | |
1587 | check_mesh_group_added(dev[1]) | |
1588 | ||
1589 | # Check for peer connected | |
1590 | check_mesh_peer_connected(dev[0]) | |
1591 | check_mesh_peer_connected(dev[1]) | |
1592 | dev[0].dump_monitor() | |
1593 | dev[1].dump_monitor() | |
1594 | ||
1595 | addr0 = dev[0].own_addr() | |
1596 | addr1 = dev[1].own_addr() | |
1597 | pmksa0 = dev[0].get_pmksa(addr1) | |
1598 | pmksa1 = dev[1].get_pmksa(addr0) | |
1599 | if pmksa0 is None or pmksa1 is None: | |
1600 | raise Exception("No PMKSA cache entry created") | |
1601 | if pmksa0['pmkid'] != pmksa1['pmkid']: | |
1602 | raise Exception("PMKID mismatch in PMKSA cache entries") | |
1603 | ||
1604 | res1 = dev[1].request("MESH_PMKSA_GET any") | |
1605 | res2 = dev[1].request("MESH_PMKSA_GET " + addr0) | |
1606 | logger.info("MESH_PMKSA_GET: " + res1) | |
1607 | if "UNKNOWN COMMAND" in res1: | |
1608 | raise HwsimSkip("MESH_PMKSA_GET not supported in the build") | |
1609 | logger.info("MESH_PMKSA_GET: " + res2) | |
1610 | if pmksa0['pmkid'] not in res1: | |
1611 | raise Exception("PMKID not included in PMKSA entry") | |
1612 | if res1 != res2: | |
1613 | raise Exception("Unexpected difference in MESH_PMKSA_GET output") | |
1614 | ||
1615 | dev[1].mesh_group_remove() | |
1616 | check_mesh_group_removed(dev[1]) | |
1617 | dev[0].dump_monitor() | |
1618 | dev[1].dump_monitor() | |
1619 | res = dev[1].get_pmksa(addr0) | |
1620 | if res is not None: | |
1621 | raise Exception("Unexpected PMKSA cache entry remaining") | |
1622 | ||
1623 | if "OK" not in dev[1].request("MESH_PMKSA_ADD " + res2): | |
1624 | raise Exception("MESH_PMKSA_ADD failed") | |
1625 | dev[1].mesh_group_add(id) | |
1626 | check_mesh_group_added(dev[1]) | |
1627 | check_mesh_peer_connected(dev[1]) | |
1628 | dev[0].dump_monitor() | |
1629 | dev[1].dump_monitor() | |
1630 | pmksa1b = dev[1].get_pmksa(addr0) | |
1631 | if pmksa1b is None: | |
1632 | raise Exception("No PMKSA cache entry created after external storage restore") | |
1633 | if pmksa1['pmkid'] != pmksa1b['pmkid']: | |
1634 | raise Exception("PMKID mismatch in PMKSA cache entries after external storage restore") | |
1635 | ||
1636 | hwsim_utils.test_connectivity(dev[0], dev[1]) | |
1637 | ||
1638 | res = dev[1].request("MESH_PMKSA_GET foo") | |
1639 | if "FAIL" not in res: | |
1640 | raise Exception("Invalid MESH_PMKSA_GET accepted") | |
1641 | ||
1642 | dev[1].mesh_group_remove() | |
1643 | check_mesh_group_removed(dev[1]) | |
1644 | dev[0].dump_monitor() | |
1645 | dev[1].dump_monitor() | |
1646 | dev[1].request("REMOVE_NETWORK all") | |
1647 | res = dev[1].request("MESH_PMKSA_GET any") | |
1648 | if "FAIL" not in res: | |
1649 | raise Exception("MESH_PMKSA_GET accepted when not in mesh") | |
1650 | ||
1651 | tests = [ "foo", | |
1652 | "02:02:02:02:02:02", | |
1653 | "02:02:02:02:02:02 q", | |
1654 | "02:02:02:02:02:02 c3d51a7ccfca0c6d5287291a7169d79b", | |
1655 | "02:02:02:02:02:02 c3d51a7ccfca0c6d5287291a7169d79b q", | |
1656 | "02:02:02:02:02:02 c3d51a7ccfca0c6d5287291a7169d79b 1bed4fa22ece7997ca1bdc8b829019fe63acac91cba3405522c24c91f7cfb49f", | |
1657 | "02:02:02:02:02:02 c3d51a7ccfca0c6d5287291a7169d79b 1bed4fa22ece7997ca1bdc8b829019fe63acac91cba3405522c24c91f7cfb49f q" ] | |
1658 | for t in tests: | |
1659 | if "FAIL" not in dev[1].request("MESH_PMKSA_ADD " + t): | |
1660 | raise Exception("Invalid MESH_PMKSA_ADD accepted") | |
1661 | ||
b15acadc JM |
1662 | def test_mesh_oom(dev, apdev): |
1663 | """Mesh network setup failing due to OOM""" | |
1664 | check_mesh_support(dev[0], secure=True) | |
1665 | dev[0].request("SET sae_groups ") | |
1666 | ||
1667 | with alloc_fail(dev[0], 1, "mesh_config_create"): | |
1668 | add_open_mesh_network(dev[0]) | |
1669 | ev = dev[0].wait_event(["Failed to init mesh"]) | |
1670 | if ev is None: | |
1671 | raise Exception("Init failure not reported") | |
1672 | ||
13f69792 | 1673 | with alloc_fail(dev[0], 2, "=wpa_supplicant_mesh_init"): |
ec87430b JM |
1674 | add_open_mesh_network(dev[0], basic_rates="60 120 240") |
1675 | ev = dev[0].wait_event(["Failed to init mesh"]) | |
1676 | if ev is None: | |
1677 | raise Exception("Init failure not reported") | |
1678 | ||
1679 | for i in range(1, 66): | |
1680 | dev[0].dump_monitor() | |
1681 | logger.info("Test instance %d" % i) | |
1682 | try: | |
1683 | with alloc_fail(dev[0], i, "wpa_supplicant_mesh_init"): | |
1684 | add_open_mesh_network(dev[0]) | |
1685 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") | |
1686 | ev = dev[0].wait_event(["Failed to init mesh", | |
1687 | "MESH-GROUP-STARTED"]) | |
1688 | if ev is None: | |
1689 | raise Exception("Init failure not reported") | |
1690 | except Exception, e: | |
1691 | if i < 15: | |
1692 | raise | |
1693 | logger.info("Ignore no-oom for i=%d" % i) | |
1694 | ||
13f69792 | 1695 | with alloc_fail(dev[0], 3, "=wpa_supplicant_mesh_init"): |
ec87430b JM |
1696 | id = add_mesh_secure_net(dev[0]) |
1697 | dev[0].mesh_group_add(id) | |
1698 | ev = dev[0].wait_event(["Failed to init mesh"]) | |
1699 | if ev is None: | |
1700 | raise Exception("Init failure not reported") | |
aa59370b JM |
1701 | |
1702 | def test_mesh_add_interface_oom(dev): | |
1703 | """wpa_supplicant mesh with dynamic interface addition failing""" | |
1704 | check_mesh_support(dev[0]) | |
1705 | for i in range(1, 3): | |
1706 | mesh = None | |
1707 | try: | |
1708 | with alloc_fail(dev[0], i, "wpas_mesh_add_interface"): | |
1709 | mesh = dev[0].request("MESH_INTERFACE_ADD").strip() | |
1710 | finally: | |
1711 | if mesh and mesh != "FAIL": | |
1712 | dev[0].request("MESH_GROUP_REMOVE " + mesh) | |
4d4cdc3b JM |
1713 | |
1714 | def test_mesh_scan_oom(dev): | |
1715 | """wpa_supplicant mesh scan results and OOM""" | |
1716 | check_mesh_support(dev[0]) | |
1717 | add_open_mesh_network(dev[0]) | |
1718 | check_mesh_group_added(dev[0]) | |
1719 | for i in range(5): | |
1720 | dev[1].scan(freq="2412") | |
1721 | res = dev[1].request("SCAN_RESULTS") | |
1722 | if "[MESH]" in res: | |
1723 | break | |
1724 | for r in res.splitlines(): | |
1725 | if "[MESH]" in r: | |
1726 | break | |
1727 | bssid = r.split('\t')[0] | |
1728 | ||
1729 | bss = dev[1].get_bss(bssid) | |
1730 | if bss is None: | |
1731 | raise Exception("Could not get BSS entry for mesh") | |
1732 | ||
1733 | for i in range(1, 3): | |
1734 | with alloc_fail(dev[1], i, "mesh_attr_text"): | |
1735 | bss = dev[1].get_bss(bssid) | |
51435515 | 1736 | if bss and "mesh_id" in bss: |
4d4cdc3b | 1737 | raise Exception("Unexpected BSS result during OOM") |
f0ee4535 | 1738 | |
699074d3 JM |
1739 | def test_mesh_drv_fail(dev, apdev): |
1740 | """Mesh network setup failing due to driver command failure""" | |
1741 | check_mesh_support(dev[0], secure=True) | |
1742 | dev[0].request("SET sae_groups ") | |
1743 | ||
1744 | with fail_test(dev[0], 1, "nl80211_join_mesh"): | |
1745 | add_open_mesh_network(dev[0]) | |
1746 | ev = dev[0].wait_event(["mesh join error"]) | |
1747 | if ev is None: | |
1748 | raise Exception("Join failure not reported") | |
1749 | ||
1750 | dev[0].dump_monitor() | |
1751 | with fail_test(dev[0], 1, "wpa_driver_nl80211_if_add"): | |
1752 | if "FAIL" not in dev[0].request("MESH_INTERFACE_ADD").strip(): | |
1753 | raise Exception("Interface added unexpectedly") | |
1754 | ||
1755 | dev[0].dump_monitor() | |
1756 | with fail_test(dev[0], 1, "wpa_driver_nl80211_init_mesh"): | |
1757 | add_open_mesh_network(dev[0]) | |
1758 | ev = dev[0].wait_event(["Could not join mesh"]) | |
1759 | if ev is None: | |
1760 | raise Exception("Join failure not reported") | |
1761 | ||
f0ee4535 JM |
1762 | def test_mesh_sae_groups_invalid(dev, apdev): |
1763 | """Mesh with invalid SAE group configuration""" | |
1764 | check_mesh_support(dev[0], secure=True) | |
1765 | ||
a680f4ef | 1766 | dev[0].request("SET sae_groups 26") |
f0ee4535 JM |
1767 | id = add_mesh_secure_net(dev[0]) |
1768 | dev[0].mesh_group_add(id) | |
1769 | ||
1770 | dev[1].request("SET sae_groups 123 122 121") | |
1771 | id = add_mesh_secure_net(dev[1]) | |
1772 | dev[1].mesh_group_add(id) | |
1773 | ||
1774 | check_mesh_group_added(dev[0]) | |
1775 | check_mesh_group_added(dev[1]) | |
1776 | ||
1777 | ev = dev[0].wait_event(["new peer notification"], timeout=10) | |
1778 | if ev is None: | |
1779 | raise Exception("dev[0] did not see peer") | |
1780 | ev = dev[1].wait_event(["new peer notification"], timeout=10) | |
1781 | if ev is None: | |
1782 | raise Exception("dev[1] did not see peer") | |
1783 | ||
1784 | ev = dev[0].wait_event(["MESH-PEER-CONNECTED"], timeout=0.1) | |
1785 | if ev is not None: | |
1786 | raise Exception("Unexpected connection(0)") | |
1787 | ||
1788 | ev = dev[1].wait_event(["MESH-PEER-CONNECTED"], timeout=0.01) | |
1789 | if ev is not None: | |
1790 | raise Exception("Unexpected connection(1)") | |
1791 | ||
a3bd5327 JM |
1792 | # Additional coverage in mesh_rsn_sae_group() with non-zero |
1793 | # wpa_s->mesh_rsn->sae_group_index. | |
1794 | dev[0].dump_monitor() | |
1795 | dev[1].dump_monitor() | |
1796 | id = add_mesh_secure_net(dev[2]) | |
1797 | dev[2].mesh_group_add(id) | |
1798 | check_mesh_group_added(dev[2]) | |
1799 | check_mesh_peer_connected(dev[0]) | |
1800 | check_mesh_peer_connected(dev[2]) | |
1801 | ev = dev[1].wait_event(["new peer notification"], timeout=10) | |
1802 | if ev is None: | |
1803 | raise Exception("dev[1] did not see peer(2)") | |
1804 | dev[0].dump_monitor() | |
1805 | dev[1].dump_monitor() | |
1806 | dev[2].dump_monitor() | |
1807 | ||
f0ee4535 JM |
1808 | dev[0].request("SET sae_groups ") |
1809 | dev[1].request("SET sae_groups ") | |
b0ec3d77 JM |
1810 | |
1811 | def test_mesh_sae_failure(dev, apdev): | |
1812 | """Mesh and local SAE failures""" | |
1813 | check_mesh_support(dev[0], secure=True) | |
1814 | ||
1815 | dev[0].request("SET sae_groups ") | |
1816 | dev[1].request("SET sae_groups ") | |
1817 | ||
1818 | funcs = [ (1, "=mesh_rsn_auth_sae_sta", True), | |
1819 | (1, "mesh_rsn_build_sae_commit;mesh_rsn_auth_sae_sta", False), | |
1820 | (1, "auth_sae_init_committed;mesh_rsn_auth_sae_sta", True), | |
1821 | (1, "=mesh_rsn_protect_frame", True), | |
1822 | (2, "=mesh_rsn_protect_frame", True), | |
1823 | (1, "aes_siv_encrypt;mesh_rsn_protect_frame", True), | |
1824 | (1, "=mesh_rsn_process_ampe", True), | |
1825 | (1, "aes_siv_decrypt;mesh_rsn_process_ampe", True) ] | |
1826 | for count, func, success in funcs: | |
1827 | id = add_mesh_secure_net(dev[0]) | |
1828 | dev[0].mesh_group_add(id) | |
1829 | ||
1830 | with alloc_fail(dev[1], count, func): | |
1831 | id = add_mesh_secure_net(dev[1]) | |
1832 | dev[1].mesh_group_add(id) | |
1833 | check_mesh_group_added(dev[0]) | |
1834 | check_mesh_group_added(dev[1]) | |
1835 | if success: | |
1836 | # retry is expected to work | |
1837 | check_mesh_peer_connected(dev[0]) | |
1838 | check_mesh_peer_connected(dev[1]) | |
1839 | else: | |
1840 | wait_fail_trigger(dev[1], "GET_ALLOC_FAIL") | |
1841 | dev[0].mesh_group_remove() | |
1842 | dev[1].mesh_group_remove() | |
1843 | check_mesh_group_removed(dev[0]) | |
1844 | check_mesh_group_removed(dev[1]) | |
a6447640 JM |
1845 | |
1846 | def test_mesh_failure(dev, apdev): | |
1847 | """Mesh and local failures""" | |
1848 | check_mesh_support(dev[0]) | |
1849 | ||
1850 | funcs = [ (1, "ap_sta_add;mesh_mpm_add_peer", True), | |
1851 | (1, "wpabuf_alloc;mesh_mpm_send_plink_action", True) ] | |
1852 | for count, func, success in funcs: | |
1853 | add_open_mesh_network(dev[0]) | |
1854 | ||
1855 | with alloc_fail(dev[1], count, func): | |
1856 | add_open_mesh_network(dev[1]) | |
1857 | check_mesh_group_added(dev[0]) | |
1858 | check_mesh_group_added(dev[1]) | |
1859 | if success: | |
1860 | # retry is expected to work | |
1861 | check_mesh_peer_connected(dev[0]) | |
1862 | check_mesh_peer_connected(dev[1]) | |
1863 | else: | |
1864 | wait_fail_trigger(dev[1], "GET_ALLOC_FAIL") | |
1865 | dev[0].mesh_group_remove() | |
1866 | dev[1].mesh_group_remove() | |
1867 | check_mesh_group_removed(dev[0]) | |
1868 | check_mesh_group_removed(dev[1]) | |
1869 | ||
1870 | funcs = [ (1, "mesh_mpm_init_link", True) ] | |
1871 | for count, func, success in funcs: | |
1872 | add_open_mesh_network(dev[0]) | |
1873 | ||
1874 | with fail_test(dev[1], count, func): | |
1875 | add_open_mesh_network(dev[1]) | |
1876 | check_mesh_group_added(dev[0]) | |
1877 | check_mesh_group_added(dev[1]) | |
1878 | if success: | |
1879 | # retry is expected to work | |
1880 | check_mesh_peer_connected(dev[0]) | |
1881 | check_mesh_peer_connected(dev[1]) | |
1882 | else: | |
1883 | wait_fail_trigger(dev[1], "GET_FAIL") | |
1884 | dev[0].mesh_group_remove() | |
1885 | dev[1].mesh_group_remove() | |
1886 | check_mesh_group_removed(dev[0]) | |
1887 | check_mesh_group_removed(dev[1]) | |
2cf6341e JM |
1888 | |
1889 | def test_mesh_invalid_frequency(dev, apdev): | |
1890 | """Mesh and invalid frequency configuration""" | |
1891 | check_mesh_support(dev[0]) | |
1892 | add_open_mesh_network(dev[0], freq=None) | |
1893 | ev = dev[0].wait_event(["MESH-GROUP-STARTED", | |
1894 | "Could not join mesh"]) | |
1895 | if ev is None or "Could not join mesh" not in ev: | |
1896 | raise Exception("Mesh join failure not reported") | |
1897 | dev[0].request("REMOVE_NETWORK all") | |
1898 | ||
1899 | add_open_mesh_network(dev[0], freq="2413") | |
1900 | ev = dev[0].wait_event(["MESH-GROUP-STARTED", | |
1901 | "Could not join mesh"]) | |
1902 | if ev is None or "Could not join mesh" not in ev: | |
1903 | raise Exception("Mesh join failure not reported") | |
521a98a8 JM |
1904 | |
1905 | def test_mesh_default_beacon_int(dev, apdev): | |
1906 | """Mesh and default beacon interval""" | |
1907 | check_mesh_support(dev[0]) | |
1908 | try: | |
1909 | dev[0].request("SET beacon_int 200") | |
1910 | add_open_mesh_network(dev[0]) | |
1911 | check_mesh_group_added(dev[0]) | |
1912 | finally: | |
1913 | dev[0].request("SET beacon_int 0") | |
e8739be8 JM |
1914 | |
1915 | def test_mesh_scan_parse_error(dev, apdev): | |
1916 | """Mesh scan element parse error""" | |
1917 | check_mesh_support(dev[0]) | |
1918 | params = { "ssid": "open", | |
1919 | "beacon_int": "2000" } | |
1920 | hapd = hostapd.add_ap(apdev[0], params) | |
1921 | bssid = apdev[0]['bssid'] | |
1922 | hapd.set('vendor_elements', 'dd0201') | |
1923 | for i in range(10): | |
1924 | dev[0].scan(freq=2412) | |
1925 | if bssid in dev[0].request("SCAN_RESULTS"): | |
1926 | break | |
1927 | # This will fail in IE parsing due to the truncated IE in the Probe | |
1928 | # Response frame. | |
1929 | bss = dev[0].request("BSS " + bssid) | |
66bb7d97 JM |
1930 | |
1931 | def test_mesh_missing_mic(dev, apdev): | |
1932 | """Secure mesh network and missing MIC""" | |
1933 | check_mesh_support(dev[0], secure=True) | |
1934 | ||
1935 | dev[0].request("SET ext_mgmt_frame_handling 1") | |
1936 | dev[0].request("SET sae_groups ") | |
1937 | id = add_mesh_secure_net(dev[0]) | |
1938 | dev[0].mesh_group_add(id) | |
1939 | ||
1940 | dev[1].request("SET sae_groups ") | |
1941 | id = add_mesh_secure_net(dev[1]) | |
1942 | dev[1].mesh_group_add(id) | |
1943 | ||
1944 | # Check for mesh joined | |
1945 | check_mesh_group_added(dev[0]) | |
1946 | check_mesh_group_added(dev[1]) | |
1947 | ||
1948 | count = 0 | |
1949 | remove_mic = True | |
1950 | while True: | |
1951 | count += 1 | |
1952 | if count > 15: | |
1953 | raise Exception("Did not see Action frames") | |
1954 | rx_msg = dev[0].mgmt_rx() | |
1955 | if rx_msg is None: | |
7309e804 JM |
1956 | ev = dev[1].wait_event(["MESH-PEER-CONNECTED"], timeout=0.01) |
1957 | if ev: | |
1958 | break | |
66bb7d97 JM |
1959 | raise Exception("MGMT-RX timeout") |
1960 | if rx_msg['subtype'] == 13: | |
1961 | payload = rx_msg['payload'] | |
1962 | frame = rx_msg['frame'] | |
1963 | (categ, action) = struct.unpack('BB', payload[0:2]) | |
1964 | if categ == 15 and action == 1 and remove_mic: | |
1965 | # Mesh Peering Open | |
1966 | pos = frame.find('\x8c\x10') | |
1967 | if not pos: | |
1968 | raise Exception("Could not find MIC element") | |
1969 | logger.info("Found MIC at %d" % pos) | |
1970 | # Remove MIC | |
1971 | rx_msg['frame'] = frame[0:pos] | |
1972 | remove_mic = False | |
1973 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(rx_msg['freq'], rx_msg['datarate'], rx_msg['ssi_signal'], rx_msg['frame'].encode('hex'))): | |
1974 | raise Exception("MGMT_RX_PROCESS failed") | |
1975 | ev = dev[1].wait_event(["MESH-PEER-CONNECTED"], timeout=0.01) | |
1976 | if ev: | |
1977 | break | |
81d6e230 JM |
1978 | |
1979 | def test_mesh_pmkid_mismatch(dev, apdev): | |
1980 | """Secure mesh network and PMKID mismatch""" | |
1981 | check_mesh_support(dev[0], secure=True) | |
1982 | addr0 = dev[0].own_addr() | |
1983 | addr1 = dev[1].own_addr() | |
1984 | dev[0].request("SET sae_groups ") | |
1985 | id = add_mesh_secure_net(dev[0]) | |
1986 | dev[0].set_network(id, "no_auto_peer", "1") | |
1987 | dev[0].mesh_group_add(id) | |
1988 | ||
1989 | dev[1].request("SET sae_groups ") | |
1990 | id = add_mesh_secure_net(dev[1]) | |
1991 | dev[1].set_network(id, "no_auto_peer", "1") | |
1992 | dev[1].mesh_group_add(id) | |
1993 | ||
1994 | # Check for mesh joined | |
1995 | check_mesh_group_added(dev[0]) | |
1996 | check_mesh_group_added(dev[1]) | |
1997 | ||
1998 | # Check for peer connected | |
1999 | ev = dev[0].wait_event(["will not initiate new peer link"], timeout=10) | |
2000 | if ev is None: | |
2001 | raise Exception("Missing no-initiate message") | |
2002 | if "OK" not in dev[0].request("MESH_PEER_ADD " + addr1): | |
2003 | raise Exception("MESH_PEER_ADD failed") | |
2004 | check_mesh_peer_connected(dev[0]) | |
2005 | check_mesh_peer_connected(dev[1]) | |
2006 | ||
2007 | if "OK" not in dev[0].request("MESH_PEER_REMOVE " + addr1): | |
2008 | raise Exception("Failed to remove peer") | |
2009 | ||
2010 | ev = dev[0].wait_event(["will not initiate new peer link"], timeout=10) | |
2011 | if ev is None: | |
2012 | raise Exception("Missing no-initiate message (2)") | |
2013 | dev[0].dump_monitor() | |
2014 | dev[1].dump_monitor() | |
2015 | dev[0].request("SET ext_mgmt_frame_handling 1") | |
2016 | if "OK" not in dev[0].request("MESH_PEER_ADD " + addr1): | |
2017 | raise Exception("MESH_PEER_ADD failed (2)") | |
2018 | ||
2019 | count = 0 | |
2020 | break_pmkid = True | |
2021 | while True: | |
2022 | count += 1 | |
2023 | if count > 50: | |
2024 | raise Exception("Did not see Action frames") | |
2025 | rx_msg = dev[0].mgmt_rx() | |
2026 | if rx_msg is None: | |
2027 | ev = dev[1].wait_event(["MESH-PEER-CONNECTED"], timeout=0.1) | |
2028 | if ev: | |
2029 | break | |
2030 | raise Exception("MGMT-RX timeout") | |
2031 | if rx_msg['subtype'] == 13: | |
2032 | payload = rx_msg['payload'] | |
2033 | frame = rx_msg['frame'] | |
2034 | (categ, action) = struct.unpack('BB', payload[0:2]) | |
2035 | if categ == 15 and action == 1 and break_pmkid: | |
2036 | # Mesh Peering Open | |
2037 | pos = frame.find('\x75\x14') | |
2038 | if not pos: | |
2039 | raise Exception("Could not find Mesh Peering Management element") | |
2040 | logger.info("Found Mesh Peering Management element at %d" % pos) | |
2041 | # Break PMKID to hit "Mesh RSN: Invalid PMKID (Chosen PMK did | |
2042 | # not match calculated PMKID)" | |
2043 | rx_msg['frame'] = frame[0:pos + 6] + '\x00\x00\x00\x00' + frame[pos + 10:] | |
2044 | break_pmkid = False | |
2045 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(rx_msg['freq'], rx_msg['datarate'], rx_msg['ssi_signal'], rx_msg['frame'].encode('hex'))): | |
2046 | raise Exception("MGMT_RX_PROCESS failed") | |
2047 | ev = dev[1].wait_event(["MESH-PEER-CONNECTED"], timeout=0.01) | |
2048 | if ev: | |
2049 | break | |
739fd20c JM |
2050 | |
2051 | def test_mesh_peering_proto(dev, apdev): | |
2052 | """Mesh peering management protocol testing""" | |
2053 | check_mesh_support(dev[0]) | |
2054 | ||
2055 | dev[0].request("SET ext_mgmt_frame_handling 1") | |
2056 | add_open_mesh_network(dev[0], beacon_int=160) | |
2057 | add_open_mesh_network(dev[1], beacon_int=160) | |
2058 | ||
2059 | count = 0 | |
2060 | test = 1 | |
2061 | while True: | |
2062 | count += 1 | |
2063 | if count > 50: | |
2064 | raise Exception("Did not see Action frames") | |
2065 | rx_msg = dev[0].mgmt_rx() | |
2066 | if rx_msg is None: | |
2067 | ev = dev[1].wait_event(["MESH-PEER-CONNECTED"], timeout=0.01) | |
2068 | if ev: | |
2069 | break | |
2070 | raise Exception("MGMT-RX timeout") | |
2071 | if rx_msg['subtype'] == 13: | |
2072 | payload = rx_msg['payload'] | |
2073 | frame = rx_msg['frame'] | |
2074 | (categ, action) = struct.unpack('BB', payload[0:2]) | |
2075 | if categ == 15 and action == 1 and test == 1: | |
2076 | # Mesh Peering Open | |
2077 | pos = frame.find('\x75\x04') | |
2078 | if not pos: | |
2079 | raise Exception("Could not find Mesh Peering Management element") | |
2080 | logger.info("Found Mesh Peering Management element at %d" % pos) | |
2081 | # Remove the element to hit | |
2082 | # "MPM: No Mesh Peering Management element" | |
2083 | rx_msg['frame'] = frame[0:pos] | |
2084 | test += 1 | |
2085 | elif categ == 15 and action == 1 and test == 2: | |
2086 | # Mesh Peering Open | |
2087 | pos = frame.find('\x72\x0e') | |
2088 | if not pos: | |
2089 | raise Exception("Could not find Mesh ID element") | |
2090 | logger.info("Found Mesh ID element at %d" % pos) | |
2091 | # Remove the element to hit | |
2092 | # "MPM: No Mesh ID or Mesh Configuration element" | |
2093 | rx_msg['frame'] = frame[0:pos] + frame[pos + 16:] | |
2094 | test += 1 | |
2095 | elif categ == 15 and action == 1 and test == 3: | |
2096 | # Mesh Peering Open | |
2097 | pos = frame.find('\x72\x0e') | |
2098 | if not pos: | |
2099 | raise Exception("Could not find Mesh ID element") | |
2100 | logger.info("Found Mesh ID element at %d" % pos) | |
2101 | # Replace Mesh ID to hit "MPM: Mesh ID or Mesh Configuration | |
2102 | # element do not match local MBSS" | |
2103 | rx_msg['frame'] = frame[0:pos] + '\x72\x0etest-test-test' + frame[pos + 16:] | |
2104 | test += 1 | |
2105 | elif categ == 15 and action == 1 and test == 4: | |
2106 | # Mesh Peering Open | |
2107 | # Remove IEs to hit | |
2108 | # "MPM: Ignore too short action frame 1 ie_len 0" | |
2109 | rx_msg['frame'] = frame[0:26] | |
2110 | test += 1 | |
2111 | elif categ == 15 and action == 1 and test == 5: | |
2112 | # Mesh Peering Open | |
2113 | # Truncate IEs to hit | |
2114 | # "MPM: Failed to parse PLINK IEs" | |
2115 | rx_msg['frame'] = frame[0:30] | |
2116 | test += 1 | |
2117 | elif categ == 15 and action == 1 and test == 6: | |
2118 | # Mesh Peering Open | |
2119 | pos = frame.find('\x75\x04') | |
2120 | if not pos: | |
2121 | raise Exception("Could not find Mesh Peering Management element") | |
2122 | logger.info("Found Mesh Peering Management element at %d" % pos) | |
2123 | # Truncate the element to hit | |
2124 | # "MPM: Invalid peer mgmt ie" and | |
2125 | # "MPM: Mesh parsing rejected frame" | |
2126 | rx_msg['frame'] = frame[0:pos] + '\x75\x00\x00\x00' + frame[pos + 6:] | |
2127 | test += 1 | |
2128 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(rx_msg['freq'], rx_msg['datarate'], rx_msg['ssi_signal'], rx_msg['frame'].encode('hex'))): | |
2129 | raise Exception("MGMT_RX_PROCESS failed") | |
2130 | ev = dev[1].wait_event(["MESH-PEER-CONNECTED"], timeout=0.01) | |
2131 | if ev: | |
2132 | break | |
2133 | ||
2134 | if test != 7: | |
2135 | raise Exception("Not all test frames completed") | |
c3456015 JM |
2136 | |
2137 | def test_mesh_mpm_init_proto(dev, apdev): | |
2138 | """Mesh peering management protocol testing for peer addition""" | |
2139 | check_mesh_support(dev[0]) | |
2140 | add_open_mesh_network(dev[0]) | |
2141 | check_mesh_group_added(dev[0]) | |
2142 | dev[0].dump_monitor() | |
2143 | ||
2144 | dev[0].request("SET ext_mgmt_frame_handling 1") | |
2145 | ||
2146 | addr = "020000000100" | |
2147 | hdr = "d000ac00020000000000" + addr + addr + "1000" | |
2148 | fixed = "0f010000" | |
2149 | supp_rates = "010802040b168c129824" | |
2150 | ext_supp_rates = "3204b048606c" | |
2151 | mesh_id = "720e777061732d6d6573682d6f70656e" | |
2152 | mesh_conf = "710701010001000009" | |
2153 | mpm = "75040000079d" | |
2154 | ht_capab = "2d1a7c001bffff000000000000000000000100000000000000000000" | |
2155 | ht_oper = "3d160b000000000000000000000000000000000000000000" | |
2156 | ||
2157 | dev[0].request("NOTE no supported rates") | |
2158 | frame = hdr + fixed + ext_supp_rates + mesh_id + mesh_conf + mpm + ht_capab + ht_oper | |
2159 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=%s" % frame): | |
2160 | raise Exception("MGMT_RX_PROCESS failed") | |
2161 | ||
2162 | dev[0].request("NOTE Invalid supported rates element length 33+0") | |
2163 | long_supp_rates = "012100112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00" | |
2164 | frame = hdr + fixed + long_supp_rates + mesh_id + mesh_conf + mpm + ht_capab + ht_oper | |
2165 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=%s" % frame): | |
2166 | raise Exception("MGMT_RX_PROCESS failed") | |
2167 | ||
2168 | dev[0].request("NOTE Too short mesh config") | |
2169 | short_mesh_conf = "710401010001" | |
2170 | frame = hdr + fixed + supp_rates + mesh_id + short_mesh_conf + mpm + ht_capab + ht_oper | |
2171 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=%s" % frame): | |
2172 | raise Exception("MGMT_RX_PROCESS failed") | |
2173 | ||
2174 | dev[0].request("NOTE Add STA failure") | |
2175 | frame = hdr + fixed + supp_rates + ext_supp_rates + mesh_id + mesh_conf + mpm + ht_capab + ht_oper | |
2176 | with fail_test(dev[0], 1, "wpa_driver_nl80211_sta_add"): | |
2177 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=%s" % frame): | |
2178 | raise Exception("MGMT_RX_PROCESS failed") | |
2179 | ||
2180 | dev[0].request("NOTE Send Action failure") | |
2181 | with fail_test(dev[0], 1, "driver_nl80211_send_action"): | |
2182 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=%s" % frame): | |
2183 | raise Exception("MGMT_RX_PROCESS failed") | |
2184 | ||
2185 | dev[0].request("NOTE Set STA failure") | |
2186 | addr = "020000000101" | |
2187 | hdr = "d000ac00020000000000" + addr + addr + "1000" | |
2188 | frame = hdr + fixed + supp_rates + ext_supp_rates + mesh_id + mesh_conf + mpm + ht_capab + ht_oper | |
2189 | with fail_test(dev[0], 2, "wpa_driver_nl80211_sta_add"): | |
2190 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=%s" % frame): | |
2191 | raise Exception("MGMT_RX_PROCESS failed") | |
2192 | ||
2193 | dev[0].request("NOTE ap_sta_add OOM") | |
2194 | addr = "020000000102" | |
2195 | hdr = "d000ac00020000000000" + addr + addr + "1000" | |
2196 | frame = hdr + fixed + supp_rates + ext_supp_rates + mesh_id + mesh_conf + mpm + ht_capab + ht_oper | |
2197 | with alloc_fail(dev[0], 1, "ap_sta_add"): | |
2198 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=%s" % frame): | |
2199 | raise Exception("MGMT_RX_PROCESS failed") | |
2200 | ||
2201 | dev[0].request("NOTE hostapd_get_aid() failure") | |
2202 | addr = "020000000103" | |
2203 | hdr = "d000ac00020000000000" + addr + addr + "1000" | |
2204 | frame = hdr + fixed + supp_rates + ext_supp_rates + mesh_id + mesh_conf + mpm + ht_capab + ht_oper | |
2205 | with fail_test(dev[0], 1, "hostapd_get_aid"): | |
2206 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=%s" % frame): | |
2207 | raise Exception("MGMT_RX_PROCESS failed") | |
2208 | ||
2209 | if "OK" not in dev[0].request("MESH_PEER_REMOVE 02:00:00:00:01:00"): | |
2210 | raise Exception("Failed to remove peer") | |
2211 | if "FAIL" not in dev[0].request("MESH_PEER_REMOVE 02:00:00:00:01:02"): | |
2212 | raise Exception("Unexpected MESH_PEER_REMOVE success") | |
2213 | if "FAIL" not in dev[1].request("MESH_PEER_REMOVE 02:00:00:00:01:02"): | |
2214 | raise Exception("Unexpected MESH_PEER_REMOVE success(2)") | |
2215 | if "FAIL" not in dev[1].request("MESH_PEER_ADD 02:00:00:00:01:02"): | |
2216 | raise Exception("Unexpected MESH_PEER_ADD success") | |
68f326d5 JM |
2217 | |
2218 | def test_mesh_holding(dev, apdev): | |
2219 | """Mesh MPM FSM and HOLDING state event OPN_ACPT""" | |
2220 | check_mesh_support(dev[0]) | |
2221 | add_open_mesh_network(dev[0]) | |
2222 | add_open_mesh_network(dev[1]) | |
2223 | check_mesh_group_added(dev[0]) | |
2224 | check_mesh_group_added(dev[1]) | |
2225 | check_mesh_peer_connected(dev[0]) | |
2226 | check_mesh_peer_connected(dev[1]) | |
2227 | ||
2228 | addr0 = dev[0].own_addr() | |
2229 | addr1 = dev[1].own_addr() | |
2230 | ||
2231 | dev[0].request("SET ext_mgmt_frame_handling 1") | |
2232 | if "OK" not in dev[0].request("MESH_PEER_REMOVE " + addr1): | |
2233 | raise Exception("Failed to remove peer") | |
2234 | ||
2235 | rx_msg = dev[0].mgmt_rx() | |
2236 | if rx_msg is None: | |
2237 | raise Exception("MGMT-RX timeout") | |
2238 | if rx_msg['subtype'] != 13: | |
2239 | raise Exception("Unexpected management frame") | |
2240 | payload = rx_msg['payload'] | |
2241 | (categ, action) = struct.unpack('BB', payload[0:2]) | |
2242 | if categ != 0x0f or action != 0x03: | |
2243 | raise Exception("Did not see Mesh Peering Close") | |
2244 | ||
2245 | peer_lid = payload[-6:-4].encode("hex") | |
2246 | my_lid = payload[-4:-2].encode("hex") | |
2247 | ||
2248 | # Drop Mesh Peering Close and instead, process an unexpected Mesh Peering | |
2249 | # Open to trigger transmission of another Mesh Peering Close in the HOLDING | |
2250 | # state based on an OPN_ACPT event. | |
2251 | ||
2252 | dst = addr0.replace(':', '') | |
2253 | src = addr1.replace(':', '') | |
2254 | hdr = "d000ac00" + dst + src + src + "1000" | |
2255 | fixed = "0f010000" | |
2256 | supp_rates = "010802040b168c129824" | |
2257 | ext_supp_rates = "3204b048606c" | |
2258 | mesh_id = "720e777061732d6d6573682d6f70656e" | |
2259 | mesh_conf = "710701010001000009" | |
2260 | mpm = "7504" + my_lid + peer_lid | |
2261 | ht_capab = "2d1a7c001bffff000000000000000000000100000000000000000000" | |
2262 | ht_oper = "3d160b000000000000000000000000000000000000000000" | |
2263 | ||
2264 | frame = hdr + fixed + supp_rates + ext_supp_rates + mesh_id + mesh_conf + mpm + ht_capab + ht_oper | |
2265 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=%s" % frame): | |
2266 | raise Exception("MGMT_RX_PROCESS failed") | |
2267 | time.sleep(0.1) | |
434f8f7f JM |
2268 | |
2269 | def test_mesh_cnf_rcvd_event_cls_acpt(dev, apdev): | |
2270 | """Mesh peering management protocol testing - CLS_ACPT event in CNF_RCVD""" | |
2271 | check_mesh_support(dev[0]) | |
2272 | add_open_mesh_network(dev[0]) | |
2273 | check_mesh_group_added(dev[0]) | |
2274 | dev[0].dump_monitor() | |
2275 | ||
2276 | dev[0].request("SET ext_mgmt_frame_handling 1") | |
2277 | add_open_mesh_network(dev[1]) | |
2278 | check_mesh_group_added(dev[1]) | |
2279 | ||
2280 | addr0 = dev[0].own_addr() | |
2281 | addr1 = dev[1].own_addr() | |
2282 | ||
2283 | rx_msg = dev[0].mgmt_rx() | |
2284 | # Drop Mesh Peering Open | |
2285 | ||
2286 | rx_msg = dev[0].mgmt_rx() | |
2287 | # Allow Mesh Peering Confirm to go through | |
2288 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(rx_msg['freq'], rx_msg['datarate'], rx_msg['ssi_signal'], rx_msg['frame'].encode('hex'))): | |
2289 | raise Exception("MGMT_RX_PROCESS failed") | |
2290 | ||
2291 | payload = rx_msg['payload'] | |
2292 | peer_lid = payload[51:53].encode("hex") | |
2293 | my_lid = payload[53:55].encode("hex") | |
2294 | ||
2295 | dst = addr0.replace(':', '') | |
2296 | src = addr1.replace(':', '') | |
2297 | hdr = "d000ac00" + dst + src + src + "1000" | |
2298 | fixed = "0f03" | |
2299 | mesh_id = "720e777061732d6d6573682d6f70656e" | |
2300 | mpm = "75080000" + peer_lid + my_lid + "3700" | |
2301 | frame = hdr + fixed + mesh_id + mpm | |
2302 | ||
2303 | # Inject Mesh Peering Close to hit "state CNF_RCVD event CLS_ACPT" to | |
2304 | # HOLDING transition. | |
2305 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + frame): | |
2306 | raise Exception("MGMT_RX_PROCESS failed") | |
b136894f JM |
2307 | |
2308 | def test_mesh_opn_snt_event_cls_acpt(dev, apdev): | |
2309 | """Mesh peering management protocol testing - CLS_ACPT event in OPN_SNT""" | |
2310 | check_mesh_support(dev[0]) | |
2311 | add_open_mesh_network(dev[0]) | |
2312 | check_mesh_group_added(dev[0]) | |
2313 | dev[0].dump_monitor() | |
2314 | ||
2315 | dev[0].request("SET ext_mgmt_frame_handling 1") | |
2316 | add_open_mesh_network(dev[1]) | |
2317 | check_mesh_group_added(dev[1]) | |
2318 | ||
2319 | addr0 = dev[0].own_addr() | |
2320 | addr1 = dev[1].own_addr() | |
2321 | ||
2322 | rx_msg = dev[0].mgmt_rx() | |
2323 | # Drop Mesh Peering Open | |
2324 | ||
2325 | rx_msg = dev[0].mgmt_rx() | |
2326 | # Drop Mesh Peering Confirm | |
2327 | ||
2328 | payload = rx_msg['payload'] | |
2329 | peer_lid = "0000" | |
2330 | my_lid = payload[53:55].encode("hex") | |
2331 | ||
2332 | dst = addr0.replace(':', '') | |
2333 | src = addr1.replace(':', '') | |
2334 | hdr = "d000ac00" + dst + src + src + "1000" | |
2335 | fixed = "0f03" | |
2336 | mesh_id = "720e777061732d6d6573682d6f70656e" | |
2337 | mpm = "75080000" + peer_lid + my_lid + "3700" | |
2338 | frame = hdr + fixed + mesh_id + mpm | |
2339 | ||
2340 | # Inject Mesh Peering Close to hit "state OPN_SNTevent CLS_ACPT" to | |
2341 | # HOLDING transition. | |
2342 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq=2412 datarate=0 ssi_signal=-30 frame=" + frame): | |
2343 | raise Exception("MGMT_RX_PROCESS failed") | |
a8ef83f4 JM |
2344 | |
2345 | def test_mesh_select_network(dev): | |
2346 | """Mesh network and SELECT_NETWORK""" | |
2347 | check_mesh_support(dev[0]) | |
2348 | id0 = add_open_mesh_network(dev[0], start=False) | |
2349 | id1 = add_open_mesh_network(dev[1], start=False) | |
2350 | dev[0].select_network(id0) | |
2351 | dev[1].select_network(id1) | |
2352 | check_mesh_group_added(dev[0]) | |
2353 | check_mesh_group_added(dev[1]) | |
2354 | check_mesh_peer_connected(dev[0]) | |
2355 | check_mesh_peer_connected(dev[1]) | |
2356 | hwsim_utils.test_connectivity(dev[0], dev[1]) | |
f5a270b5 JB |
2357 | |
2358 | def test_mesh_forwarding(dev): | |
2359 | """Mesh with two stations that can't reach each other directly""" | |
2360 | try: | |
2361 | set_group_map(dev[0], 1) | |
2362 | set_group_map(dev[1], 3) | |
2363 | set_group_map(dev[2], 2) | |
2364 | check_mesh_support(dev[0]) | |
2365 | for i in range(3): | |
2366 | add_open_mesh_network(dev[i]) | |
2367 | check_mesh_group_added(dev[i]) | |
2368 | for i in range(3): | |
2369 | check_mesh_peer_connected(dev[i]) | |
2370 | ||
2371 | hwsim_utils.test_connectivity(dev[0], dev[1]) | |
2372 | hwsim_utils.test_connectivity(dev[1], dev[2]) | |
2373 | hwsim_utils.test_connectivity(dev[0], dev[2]) | |
2374 | finally: | |
2375 | # reset groups | |
2376 | set_group_map(dev[0], 1) | |
2377 | set_group_map(dev[1], 1) | |
2378 | set_group_map(dev[2], 1) | |
7f2905e0 JM |
2379 | |
2380 | def test_mesh_forwarding_secure(dev): | |
2381 | """Mesh with two stations that can't reach each other directly (RSN)""" | |
2382 | check_mesh_support(dev[0], secure=True) | |
2383 | try: | |
2384 | set_group_map(dev[0], 1) | |
2385 | set_group_map(dev[1], 3) | |
2386 | set_group_map(dev[2], 2) | |
2387 | for i in range(3): | |
2388 | dev[i].request("SET sae_groups ") | |
2389 | id = add_mesh_secure_net(dev[i]) | |
2390 | dev[i].mesh_group_add(id) | |
2391 | check_mesh_group_added(dev[i]) | |
2392 | for i in range(3): | |
2393 | check_mesh_peer_connected(dev[i]) | |
2394 | ||
2395 | hwsim_utils.test_connectivity(dev[0], dev[1]) | |
2396 | hwsim_utils.test_connectivity(dev[1], dev[2]) | |
2397 | hwsim_utils.test_connectivity(dev[0], dev[2]) | |
2398 | finally: | |
2399 | # reset groups | |
2400 | set_group_map(dev[0], 1) | |
2401 | set_group_map(dev[1], 1) | |
2402 | set_group_map(dev[2], 1) |