]>
Commit | Line | Data |
---|---|---|
709f18d5 JM |
1 | # Test cases for dynamic BSS changes with hostapd |
2 | # Copyright (c) 2013, Qualcomm Atheros, Inc. | |
3 | # | |
4 | # This software may be distributed under the terms of the BSD license. | |
5 | # See README for more details. | |
6 | ||
9fd6804d | 7 | from remotehost import remote_compatible |
709f18d5 JM |
8 | import time |
9 | import subprocess | |
10 | import logging | |
c9aa4308 | 11 | logger = logging.getLogger() |
b97a7bf6 | 12 | import os |
709f18d5 JM |
13 | |
14 | import hwsim_utils | |
15 | import hostapd | |
3f9e6ca5 | 16 | from utils import alloc_fail, require_under_vm, get_phy |
4e979d9d | 17 | from test_ap_acs import force_prev_ap_on_24g |
709f18d5 | 18 | |
9fd6804d | 19 | @remote_compatible |
709f18d5 JM |
20 | def test_ap_change_ssid(dev, apdev): |
21 | """Dynamic SSID change with hostapd and WPA2-PSK""" | |
22 | params = hostapd.wpa2_params(ssid="test-wpa2-psk-start", | |
23 | passphrase="12345678") | |
6f334bf7 | 24 | hapd = hostapd.add_ap(apdev[0], params) |
c65f23ab JM |
25 | id = dev[0].connect("test-wpa2-psk-start", psk="12345678", |
26 | scan_freq="2412") | |
709f18d5 JM |
27 | dev[0].request("DISCONNECT") |
28 | ||
29 | logger.info("Change SSID dynamically") | |
709f18d5 JM |
30 | res = hapd.request("SET ssid test-wpa2-psk-new") |
31 | if "OK" not in res: | |
32 | raise Exception("SET command failed") | |
33 | res = hapd.request("RELOAD") | |
34 | if "OK" not in res: | |
35 | raise Exception("RELOAD command failed") | |
36 | ||
37 | dev[0].set_network_quoted(id, "ssid", "test-wpa2-psk-new") | |
38 | dev[0].connect_network(id) | |
a6333977 | 39 | |
90ad11e6 | 40 | def multi_check(dev, check, scan_opt=True): |
78060b25 | 41 | id = [] |
dd6f538e JM |
42 | num_bss = len(check) |
43 | for i in range(0, num_bss): | |
78060b25 JM |
44 | dev[i].request("BSS_FLUSH 0") |
45 | dev[i].dump_monitor() | |
dd6f538e | 46 | for i in range(0, num_bss): |
4905f1eb JM |
47 | if check[i]: |
48 | continue | |
49 | id.append(dev[i].connect("bss-" + str(i + 1), key_mgmt="NONE", | |
50 | scan_freq="2412", wait_connect=False)) | |
51 | for i in range(num_bss): | |
78060b25 | 52 | if not check[i]: |
4905f1eb | 53 | continue |
90ad11e6 JM |
54 | bssid = '02:00:00:00:03:0' + str(i) |
55 | if scan_opt: | |
56 | dev[i].scan_for_bss(bssid, freq=2412) | |
4905f1eb JM |
57 | id.append(dev[i].connect("bss-" + str(i + 1), key_mgmt="NONE", |
58 | scan_freq="2412", wait_connect=True)) | |
59 | first = True | |
60 | for i in range(num_bss): | |
61 | if not check[i]: | |
62 | timeout=0.2 if first else 0.01 | |
63 | first = False | |
64 | ev = dev[i].wait_event(["CTRL-EVENT-CONNECTED"], timeout=timeout) | |
78060b25 JM |
65 | if ev: |
66 | raise Exception("Unexpected connection") | |
67 | ||
dd6f538e | 68 | for i in range(0, num_bss): |
78060b25 | 69 | dev[i].remove_network(id[i]) |
4905f1eb JM |
70 | for i in range(num_bss): |
71 | if check[i]: | |
72 | dev[i].wait_disconnected(timeout=5) | |
a6333977 | 73 | |
78060b25 | 74 | res = '' |
dd6f538e | 75 | for i in range(0, num_bss): |
78060b25 | 76 | res = res + dev[i].request("BSS RANGE=ALL MASK=0x2") |
a6333977 | 77 | |
dd6f538e | 78 | for i in range(0, num_bss): |
78060b25 JM |
79 | if not check[i]: |
80 | bssid = '02:00:00:00:03:0' + str(i) | |
81 | if bssid in res: | |
82 | raise Exception("Unexpected BSS" + str(i) + " in scan results") | |
a6333977 JM |
83 | |
84 | def test_ap_bss_add_remove(dev, apdev): | |
85 | """Dynamic BSS add/remove operations with hostapd""" | |
90ad11e6 JM |
86 | try: |
87 | _test_ap_bss_add_remove(dev, apdev) | |
88 | finally: | |
89 | for i in range(3): | |
90 | dev[i].request("SCAN_INTERVAL 5") | |
91 | ||
92 | def _test_ap_bss_add_remove(dev, apdev): | |
93 | for i in range(3): | |
f98b0e58 | 94 | dev[i].flush_scan_cache() |
90ad11e6 | 95 | dev[i].request("SCAN_INTERVAL 1") |
a6333977 JM |
96 | ifname1 = apdev[0]['ifname'] |
97 | ifname2 = apdev[0]['ifname'] + '-2' | |
98 | ifname3 = apdev[0]['ifname'] + '-3' | |
99 | logger.info("Set up three BSSes one by one") | |
9cd6f4c0 | 100 | hostapd.add_bss(apdev[0], ifname1, 'bss-1.conf') |
78060b25 | 101 | multi_check(dev, [ True, False, False ]) |
9cd6f4c0 | 102 | hostapd.add_bss(apdev[0], ifname2, 'bss-2.conf') |
78060b25 | 103 | multi_check(dev, [ True, True, False ]) |
9cd6f4c0 | 104 | hostapd.add_bss(apdev[0], ifname3, 'bss-3.conf') |
78060b25 | 105 | multi_check(dev, [ True, True, True ]) |
a6333977 JM |
106 | |
107 | logger.info("Remove the last BSS and re-add it") | |
c92ee957 | 108 | hostapd.remove_bss(apdev[0], ifname3) |
78060b25 | 109 | multi_check(dev, [ True, True, False ]) |
9cd6f4c0 | 110 | hostapd.add_bss(apdev[0], ifname3, 'bss-3.conf') |
78060b25 | 111 | multi_check(dev, [ True, True, True ]) |
a6333977 JM |
112 | |
113 | logger.info("Remove the middle BSS and re-add it") | |
c92ee957 | 114 | hostapd.remove_bss(apdev[0], ifname2) |
78060b25 | 115 | multi_check(dev, [ True, False, True ]) |
9cd6f4c0 | 116 | hostapd.add_bss(apdev[0], ifname2, 'bss-2.conf') |
78060b25 | 117 | multi_check(dev, [ True, True, True ]) |
a6333977 | 118 | |
a364852b | 119 | logger.info("Remove the first BSS and re-add it and other BSSs") |
c92ee957 | 120 | hostapd.remove_bss(apdev[0], ifname1) |
a364852b | 121 | multi_check(dev, [ False, False, False ]) |
9cd6f4c0 JD |
122 | hostapd.add_bss(apdev[0], ifname1, 'bss-1.conf') |
123 | hostapd.add_bss(apdev[0], ifname2, 'bss-2.conf') | |
124 | hostapd.add_bss(apdev[0], ifname3, 'bss-3.conf') | |
78060b25 | 125 | multi_check(dev, [ True, True, True ]) |
a6333977 | 126 | |
a364852b | 127 | logger.info("Remove two BSSes and re-add them") |
c92ee957 | 128 | hostapd.remove_bss(apdev[0], ifname2) |
a364852b | 129 | multi_check(dev, [ True, False, True ]) |
c92ee957 | 130 | hostapd.remove_bss(apdev[0], ifname3) |
78060b25 | 131 | multi_check(dev, [ True, False, False ]) |
9cd6f4c0 | 132 | hostapd.add_bss(apdev[0], ifname2, 'bss-2.conf') |
78060b25 | 133 | multi_check(dev, [ True, True, False ]) |
9cd6f4c0 | 134 | hostapd.add_bss(apdev[0], ifname3, 'bss-3.conf') |
78060b25 | 135 | multi_check(dev, [ True, True, True ]) |
a6333977 | 136 | |
a364852b | 137 | logger.info("Remove three BSSes in and re-add them") |
c92ee957 | 138 | hostapd.remove_bss(apdev[0], ifname3) |
78060b25 | 139 | multi_check(dev, [ True, True, False ]) |
c92ee957 | 140 | hostapd.remove_bss(apdev[0], ifname2) |
78060b25 | 141 | multi_check(dev, [ True, False, False ]) |
c92ee957 | 142 | hostapd.remove_bss(apdev[0], ifname1) |
77990cd7 | 143 | multi_check(dev, [ False, False, False ]) |
9cd6f4c0 | 144 | hostapd.add_bss(apdev[0], ifname1, 'bss-1.conf') |
78060b25 | 145 | multi_check(dev, [ True, False, False ]) |
9cd6f4c0 | 146 | hostapd.add_bss(apdev[0], ifname2, 'bss-2.conf') |
78060b25 | 147 | multi_check(dev, [ True, True, False ]) |
9cd6f4c0 | 148 | hostapd.add_bss(apdev[0], ifname3, 'bss-3.conf') |
78060b25 | 149 | multi_check(dev, [ True, True, True ]) |
a6333977 JM |
150 | |
151 | logger.info("Test error handling if a duplicate ifname is tried") | |
9cd6f4c0 | 152 | hostapd.add_bss(apdev[0], ifname3, 'bss-3.conf', ignore_error=True) |
78060b25 | 153 | multi_check(dev, [ True, True, True ]) |
5230bf64 | 154 | |
dd6f538e JM |
155 | def test_ap_bss_add_remove_during_ht_scan(dev, apdev): |
156 | """Dynamic BSS add during HT40 co-ex scan""" | |
f98b0e58 JM |
157 | for i in range(3): |
158 | dev[i].flush_scan_cache() | |
dd6f538e JM |
159 | ifname1 = apdev[0]['ifname'] |
160 | ifname2 = apdev[0]['ifname'] + '-2' | |
9cd6f4c0 JD |
161 | hostapd.add_bss(apdev[0], ifname1, 'bss-ht40-1.conf') |
162 | hostapd.add_bss(apdev[0], ifname2, 'bss-ht40-2.conf') | |
90ad11e6 | 163 | multi_check(dev, [ True, True ], scan_opt=False) |
c92ee957 JD |
164 | hostapd.remove_bss(apdev[0], ifname2) |
165 | hostapd.remove_bss(apdev[0], ifname1) | |
dd6f538e | 166 | |
9cd6f4c0 JD |
167 | hostapd.add_bss(apdev[0], ifname1, 'bss-ht40-1.conf') |
168 | hostapd.add_bss(apdev[0], ifname2, 'bss-ht40-2.conf') | |
c92ee957 | 169 | hostapd.remove_bss(apdev[0], ifname2) |
90ad11e6 | 170 | multi_check(dev, [ True, False ], scan_opt=False) |
c92ee957 | 171 | hostapd.remove_bss(apdev[0], ifname1) |
dd6f538e | 172 | |
9cd6f4c0 JD |
173 | hostapd.add_bss(apdev[0], ifname1, 'bss-ht40-1.conf') |
174 | hostapd.add_bss(apdev[0], ifname2, 'bss-ht40-2.conf') | |
c92ee957 | 175 | hostapd.remove_bss(apdev[0], ifname1) |
dd6f538e JM |
176 | multi_check(dev, [ False, False ]) |
177 | ||
77990cd7 JM |
178 | def test_ap_multi_bss_config(dev, apdev): |
179 | """hostapd start with a multi-BSS configuration file""" | |
f98b0e58 JM |
180 | for i in range(3): |
181 | dev[i].flush_scan_cache() | |
77990cd7 JM |
182 | ifname1 = apdev[0]['ifname'] |
183 | ifname2 = apdev[0]['ifname'] + '-2' | |
184 | ifname3 = apdev[0]['ifname'] + '-3' | |
185 | logger.info("Set up three BSSes with one configuration file") | |
50e49cd2 | 186 | hapd = hostapd.add_iface(apdev[0], 'multi-bss.conf') |
77990cd7 JM |
187 | hapd.enable() |
188 | multi_check(dev, [ True, True, True ]) | |
c92ee957 | 189 | hostapd.remove_bss(apdev[0], ifname2) |
a364852b | 190 | multi_check(dev, [ True, False, True ]) |
c92ee957 | 191 | hostapd.remove_bss(apdev[0], ifname3) |
a364852b | 192 | multi_check(dev, [ True, False, False ]) |
c92ee957 | 193 | hostapd.remove_bss(apdev[0], ifname1) |
a364852b JM |
194 | multi_check(dev, [ False, False, False ]) |
195 | ||
50e49cd2 | 196 | hapd = hostapd.add_iface(apdev[0], 'multi-bss.conf') |
a364852b | 197 | hapd.enable() |
c92ee957 | 198 | hostapd.remove_bss(apdev[0], ifname1) |
77990cd7 JM |
199 | multi_check(dev, [ False, False, False ]) |
200 | ||
a3d35254 JD |
201 | def invalid_ap(ap): |
202 | logger.info("Trying to start AP " + ap['ifname'] + " with invalid configuration") | |
203 | hapd = hostapd.add_ap(ap, {}, no_enable=True) | |
5230bf64 JM |
204 | hapd.set("ssid", "invalid-config") |
205 | hapd.set("channel", "12345") | |
206 | try: | |
207 | hapd.enable() | |
208 | started = True | |
bab493b9 | 209 | except Exception as e: |
5230bf64 JM |
210 | started = False |
211 | if started: | |
212 | raise Exception("ENABLE command succeeded unexpectedly") | |
213 | return hapd | |
214 | ||
9fd6804d | 215 | @remote_compatible |
5230bf64 JM |
216 | def test_ap_invalid_config(dev, apdev): |
217 | """Try to start AP with invalid configuration and fix configuration""" | |
a3d35254 | 218 | hapd = invalid_ap(apdev[0]) |
5230bf64 JM |
219 | |
220 | logger.info("Fix configuration and start AP again") | |
221 | hapd.set("channel", "1") | |
222 | hapd.enable() | |
223 | dev[0].connect("invalid-config", key_mgmt="NONE", scan_freq="2412") | |
224 | ||
9fd6804d | 225 | @remote_compatible |
5230bf64 JM |
226 | def test_ap_invalid_config2(dev, apdev): |
227 | """Try to start AP with invalid configuration and remove interface""" | |
a3d35254 | 228 | hapd = invalid_ap(apdev[0]) |
5230bf64 | 229 | logger.info("Remove interface with failed configuration") |
a3d35254 | 230 | hostapd.remove_bss(apdev[0]) |
742117ad JM |
231 | |
232 | def test_ap_remove_during_acs(dev, apdev): | |
233 | """Remove interface during ACS""" | |
4e979d9d | 234 | force_prev_ap_on_24g(apdev[0]) |
742117ad JM |
235 | params = hostapd.wpa2_params(ssid="test-acs-remove", passphrase="12345678") |
236 | params['channel'] = '0' | |
41ba40e7 | 237 | hostapd.add_ap(apdev[0], params) |
4193b897 | 238 | hostapd.remove_bss(apdev[0]) |
742117ad JM |
239 | |
240 | def test_ap_remove_during_acs2(dev, apdev): | |
241 | """Remove BSS during ACS in multi-BSS configuration""" | |
4e979d9d | 242 | force_prev_ap_on_24g(apdev[0]) |
742117ad JM |
243 | ifname = apdev[0]['ifname'] |
244 | ifname2 = ifname + "-2" | |
4193b897 | 245 | hapd = hostapd.add_ap(apdev[0], {}, no_enable=True) |
742117ad JM |
246 | hapd.set("ssid", "test-acs-remove") |
247 | hapd.set("channel", "0") | |
248 | hapd.set("bss", ifname2) | |
249 | hapd.set("ssid", "test-acs-remove2") | |
250 | hapd.enable() | |
4193b897 | 251 | hostapd.remove_bss(apdev[0]) |
742117ad JM |
252 | |
253 | def test_ap_remove_during_acs3(dev, apdev): | |
254 | """Remove second BSS during ACS in multi-BSS configuration""" | |
4e979d9d | 255 | force_prev_ap_on_24g(apdev[0]) |
742117ad JM |
256 | ifname = apdev[0]['ifname'] |
257 | ifname2 = ifname + "-2" | |
4193b897 | 258 | hapd = hostapd.add_ap(apdev[0], {}, no_enable=True) |
742117ad JM |
259 | hapd.set("ssid", "test-acs-remove") |
260 | hapd.set("channel", "0") | |
261 | hapd.set("bss", ifname2) | |
262 | hapd.set("ssid", "test-acs-remove2") | |
263 | hapd.enable() | |
4193b897 | 264 | hostapd.remove_bss(apdev[0], ifname2) |
742117ad | 265 | |
9fd6804d | 266 | @remote_compatible |
742117ad JM |
267 | def test_ap_remove_during_ht_coex_scan(dev, apdev): |
268 | """Remove interface during HT co-ex scan""" | |
269 | params = hostapd.wpa2_params(ssid="test-ht-remove", passphrase="12345678") | |
270 | params['channel'] = '1' | |
271 | params['ht_capab'] = "[HT40+]" | |
272 | ifname = apdev[0]['ifname'] | |
41ba40e7 | 273 | hostapd.add_ap(apdev[0], params) |
4193b897 | 274 | hostapd.remove_bss(apdev[0]) |
742117ad JM |
275 | |
276 | def test_ap_remove_during_ht_coex_scan2(dev, apdev): | |
277 | """Remove BSS during HT co-ex scan in multi-BSS configuration""" | |
278 | ifname = apdev[0]['ifname'] | |
279 | ifname2 = ifname + "-2" | |
4193b897 | 280 | hapd = hostapd.add_ap(apdev[0], {}, no_enable=True) |
742117ad JM |
281 | hapd.set("ssid", "test-ht-remove") |
282 | hapd.set("channel", "1") | |
283 | hapd.set("ht_capab", "[HT40+]") | |
284 | hapd.set("bss", ifname2) | |
285 | hapd.set("ssid", "test-ht-remove2") | |
286 | hapd.enable() | |
4193b897 | 287 | hostapd.remove_bss(apdev[0]) |
742117ad JM |
288 | |
289 | def test_ap_remove_during_ht_coex_scan3(dev, apdev): | |
290 | """Remove second BSS during HT co-ex scan in multi-BSS configuration""" | |
291 | ifname = apdev[0]['ifname'] | |
292 | ifname2 = ifname + "-2" | |
4193b897 | 293 | hapd = hostapd.add_ap(apdev[0], {}, no_enable=True) |
742117ad JM |
294 | hapd.set("ssid", "test-ht-remove") |
295 | hapd.set("channel", "1") | |
296 | hapd.set("ht_capab", "[HT40+]") | |
297 | hapd.set("bss", ifname2) | |
298 | hapd.set("ssid", "test-ht-remove2") | |
299 | hapd.enable() | |
4193b897 | 300 | hostapd.remove_bss(apdev[0], ifname2) |
00f74dbd | 301 | |
9fd6804d | 302 | @remote_compatible |
00f74dbd JM |
303 | def test_ap_enable_disable_reenable(dev, apdev): |
304 | """Enable, disable, re-enable AP""" | |
4193b897 | 305 | hapd = hostapd.add_ap(apdev[0], {}, no_enable=True) |
00f74dbd JM |
306 | hapd.set("ssid", "dynamic") |
307 | hapd.enable() | |
308 | ev = hapd.wait_event(["AP-ENABLED"], timeout=30) | |
309 | if ev is None: | |
310 | raise Exception("AP startup timed out") | |
311 | dev[0].connect("dynamic", key_mgmt="NONE", scan_freq="2412") | |
312 | hapd.disable() | |
313 | ev = hapd.wait_event(["AP-DISABLED"], timeout=30) | |
314 | if ev is None: | |
315 | raise Exception("AP disabling timed out") | |
5f35a5e2 | 316 | dev[0].wait_disconnected(timeout=10) |
00f74dbd JM |
317 | hapd.enable() |
318 | ev = hapd.wait_event(["AP-ENABLED"], timeout=30) | |
319 | if ev is None: | |
320 | raise Exception("AP startup timed out") | |
321 | dev[1].connect("dynamic", key_mgmt="NONE", scan_freq="2412") | |
5f35a5e2 | 322 | dev[0].wait_connected(timeout=10) |
de93da91 JM |
323 | |
324 | def test_ap_double_disable(dev, apdev): | |
325 | """Double DISABLE regression test""" | |
5148b392 | 326 | hapd = hostapd.add_bss(apdev[0], apdev[0]['ifname'], 'bss-1.conf') |
9cd6f4c0 | 327 | hostapd.add_bss(apdev[0], apdev[0]['ifname'] + '-2', 'bss-2.conf') |
de93da91 JM |
328 | hapd.disable() |
329 | if "FAIL" not in hapd.request("DISABLE"): | |
330 | raise Exception("Second DISABLE accepted unexpectedly") | |
331 | hapd.enable() | |
332 | hapd.disable() | |
333 | if "FAIL" not in hapd.request("DISABLE"): | |
334 | raise Exception("Second DISABLE accepted unexpectedly") | |
b97a7bf6 JM |
335 | |
336 | def test_ap_bss_add_many(dev, apdev): | |
337 | """Large number of BSS add operations with hostapd""" | |
338 | try: | |
339 | _test_ap_bss_add_many(dev, apdev) | |
340 | finally: | |
341 | dev[0].request("SCAN_INTERVAL 5") | |
342 | ifname = apdev[0]['ifname'] | |
dc6342de | 343 | hapd = hostapd.HostapdGlobal(apdev[0]) |
b97a7bf6 JM |
344 | hapd.flush() |
345 | for i in range(16): | |
346 | ifname2 = ifname + '-' + str(i) | |
347 | hapd.remove(ifname2) | |
348 | try: | |
349 | os.remove('/tmp/hwsim-bss.conf') | |
350 | except: | |
351 | pass | |
352 | ||
353 | def _test_ap_bss_add_many(dev, apdev): | |
354 | ifname = apdev[0]['ifname'] | |
9cd6f4c0 | 355 | hostapd.add_bss(apdev[0], ifname, 'bss-1.conf') |
b97a7bf6 JM |
356 | fname = '/tmp/hwsim-bss.conf' |
357 | for i in range(16): | |
358 | ifname2 = ifname + '-' + str(i) | |
359 | with open(fname, 'w') as f: | |
360 | f.write("driver=nl80211\n") | |
361 | f.write("hw_mode=g\n") | |
362 | f.write("channel=1\n") | |
363 | f.write("ieee80211n=1\n") | |
364 | f.write("interface=%s\n" % ifname2) | |
365 | f.write("bssid=02:00:00:00:03:%02x\n" % (i + 1)) | |
366 | f.write("ctrl_interface=/var/run/hostapd\n") | |
367 | f.write("ssid=test-%d\n" % i) | |
9cd6f4c0 | 368 | hostapd.add_bss(apdev[0], ifname2, fname) |
b97a7bf6 JM |
369 | os.remove(fname) |
370 | ||
371 | dev[0].request("SCAN_INTERVAL 1") | |
372 | dev[0].connect("bss-1", key_mgmt="NONE", scan_freq="2412") | |
373 | dev[0].request("DISCONNECT") | |
374 | dev[0].wait_disconnected(timeout=5) | |
375 | for i in range(16): | |
376 | dev[0].connect("test-%d" % i, key_mgmt="NONE", scan_freq="2412") | |
377 | dev[0].request("DISCONNECT") | |
378 | dev[0].wait_disconnected(timeout=5) | |
379 | ifname2 = ifname + '-' + str(i) | |
1728a2e7 | 380 | hostapd.remove_bss(apdev[0], ifname2) |
cece9b7d JM |
381 | |
382 | def test_ap_bss_add_reuse_existing(dev, apdev): | |
383 | """Dynamic BSS add operation reusing existing interface""" | |
384 | ifname1 = apdev[0]['ifname'] | |
385 | ifname2 = apdev[0]['ifname'] + '-2' | |
9cd6f4c0 | 386 | hostapd.add_bss(apdev[0], ifname1, 'bss-1.conf') |
cece9b7d JM |
387 | subprocess.check_call(["iw", "dev", ifname1, "interface", "add", ifname2, |
388 | "type", "__ap"]) | |
9cd6f4c0 | 389 | hostapd.add_bss(apdev[0], ifname2, 'bss-2.conf') |
c92ee957 | 390 | hostapd.remove_bss(apdev[0], ifname2) |
cece9b7d | 391 | subprocess.check_call(["iw", "dev", ifname2, "del"]) |
f7af5a48 JM |
392 | |
393 | def hapd_bss_out_of_mem(hapd, phy, confname, count, func): | |
394 | with alloc_fail(hapd, count, func): | |
395 | hapd_global = hostapd.HostapdGlobal() | |
396 | res = hapd_global.ctrl.request("ADD bss_config=" + phy + ":" + confname) | |
397 | if "OK" in res: | |
398 | raise Exception("add_bss succeeded") | |
399 | ||
400 | def test_ap_bss_add_out_of_memory(dev, apdev): | |
401 | """Running out of memory while adding a BSS""" | |
8b8a1864 | 402 | hapd2 = hostapd.add_ap(apdev[1], { "ssid": "open" }) |
f7af5a48 JM |
403 | |
404 | ifname1 = apdev[0]['ifname'] | |
405 | ifname2 = apdev[0]['ifname'] + '-2' | |
406 | ||
407 | hapd_bss_out_of_mem(hapd2, 'phy3', 'bss-1.conf', 1, 'hostapd_add_iface') | |
408 | for i in range(1, 3): | |
409 | hapd_bss_out_of_mem(hapd2, 'phy3', 'bss-1.conf', | |
410 | i, 'hostapd_interface_init_bss') | |
411 | hapd_bss_out_of_mem(hapd2, 'phy3', 'bss-1.conf', | |
412 | 1, 'ieee802_11_build_ap_params') | |
413 | ||
9cd6f4c0 | 414 | hostapd.add_bss(apdev[0], ifname1, 'bss-1.conf') |
f7af5a48 JM |
415 | |
416 | hapd_bss_out_of_mem(hapd2, 'phy3', 'bss-2.conf', | |
417 | 1, 'hostapd_interface_init_bss') | |
418 | hapd_bss_out_of_mem(hapd2, 'phy3', 'bss-2.conf', | |
419 | 1, 'ieee802_11_build_ap_params') | |
420 | ||
9cd6f4c0 | 421 | hostapd.add_bss(apdev[0], ifname2, 'bss-2.conf') |
c92ee957 JD |
422 | hostapd.remove_bss(apdev[0], ifname2) |
423 | hostapd.remove_bss(apdev[0], ifname1) | |
5d695df5 JM |
424 | |
425 | def test_ap_multi_bss(dev, apdev): | |
426 | """Multiple BSSes with hostapd""" | |
427 | ifname1 = apdev[0]['ifname'] | |
428 | ifname2 = apdev[0]['ifname'] + '-2' | |
5148b392 JD |
429 | hapd1 = hostapd.add_bss(apdev[0], ifname1, 'bss-1.conf') |
430 | hapd2 = hostapd.add_bss(apdev[0], ifname2, 'bss-2.conf') | |
5d695df5 JM |
431 | dev[0].connect("bss-1", key_mgmt="NONE", scan_freq="2412") |
432 | dev[1].connect("bss-2", key_mgmt="NONE", scan_freq="2412") | |
433 | ||
5d695df5 JM |
434 | hwsim_utils.test_connectivity(dev[0], hapd1) |
435 | hwsim_utils.test_connectivity(dev[1], hapd2) | |
436 | ||
437 | sta0 = hapd1.get_sta(dev[0].own_addr()) | |
438 | sta1 = hapd2.get_sta(dev[1].own_addr()) | |
439 | if 'rx_packets' not in sta0 or int(sta0['rx_packets']) < 1: | |
440 | raise Exception("sta0 did not report receiving packets") | |
441 | if 'rx_packets' not in sta1 or int(sta1['rx_packets']) < 1: | |
442 | raise Exception("sta1 did not report receiving packets") | |
08763216 | 443 | |
9fd6804d | 444 | @remote_compatible |
08763216 JM |
445 | def test_ap_add_with_driver(dev, apdev): |
446 | """Add hostapd interface with driver specified""" | |
447 | ifname = apdev[0]['ifname'] | |
c8ef2f6e JD |
448 | try: |
449 | hostname = apdev[0]['hostname'] | |
450 | except: | |
451 | hostname = None | |
452 | hapd_global = hostapd.HostapdGlobal(apdev[0]) | |
08763216 | 453 | hapd_global.add(ifname, driver="nl80211") |
c8ef2f6e JD |
454 | port = hapd_global.get_ctrl_iface_port(ifname) |
455 | hapd = hostapd.Hostapd(ifname, hostname, port) | |
08763216 JM |
456 | hapd.set_defaults() |
457 | hapd.set("ssid", "dynamic") | |
458 | hapd.enable() | |
459 | ev = hapd.wait_event(["AP-ENABLED"], timeout=30) | |
460 | if ev is None: | |
461 | raise Exception("AP startup timed out") | |
462 | dev[0].connect("dynamic", key_mgmt="NONE", scan_freq="2412") | |
463 | dev[0].request("DISCONNECT") | |
464 | dev[0].wait_disconnected() | |
465 | hapd.disable() | |
548d2801 JM |
466 | |
467 | def test_ap_iapp(dev, apdev): | |
468 | """IAPP and multiple BSSes""" | |
469 | require_under_vm() | |
470 | try: | |
471 | _test_ap_iapp(dev, apdev) | |
472 | finally: | |
473 | subprocess.call(['ifconfig', 'br-multicast', 'down'], | |
474 | stderr=open('/dev/null', 'w')) | |
475 | subprocess.call(['brctl', 'delbr', 'br-multicast'], | |
476 | stderr=open('/dev/null', 'w')) | |
477 | ||
478 | def _test_ap_iapp(dev, apdev): | |
479 | br_ifname = 'br-multicast' | |
480 | subprocess.call(['brctl', 'addbr', br_ifname]) | |
481 | subprocess.call(['brctl', 'setfd', br_ifname, '0']) | |
482 | subprocess.call(['ip', 'addr', 'add', '10.174.65.206/31', 'dev', br_ifname]) | |
483 | subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'up']) | |
484 | subprocess.call(['ip', 'route', 'add', '224.0.0.0/4', 'dev', br_ifname]) | |
485 | ||
486 | params = { "ssid": "test-1", | |
487 | "bridge": br_ifname, | |
488 | "iapp_interface": br_ifname } | |
489 | hapd = hostapd.add_ap(apdev[0], params) | |
490 | ||
491 | dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412) | |
492 | dev[0].connect("test-1", key_mgmt="NONE", scan_freq="2412") | |
493 | dev[1].connect("test-1", key_mgmt="NONE", scan_freq="2412") | |
494 | ||
495 | hapd2 = hostapd.add_ap(apdev[1], params) | |
496 | dev[0].scan_for_bss(apdev[1]['bssid'], freq=2412) | |
497 | dev[0].roam(apdev[1]['bssid']) | |
498 | dev[0].roam(apdev[0]['bssid']) | |
499 | ||
500 | dev[0].request("DISCONNECT") | |
501 | dev[1].request("DISCONNECT") | |
502 | dev[0].wait_disconnected() | |
503 | dev[1].wait_disconnected() | |
504 | ||
505 | hapd.disable() | |
506 | hapd2.disable() | |
209de576 JM |
507 | |
508 | def test_ap_duplicate_bssid(dev, apdev): | |
509 | """Duplicate BSSID""" | |
510 | params = { "ssid": "test" } | |
511 | hapd = hostapd.add_ap(apdev[0], params, no_enable=True) | |
512 | hapd.enable() | |
513 | ifname2 = apdev[0]['ifname'] + '-2' | |
514 | ifname3 = apdev[0]['ifname'] + '-3' | |
515 | # "BSS 'wlan3-2' may not have BSSID set to the MAC address of the radio" | |
516 | try: | |
517 | hostapd.add_bss(apdev[0], ifname2, 'bss-2-dup.conf') | |
518 | raise Exception("BSS add succeeded unexpectedly") | |
bab493b9 | 519 | except Exception as e: |
209de576 JM |
520 | if "Could not add hostapd BSS" in str(e): |
521 | pass | |
522 | else: | |
523 | raise | |
524 | ||
525 | hostapd.add_bss(apdev[0], ifname3, 'bss-3.conf') | |
526 | ||
527 | dev[0].connect("test", key_mgmt="NONE", scan_freq="2412") | |
528 | dev[0].request("DISCONNECT") | |
529 | dev[0].wait_disconnected() | |
530 | ||
531 | hapd.set("bssid", "02:00:00:00:03:02") | |
532 | hapd.disable() | |
533 | # "Duplicate BSSID 02:00:00:00:03:02 on interface 'wlan3-3' and 'wlan3'." | |
534 | if "FAIL" not in hapd.request("ENABLE"): | |
535 | raise Exception("ENABLE with duplicate BSSID succeeded unexpectedly") | |
3f9e6ca5 JM |
536 | |
537 | def test_ap_bss_config_file(dev, apdev, params): | |
538 | """hostapd BSS config file""" | |
539 | pidfile = os.path.join(params['logdir'], "ap_bss_config_file-hostapd.pid") | |
540 | logfile = os.path.join(params['logdir'], "ap_bss_config_file-hostapd-log") | |
541 | prg = os.path.join(params['logdir'], 'alt-hostapd/hostapd/hostapd') | |
542 | if not os.path.exists(prg): | |
543 | prg = '../../hostapd/hostapd' | |
544 | phy = get_phy(apdev[0]) | |
545 | cmd = [ prg, '-B', '-dddt', '-P', pidfile, '-f', logfile, '-S', '-T', | |
546 | '-b', phy + ':bss-1.conf', '-b', phy + ':bss-2.conf', | |
547 | '-b', phy + ':bss-3.conf' ] | |
548 | res = subprocess.check_call(cmd) | |
549 | if res != 0: | |
550 | raise Exception("Could not start hostapd: %s" % str(res)) | |
551 | multi_check(dev, [ True, True, True ]) | |
552 | for i in range(0, 3): | |
553 | dev[i].request("DISCONNECT") | |
554 | ||
555 | hapd = hostapd.Hostapd(apdev[0]['ifname']) | |
556 | hapd.ping() | |
557 | if "OK" not in hapd.request("TERMINATE"): | |
558 | raise Exception("Failed to terminate hostapd process") | |
df20cdc4 | 559 | ev = hapd.wait_event(["CTRL-EVENT-TERMINATING"], timeout=15) |
3f9e6ca5 JM |
560 | if ev is None: |
561 | raise Exception("CTRL-EVENT-TERMINATING not seen") | |
562 | for i in range(30): | |
563 | time.sleep(0.1) | |
564 | if not os.path.exists(pidfile): | |
565 | break | |
566 | if os.path.exists(pidfile): | |
567 | raise Exception("PID file exits after process termination") |