tests: Fix ap_{open,wpa2_psk}_wpas_in_bridge cleanup
[mech_eap.git] / tests / hwsim / test_ap_open.py
1 # Open mode AP tests
2 # Copyright (c) 2014, Qualcomm Atheros, Inc.
3 #
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
6
7 import logging
8 logger = logging.getLogger()
9 import struct
10 import subprocess
11 import time
12
13 import hostapd
14 import hwsim_utils
15 from utils import alloc_fail
16 from wpasupplicant import WpaSupplicant
17
18 def test_ap_open(dev, apdev):
19     """AP with open mode (no security) configuration"""
20     hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
21     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
22                    bg_scan_period="0")
23     ev = hapd.wait_event([ "AP-STA-CONNECTED" ], timeout=5)
24     if ev is None:
25         raise Exception("No connection event received from hostapd")
26     hwsim_utils.test_connectivity(dev[0], hapd)
27
28     dev[0].request("DISCONNECT")
29     ev = hapd.wait_event([ "AP-STA-DISCONNECTED" ], timeout=5)
30     if ev is None:
31         raise Exception("No disconnection event received from hostapd")
32
33 def test_ap_open_packet_loss(dev, apdev):
34     """AP with open mode configuration and large packet loss"""
35     params = { "ssid": "open",
36                "ignore_probe_probability": "0.5",
37                "ignore_auth_probability": "0.5",
38                "ignore_assoc_probability": "0.5",
39                "ignore_reassoc_probability": "0.5" }
40     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
41     for i in range(0, 3):
42         dev[i].connect("open", key_mgmt="NONE", scan_freq="2412",
43                        wait_connect=False)
44     for i in range(0, 3):
45         dev[i].wait_connected(timeout=20)
46
47 def test_ap_open_unknown_action(dev, apdev):
48     """AP with open mode configuration and unknown Action frame"""
49     hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
50     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
51     bssid = apdev[0]['bssid']
52     cmd = "MGMT_TX {} {} freq=2412 action=765432".format(bssid, bssid)
53     if "FAIL" in dev[0].request(cmd):
54         raise Exception("Could not send test Action frame")
55     ev = dev[0].wait_event(["MGMT-TX-STATUS"], timeout=10)
56     if ev is None:
57         raise Exception("Timeout on MGMT-TX-STATUS")
58     if "result=SUCCESS" not in ev:
59         raise Exception("AP did not ack Action frame")
60
61 def test_ap_open_reconnect_on_inactivity_disconnect(dev, apdev):
62     """Reconnect to open mode AP after inactivity related disconnection"""
63     hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
64     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
65     hapd.request("DEAUTHENTICATE " + dev[0].p2p_interface_addr() + " reason=4")
66     dev[0].wait_disconnected(timeout=5)
67     dev[0].wait_connected(timeout=2, error="Timeout on reconnection")
68
69 def test_ap_open_assoc_timeout(dev, apdev):
70     """AP timing out association"""
71     ssid = "test"
72     hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
73     dev[0].scan(freq="2412")
74     hapd.set("ext_mgmt_frame_handling", "1")
75     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
76                    wait_connect=False)
77     for i in range(0, 10):
78         req = hapd.mgmt_rx()
79         if req is None:
80             raise Exception("MGMT RX wait timed out")
81         if req['subtype'] == 11:
82             break
83         req = None
84     if not req:
85         raise Exception("Authentication frame not received")
86
87     resp = {}
88     resp['fc'] = req['fc']
89     resp['da'] = req['sa']
90     resp['sa'] = req['da']
91     resp['bssid'] = req['bssid']
92     resp['payload'] = struct.pack('<HHH', 0, 2, 0)
93     hapd.mgmt_tx(resp)
94
95     assoc = 0
96     for i in range(0, 10):
97         req = hapd.mgmt_rx()
98         if req is None:
99             raise Exception("MGMT RX wait timed out")
100         if req['subtype'] == 0:
101             assoc += 1
102             if assoc == 3:
103                 break
104     if assoc != 3:
105         raise Exception("Association Request frames not received: assoc=%d" % assoc)
106     hapd.set("ext_mgmt_frame_handling", "0")
107     dev[0].wait_connected(timeout=15)
108
109 def test_ap_open_id_str(dev, apdev):
110     """AP with open mode and id_str"""
111     hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
112     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412", id_str="foo",
113                    wait_connect=False)
114     ev = dev[0].wait_connected(timeout=10)
115     if "id_str=foo" not in ev:
116         raise Exception("CTRL-EVENT-CONNECT did not have matching id_str: " + ev)
117     if dev[0].get_status_field("id_str") != "foo":
118         raise Exception("id_str mismatch")
119
120 def test_ap_open_select_any(dev, apdev):
121     """AP with open mode and select any network"""
122     hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
123     id = dev[0].connect("unknown", key_mgmt="NONE", scan_freq="2412",
124                         only_add_network=True)
125     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
126                    only_add_network=True)
127     dev[0].select_network(id)
128     ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1)
129     if ev is not None:
130         raise Exception("Unexpected connection")
131
132     dev[0].select_network("any")
133     dev[0].wait_connected(timeout=10)
134
135 def test_ap_open_unexpected_assoc_event(dev, apdev):
136     """AP with open mode and unexpected association event"""
137     hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
138     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
139     dev[0].request("DISCONNECT")
140     dev[0].wait_disconnected(timeout=15)
141     dev[0].dump_monitor()
142     # This will be accepted due to matching network
143     subprocess.call(['iw', 'dev', dev[0].ifname, 'connect', 'open', "2412",
144                      apdev[0]['bssid']])
145     dev[0].wait_connected(timeout=15)
146     dev[0].dump_monitor()
147
148     dev[0].request("REMOVE_NETWORK all")
149     dev[0].wait_disconnected(timeout=5)
150     dev[0].dump_monitor()
151     # This will result in disconnection due to no matching network
152     subprocess.call(['iw', 'dev', dev[0].ifname, 'connect', 'open', "2412",
153                      apdev[0]['bssid']])
154     dev[0].wait_disconnected(timeout=15)
155
156 def test_ap_bss_load(dev, apdev):
157     """AP with open mode (no security) configuration"""
158     hapd = hostapd.add_ap(apdev[0]['ifname'],
159                           { "ssid": "open",
160                             "bss_load_update_period": "10" })
161     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
162     # this does not really get much useful output with mac80211_hwsim currently,
163     # but run through the channel survey update couple of times
164     for i in range(0, 10):
165         hwsim_utils.test_connectivity(dev[0], hapd)
166         hwsim_utils.test_connectivity(dev[0], hapd)
167         hwsim_utils.test_connectivity(dev[0], hapd)
168         time.sleep(0.15)
169
170 def hapd_out_of_mem(hapd, apdev, count, func):
171     with alloc_fail(hapd, count, func):
172         started = False
173         try:
174             hostapd.add_ap(apdev['ifname'], { "ssid": "open" })
175             started = True
176         except:
177             pass
178         if started:
179             raise Exception("hostapd interface started even with memory allocation failure: " + arg)
180
181 def test_ap_open_out_of_memory(dev, apdev):
182     """hostapd failing to setup interface due to allocation failure"""
183     hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
184     hapd_out_of_mem(hapd, apdev[1], 1, "hostapd_alloc_bss_data")
185
186     for i in range(1, 3):
187         hapd_out_of_mem(hapd, apdev[1], i, "hostapd_iface_alloc")
188
189     for i in range(1, 5):
190         hapd_out_of_mem(hapd, apdev[1], i, "hostapd_config_defaults;hostapd_config_alloc")
191
192     hapd_out_of_mem(hapd, apdev[1], 1, "hostapd_config_alloc")
193
194     hapd_out_of_mem(hapd, apdev[1], 1, "hostapd_driver_init")
195
196     for i in range(1, 4):
197         hapd_out_of_mem(hapd, apdev[1], i, "=wpa_driver_nl80211_drv_init")
198
199     # eloop_register_read_sock() call from i802_init()
200     hapd_out_of_mem(hapd, apdev[1], 1, "eloop_sock_table_add_sock;eloop_register_sock;?eloop_register_read_sock;=i802_init")
201
202     # verify that a new interface can still be added when memory allocation does
203     # not fail
204     hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open" })
205
206 def test_bssid_black_white_list(dev, apdev):
207     """BSSID black/white list"""
208     hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
209     hapd2 = hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open" })
210
211     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
212                    bssid_whitelist=apdev[1]['bssid'])
213     dev[1].connect("open", key_mgmt="NONE", scan_freq="2412",
214                    bssid_blacklist=apdev[1]['bssid'])
215     dev[2].connect("open", key_mgmt="NONE", scan_freq="2412",
216                    bssid_whitelist="00:00:00:00:00:00/00:00:00:00:00:00",
217                    bssid_blacklist=apdev[1]['bssid'])
218     if dev[0].get_status_field('bssid') != apdev[1]['bssid']:
219         raise Exception("dev[0] connected to unexpected AP")
220     if dev[1].get_status_field('bssid') != apdev[0]['bssid']:
221         raise Exception("dev[1] connected to unexpected AP")
222     if dev[2].get_status_field('bssid') != apdev[0]['bssid']:
223         raise Exception("dev[2] connected to unexpected AP")
224     dev[0].request("REMOVE_NETWORK all")
225     dev[1].request("REMOVE_NETWORK all")
226     dev[2].request("REMOVE_NETWORK all")
227
228     dev[2].connect("open", key_mgmt="NONE", scan_freq="2412",
229                    bssid_whitelist="00:00:00:00:00:00", wait_connect=False)
230     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412",
231                    bssid_whitelist="11:22:33:44:55:66/ff:00:00:00:00:00 " + apdev[1]['bssid'] + " aa:bb:cc:dd:ee:ff")
232     dev[1].connect("open", key_mgmt="NONE", scan_freq="2412",
233                    bssid_blacklist="11:22:33:44:55:66/ff:00:00:00:00:00 " + apdev[1]['bssid'] + " aa:bb:cc:dd:ee:ff")
234     if dev[0].get_status_field('bssid') != apdev[1]['bssid']:
235         raise Exception("dev[0] connected to unexpected AP")
236     if dev[1].get_status_field('bssid') != apdev[0]['bssid']:
237         raise Exception("dev[1] connected to unexpected AP")
238     dev[0].request("REMOVE_NETWORK all")
239     dev[1].request("REMOVE_NETWORK all")
240     ev = dev[2].wait_event(["CTRL-EVENT-CONNECTED"], timeout=0.1)
241     if ev is not None:
242         raise Exception("Unexpected dev[2] connectin")
243     dev[2].request("REMOVE_NETWORK all")
244
245 def test_ap_open_wpas_in_bridge(dev, apdev):
246     """Open mode AP and wpas interface in a bridge"""
247     br_ifname='sta-br0'
248     ifname='wlan5'
249     try:
250         _test_ap_open_wpas_in_bridge(dev, apdev)
251     finally:
252         subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'down'])
253         subprocess.call(['brctl', 'delif', br_ifname, ifname])
254         subprocess.call(['brctl', 'delbr', br_ifname])
255         subprocess.call(['iw', ifname, 'set', '4addr', 'off'])
256
257 def _test_ap_open_wpas_in_bridge(dev, apdev):
258     hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open" })
259
260     br_ifname='sta-br0'
261     ifname='wlan5'
262     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
263     # First, try a failure case of adding an interface
264     try:
265         wpas.interface_add(ifname, br_ifname=br_ifname)
266         raise Exception("Interface addition succeeded unexpectedly")
267     except Exception, e:
268         if "Failed to add" in str(e):
269             logger.info("Ignore expected interface_add failure due to missing bridge interface: " + str(e))
270         else:
271             raise
272
273     # Next, add the bridge interface and add the interface again
274     subprocess.call(['brctl', 'addbr', br_ifname])
275     subprocess.call(['brctl', 'setfd', br_ifname, '0'])
276     subprocess.call(['ip', 'link', 'set', 'dev', br_ifname, 'up'])
277     subprocess.call(['iw', ifname, 'set', '4addr', 'on'])
278     subprocess.check_call(['brctl', 'addif', br_ifname, ifname])
279     wpas.interface_add(ifname, br_ifname=br_ifname)
280
281     wpas.connect("open", key_mgmt="NONE", scan_freq="2412")
282
283 def test_ap_open_start_disabled(dev, apdev):
284     """AP with open mode and beaconing disabled"""
285     hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open",
286                                                 "start_disabled": "1" })
287     bssid = apdev[0]['bssid']
288
289     dev[0].flush_scan_cache()
290     dev[0].scan(freq=2412, only_new=True)
291     if dev[0].get_bss(bssid) is not None:
292         raise Exception("AP was seen beaconing")
293     if "OK" not in hapd.request("RELOAD"):
294         raise Exception("RELOAD failed")
295     dev[0].scan_for_bss(bssid, freq=2412)
296     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
297
298 def test_ap_open_start_disabled2(dev, apdev):
299     """AP with open mode and beaconing disabled (2)"""
300     hapd = hostapd.add_ap(apdev[0]['ifname'], { "ssid": "open",
301                                                 "start_disabled": "1" })
302     bssid = apdev[0]['bssid']
303
304     dev[0].flush_scan_cache()
305     dev[0].scan(freq=2412, only_new=True)
306     if dev[0].get_bss(bssid) is not None:
307         raise Exception("AP was seen beaconing")
308     if "OK" not in hapd.request("UPDATE_BEACON"):
309         raise Exception("UPDATE_BEACON failed")
310     dev[0].scan_for_bss(bssid, freq=2412)
311     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
312     if "OK" not in hapd.request("UPDATE_BEACON"):
313         raise Exception("UPDATE_BEACON failed")
314     dev[0].request("DISCONNECT")
315     dev[0].wait_disconnected()
316     dev[0].request("RECONNECT")
317     dev[0].wait_connected()
318
319 def test_ap_open_ifdown(dev, apdev):
320     """AP with open mode and external ifconfig down"""
321     params = { "ssid": "open",
322                "ap_max_inactivity": "1" }
323     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
324     bssid = apdev[0]['bssid']
325
326     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
327     dev[1].connect("open", key_mgmt="NONE", scan_freq="2412")
328     subprocess.call(['ip', 'link', 'set', 'dev', apdev[0]['ifname'], 'down'])
329     ev = hapd.wait_event(["AP-STA-DISCONNECTED"], timeout=10)
330     if ev is None:
331         raise Exception("Timeout on AP-STA-DISCONNECTED (1)")
332     ev = hapd.wait_event(["AP-STA-DISCONNECTED"], timeout=5)
333     if ev is None:
334         raise Exception("Timeout on AP-STA-DISCONNECTED (2)")
335     ev = hapd.wait_event(["INTERFACE-DISABLED"], timeout=5)
336     if ev is None:
337         raise Exception("No INTERFACE-DISABLED event")
338     # The following wait tests beacon loss detection in mac80211 on dev0.
339     # dev1 is used to test stopping of AP side functionality on client polling.
340     dev[1].request("REMOVE_NETWORK all")
341     subprocess.call(['ip', 'link', 'set', 'dev', apdev[0]['ifname'], 'up'])
342     dev[0].wait_disconnected()
343     dev[1].wait_disconnected()
344     ev = hapd.wait_event(["INTERFACE-ENABLED"], timeout=10)
345     if ev is None:
346         raise Exception("No INTERFACE-ENABLED event")
347     dev[0].wait_connected()
348     hwsim_utils.test_connectivity(dev[0], hapd)