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