]> git.ipfire.org Git - thirdparty/hostap.git/blame - tests/hwsim/test_macsec.py
tests: Fix status fetching loop in macsec_psk_ns with UML
[thirdparty/hostap.git] / tests / hwsim / test_macsec.py
CommitLineData
ead573d8 1# Test cases for MACsec/MKA
b21540e6 2# Copyright (c) 2018-2019, Jouni Malinen <j@w1.fi>
ead573d8
JM
3#
4# This software may be distributed under the terms of the BSD license.
5# See README for more details.
6
7import logging
8logger = logging.getLogger()
e1810300 9import binascii
ead573d8
JM
10import os
11import signal
12import subprocess
13import time
14
15from wpasupplicant import WpaSupplicant
16import hwsim_utils
344929a9 17from utils import HwsimSkip, alloc_fail, fail_test, wait_fail_trigger
ead573d8
JM
18
19def cleanup_macsec():
b21540e6 20 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5', monitor=False)
ead573d8
JM
21 wpas.interface_remove("veth0")
22 wpas.interface_remove("veth1")
b21540e6 23 del wpas
ead573d8
JM
24 subprocess.call(["ip", "link", "del", "veth0"],
25 stderr=open('/dev/null', 'w'))
26
27def test_macsec_psk(dev, apdev, params):
28 """MACsec PSK"""
29 try:
30 run_macsec_psk(dev, apdev, params, "macsec_psk")
31 finally:
32 cleanup_macsec()
33
34def test_macsec_psk_mka_life_time(dev, apdev, params):
35 """MACsec PSK - MKA life time"""
36 try:
37 run_macsec_psk(dev, apdev, params, "macsec_psk_mka_life_time")
b21540e6 38 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5', monitor=False)
ead573d8 39 wpas.interface_remove("veth1")
b21540e6 40 del wpas
ead573d8
JM
41 # Wait for live peer to be removed on veth0
42 time.sleep(6.1)
43 finally:
44 cleanup_macsec()
45
46def test_macsec_psk_integ_only(dev, apdev, params):
47 """MACsec PSK (integrity only)"""
48 try:
49 run_macsec_psk(dev, apdev, params, "macsec_psk_integ_only",
50 integ_only=True)
51 finally:
52 cleanup_macsec()
53
54def test_macsec_psk_port(dev, apdev, params):
55 """MACsec PSK (port)"""
56 try:
57 run_macsec_psk(dev, apdev, params, "macsec_psk_port",
58 port0=65534, port1=65534)
59 finally:
60 cleanup_macsec()
61
62def test_macsec_psk_different_ports(dev, apdev, params):
63 """MACsec PSK (different ports)"""
64 try:
65 run_macsec_psk(dev, apdev, params, "macsec_psk_different_ports",
66 port0=2, port1=3)
67 finally:
68 cleanup_macsec()
69
70def test_macsec_psk_shorter_ckn(dev, apdev, params):
71 """MACsec PSK (shorter CKN)"""
72 try:
73 ckn = "11223344"
74 run_macsec_psk(dev, apdev, params, "macsec_psk_shorter_ckn",
75 ckn0=ckn, ckn1=ckn)
76 finally:
77 cleanup_macsec()
78
79def test_macsec_psk_shorter_ckn2(dev, apdev, params):
80 """MACsec PSK (shorter CKN, unaligned)"""
81 try:
82 ckn = "112233"
83 run_macsec_psk(dev, apdev, params, "macsec_psk_shorter_ckn2",
84 ckn0=ckn, ckn1=ckn)
85 finally:
86 cleanup_macsec()
87
88def test_macsec_psk_ckn_mismatch(dev, apdev, params):
89 """MACsec PSK (CKN mismatch)"""
90 try:
91 ckn0 = "11223344"
92 ckn1 = "1122334455667788"
93 run_macsec_psk(dev, apdev, params, "macsec_psk_ckn_mismatch",
94 ckn0=ckn0, ckn1=ckn1, expect_failure=True)
95 finally:
96 cleanup_macsec()
97
98def test_macsec_psk_cak_mismatch(dev, apdev, params):
99 """MACsec PSK (CAK mismatch)"""
100 try:
101 cak0 = 16*"11"
102 cak1 = 16*"22"
103 run_macsec_psk(dev, apdev, params, "macsec_psk_cak_mismatch",
104 cak0=cak0, cak1=cak1, expect_failure=True)
105 finally:
106 cleanup_macsec()
107
108def test_macsec_psk_256(dev, apdev, params):
109 """MACsec PSK with 256-bit keys"""
110 try:
111 cak = "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f"
112 run_macsec_psk(dev, apdev, params, "macsec_psk_256", cak0=cak, cak1=cak)
113 finally:
114 cleanup_macsec()
115
116def set_mka_psk_config(dev, mka_priority=None, integ_only=False, port=None,
117 ckn=None, cak=None):
118 dev.set("eapol_version", "3")
119 dev.set("ap_scan", "0")
120 dev.set("fast_reauth", "1")
121
122 id = dev.add_network()
123 dev.set_network(id, "key_mgmt", "NONE")
124 if cak is None:
125 cak = "000102030405060708090a0b0c0d0e0f"
126 dev.set_network(id, "mka_cak", cak)
127 if ckn is None:
128 ckn = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"
129 dev.set_network(id, "mka_ckn", ckn)
130 dev.set_network(id, "eapol_flags", "0")
131 dev.set_network(id, "macsec_policy", "1")
132 if integ_only:
133 dev.set_network(id, "macsec_integ_only", "1")
134 if mka_priority is not None:
135 dev.set_network(id, "mka_priority", str(mka_priority))
136 if port is not None:
137 dev.set_network(id, "macsec_port", str(port))
138
139 dev.select_network(id)
140
141def log_ip_macsec():
fab49f61 142 cmd = subprocess.Popen(["ip", "macsec", "show"],
ead573d8
JM
143 stdout=subprocess.PIPE,
144 stderr=open('/dev/null', 'w'))
1c48c9bc 145 res = cmd.stdout.read().decode()
ead573d8
JM
146 cmd.stdout.close()
147 logger.info("ip macsec:\n" + res)
148
149def log_ip_link():
fab49f61 150 cmd = subprocess.Popen(["ip", "link", "show"],
ead573d8 151 stdout=subprocess.PIPE)
1c48c9bc 152 res = cmd.stdout.read().decode()
ead573d8
JM
153 cmd.stdout.close()
154 logger.info("ip link:\n" + res)
155
344929a9 156def add_veth():
ead573d8 157 try:
fab49f61
JM
158 subprocess.check_call(["ip", "link", "add", "veth0", "type", "veth",
159 "peer", "name", "veth1"])
ead573d8
JM
160 except subprocess.CalledProcessError:
161 raise HwsimSkip("veth not supported (kernel CONFIG_VETH)")
162
344929a9
JM
163def add_wpas_interfaces(count=2):
164 wpa = []
165 try:
166 for i in range(count):
167 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
168 wpas.interface_add("veth%d" % i, driver="macsec_linux")
169 wpa.append(wpas)
bab493b9 170 except Exception as e:
344929a9 171 if "Failed to add a dynamic wpa_supplicant interface" in str(e):
3281c159 172 raise HwsimSkip("macsec supported (wpa_supplicant CONFIG_MACSEC, CONFIG_DRIVER_MACSEC_LINUX; kernel CONFIG_MACSEC)")
344929a9
JM
173 raise
174
175 return wpa
176
0d09bd08
JM
177def lower_addr(addr1, addr2):
178 a1 = addr1.split(':')
179 a2 = addr2.split(':')
180 for i in range(6):
e1810300 181 if binascii.unhexlify(a1[i]) < binascii.unhexlify(a2[i]):
0d09bd08 182 return True
e1810300 183 if binascii.unhexlify(a1[i]) > binascii.unhexlify(a2[i]):
0d09bd08
JM
184 return False
185 return False
186
187def wait_mka_done(wpa, expect_failure=False):
344929a9
JM
188 max_iter = 14 if expect_failure else 40
189 for i in range(max_iter):
0d09bd08
JM
190 done = True
191 for w in wpa:
192 secured = w.get_status_field("Secured")
193 peers = int(w.get_status_field("live_peers"))
194 if expect_failure and (secured == "Yes" or peers > 0):
195 raise Exception("MKA completed unexpectedly")
196 if peers != len(wpa) - 1 or secured != "Yes":
197 done = False
198 break
199 w.dump_monitor()
200 if done:
201 break
344929a9
JM
202 time.sleep(0.5)
203
204 if expect_failure:
344929a9
JM
205 return
206
0d09bd08
JM
207 if not done:
208 raise Exception("MKA not completed successfully")
209
210 key_server = None
211 ks_prio = 999
212 for w in wpa:
213 logger.info("%s STATUS:\n%s" % (w.ifname, w.request("STATUS")))
214 addr = w.get_status_field("address")
215 prio = int(w.get_status_field("Actor Priority"))
216 if key_server is None or prio < ks_prio or \
217 (prio == ks_prio and lower_addr(addr, ks_addr)):
218 key_server = w
219 ks_addr = addr
220 ks_prio = prio
221
222 logger.info("Expected key server: " + key_server.ifname)
223 if key_server.get_status_field("is_key_server") != "Yes":
224 raise Exception("Expected key server was not elected")
225 for w in wpa:
226 if w != key_server and w.get_status_field("is_key_server") == "Yes":
227 raise Exception("Unexpected key server")
344929a9
JM
228
229def run_macsec_psk(dev, apdev, params, prefix, integ_only=False, port0=None,
230 port1=None, ckn0=None, ckn1=None, cak0=None, cak1=None,
231 expect_failure=False):
232 add_veth()
233
ead573d8
JM
234 cap_veth0 = os.path.join(params['logdir'], prefix + ".veth0.pcap")
235 cap_veth1 = os.path.join(params['logdir'], prefix + ".veth1.pcap")
236 cap_macsec0 = os.path.join(params['logdir'], prefix + ".macsec0.pcap")
237 cap_macsec1 = os.path.join(params['logdir'], prefix + ".macsec1.pcap")
238
239 for i in range(2):
fab49f61 240 subprocess.check_call(["ip", "link", "set", "dev", "veth%d" % i, "up"])
ead573d8
JM
241
242 cmd = {}
243 cmd[0] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', 'veth0',
244 '-w', cap_veth0, '-s', '2000',
245 '--immediate-mode'],
246 stderr=open('/dev/null', 'w'))
247 cmd[1] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', 'veth1',
248 '-w', cap_veth1, '-s', '2000',
249 '--immediate-mode'],
250 stderr=open('/dev/null', 'w'))
251
344929a9
JM
252 wpa = add_wpas_interfaces()
253 wpas0 = wpa[0]
254 wpas1 = wpa[1]
ead573d8
JM
255
256 set_mka_psk_config(wpas0, integ_only=integ_only, port=port0, ckn=ckn0,
257 cak=cak0)
258 set_mka_psk_config(wpas1, mka_priority=100, integ_only=integ_only,
259 port=port1, ckn=ckn1, cak=cak1)
260
261 log_ip_macsec()
262 log_ip_link()
263
264 logger.info("wpas0 STATUS:\n" + wpas0.request("STATUS"))
265 logger.info("wpas1 STATUS:\n" + wpas1.request("STATUS"))
266 logger.info("wpas0 STATUS-DRIVER:\n" + wpas0.request("STATUS-DRIVER"))
267 logger.info("wpas1 STATUS-DRIVER:\n" + wpas1.request("STATUS-DRIVER"))
268 macsec_ifname0 = wpas0.get_driver_status_field("parent_ifname")
269 macsec_ifname1 = wpas1.get_driver_status_field("parent_ifname")
270
0d09bd08 271 wait_mka_done(wpa, expect_failure=expect_failure)
ead573d8
JM
272
273 if expect_failure:
ead573d8
JM
274 for i in range(len(cmd)):
275 cmd[i].terminate()
276 return
277
278 cmd[2] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', macsec_ifname0,
279 '-w', cap_macsec0, '-s', '2000',
280 '--immediate-mode'],
281 stderr=open('/dev/null', 'w'))
282 cmd[3] = subprocess.Popen(['tcpdump', '-p', '-U', '-i', macsec_ifname1,
283 '-w', cap_macsec1, '-s', '2000',
284 '--immediate-mode'],
285 stderr=open('/dev/null', 'w'))
286 time.sleep(0.5)
287
90eb910e
JM
288 mi0 = wpas0.get_status_field("mi")
289 mi1 = wpas1.get_status_field("mi")
290 sci0 = wpas0.get_status_field("actor_sci")
291 sci1 = wpas1.get_status_field("actor_sci")
292 logger.info("wpas0 MIB:\n" + wpas0.request("MIB"))
293 logger.info("wpas1 MIB:\n" + wpas1.request("MIB"))
294 mib0 = wpas0.get_mib()
295 mib1 = wpas1.get_mib()
296
297 if mib0['ieee8021XKayMkaPeerListMI'] != mi1:
298 raise Exception("Unexpected ieee8021XKayMkaPeerListMI value (0)")
299 if mib0['ieee8021XKayMkaPeerListType'] != "1":
300 raise Exception("Unexpected ieee8021XKayMkaPeerListType value (0)")
301 if mib0['ieee8021XKayMkaPeerListSCI'] != sci1:
302 raise Exception("Unexpected ieee8021XKayMkaPeerListSCI value (0)")
303 if mib1['ieee8021XKayMkaPeerListMI'] != mi0:
304 raise Exception("Unexpected ieee8021XKayMkaPeerListMI value (1)")
305 if mib1['ieee8021XKayMkaPeerListType'] != "1":
306 raise Exception("Unexpected ieee8021XKayMkaPeerListType value (1)")
307 if mib1['ieee8021XKayMkaPeerListSCI'] != sci0:
308 raise Exception("Unexpected ieee8021XKayMkaPeerListSCI value (1)")
309
ead573d8
JM
310 logger.info("wpas0 STATUS:\n" + wpas0.request("STATUS"))
311 logger.info("wpas1 STATUS:\n" + wpas1.request("STATUS"))
312 log_ip_macsec()
313 hwsim_utils.test_connectivity(wpas0, wpas1,
314 ifname1=macsec_ifname0,
315 ifname2=macsec_ifname1,
316 send_len=1400)
317 log_ip_macsec()
318
319 time.sleep(1)
320 for i in range(len(cmd)):
321 cmd[i].terminate()
322
a2acadf6 323def cleanup_macsec_br(count):
b21540e6 324 wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5', monitor=False)
a2acadf6
JM
325 for i in range(count):
326 wpas.interface_remove("veth%d" % i)
327 subprocess.call(["ip", "link", "del", "veth%d" % i],
328 stderr=open('/dev/null', 'w'))
fe5400dd 329 del wpas
a2acadf6
JM
330 subprocess.call(["ip", "link", "set", "brveth", "down"])
331 subprocess.call(["brctl", "delbr", "brveth"])
332
333def test_macsec_psk_br2(dev, apdev):
334 """MACsec PSK (bridge; 2 devices)"""
335 try:
336 run_macsec_psk_br(dev, apdev, 2, [10, 20])
337 finally:
338 cleanup_macsec_br(count=2)
339
340def test_macsec_psk_br2_same_prio(dev, apdev):
341 """MACsec PSK (bridge; 2 devices, same mka_priority)"""
342 try:
343 run_macsec_psk_br(dev, apdev, 2, [None, None])
344 finally:
345 cleanup_macsec_br(count=2)
346
347def test_macsec_psk_br3(dev, apdev):
348 """MACsec PSK (bridge; 3 devices)"""
349 try:
350 run_macsec_psk_br(dev, apdev, 3, [10, 20, 30])
351 finally:
352 cleanup_macsec_br(count=3)
353
354def test_macsec_psk_br3_same_prio(dev, apdev):
355 """MACsec PSK (bridge; 3 devices, same mka_priority)"""
356 try:
357 run_macsec_psk_br(dev, apdev, 3, [None, None, None])
358 finally:
359 cleanup_macsec_br(count=3)
360
361def run_macsec_psk_br(dev, apdev, count, mka_priority):
362 subprocess.check_call(["brctl", "addbr", "brveth"])
363 subprocess.call(["echo 8 > /sys/devices/virtual/net/brveth/bridge/group_fwd_mask"],
364 shell=True)
365
366 try:
367 for i in range(count):
fab49f61
JM
368 subprocess.check_call(["ip", "link", "add", "veth%d" % i,
369 "type", "veth",
370 "peer", "name", "vethbr%d" % i])
a2acadf6 371 subprocess.check_call(["ip", "link", "set", "vethbr%d" % i, "up"])
fab49f61
JM
372 subprocess.check_call(["brctl", "addif", "brveth",
373 "vethbr%d" % i])
a2acadf6
JM
374 except subprocess.CalledProcessError:
375 raise HwsimSkip("veth not supported (kernel CONFIG_VETH)")
376
377 subprocess.check_call(["ip", "link", "set", "brveth", "up"])
378
379 log_ip_link()
380
381 wpa = add_wpas_interfaces(count=count)
382 for i in range(count):
383 set_mka_psk_config(wpa[i], mka_priority=mka_priority[i])
384 wpa[i].dump_monitor()
385 wait_mka_done(wpa)
386
387 macsec_ifname = []
388 for i in range(count):
389 macsec_ifname.append(wpa[i].get_driver_status_field("parent_ifname"))
390
391 timeout = 2
392 max_tries = 2 if count > 2 else 1
393 success_seen = False
394 failure_seen = False
395 for i in range(1, count):
396 try:
397 hwsim_utils.test_connectivity(wpa[0], wpa[i],
398 ifname1=macsec_ifname[0],
399 ifname2=macsec_ifname[i],
400 send_len=1400,
401 timeout=timeout, max_tries=max_tries)
402 success_seen = True
403 logger.info("Traffic test %d<->%d success" % (0, i))
404 except:
405 failure_seen = True
406 logger.info("Traffic test %d<->%d failure" % (0, i))
407 for i in range(2, count):
408 try:
409 hwsim_utils.test_connectivity(wpa[1], wpa[i],
410 ifname1=macsec_ifname[1],
411 ifname2=macsec_ifname[i],
412 send_len=1400,
413 timeout=timeout, max_tries=max_tries)
414 success_seen = True
415 logger.info("Traffic test %d<->%d success" % (1, i))
416 except:
417 failure_seen = True
418 logger.info("Traffic test %d<->%d failure" % (1, i))
419
420 if not success_seen:
421 raise Exception("None of the data traffic tests succeeded")
422
423 # Something seems to be failing with three device tests semi-regularly, so
424 # do not report this as a failed test case until the real reason behind
425 # those failures have been determined.
426 if failure_seen:
427 if count < 3:
428 raise Exception("Data traffic test failed")
429 else:
430 logger.info("Data traffic test failed - ignore for now for >= 3 device cases")
431
fe5400dd 432 for i in range(count):
b21540e6 433 wpa[i].close_monitor()
fe5400dd 434 for i in range(count):
b21540e6 435 wpa[0].close_control()
fe5400dd
JM
436 del wpa[0]
437
ead573d8
JM
438def test_macsec_psk_ns(dev, apdev, params):
439 """MACsec PSK (netns)"""
440 try:
441 run_macsec_psk_ns(dev, apdev, params)
442 finally:
443 prefix = "macsec_psk_ns"
444 pidfile = os.path.join(params['logdir'], prefix + ".pid")
445 for i in range(2):
446 was_running = False
447 if os.path.exists(pidfile + str(i)):
448 with open(pidfile + str(i), 'r') as f:
449 pid = int(f.read().strip())
450 logger.info("wpa_supplicant for wpas%d still running with pid %d - kill it" % (i, pid))
451 was_running = True
452 os.kill(pid, signal.SIGTERM)
453 if was_running:
454 time.sleep(1)
455
456 subprocess.call(["ip", "netns", "exec", "ns0",
457 "ip", "link", "del", "veth0"],
458 stderr=open('/dev/null', 'w'))
459 subprocess.call(["ip", "link", "del", "veth0"],
460 stderr=open('/dev/null', 'w'))
461 log_ip_link_ns()
462 subprocess.call(["ip", "netns", "delete", "ns0"],
463 stderr=open('/dev/null', 'w'))
464 subprocess.call(["ip", "netns", "delete", "ns1"],
465 stderr=open('/dev/null', 'w'))
466
467def log_ip_macsec_ns():
fab49f61 468 cmd = subprocess.Popen(["ip", "macsec", "show"],
ead573d8
JM
469 stdout=subprocess.PIPE,
470 stderr=open('/dev/null', 'w'))
1c48c9bc 471 res = cmd.stdout.read().decode()
ead573d8
JM
472 cmd.stdout.close()
473 logger.info("ip macsec show:\n" + res)
474
fab49f61
JM
475 cmd = subprocess.Popen(["ip", "netns", "exec", "ns0",
476 "ip", "macsec", "show"],
ead573d8
JM
477 stdout=subprocess.PIPE,
478 stderr=open('/dev/null', 'w'))
1c48c9bc 479 res = cmd.stdout.read().decode()
ead573d8
JM
480 cmd.stdout.close()
481 logger.info("ip macsec show (ns0):\n" + res)
482
fab49f61
JM
483 cmd = subprocess.Popen(["ip", "netns", "exec", "ns1",
484 "ip", "macsec", "show"],
ead573d8
JM
485 stdout=subprocess.PIPE,
486 stderr=open('/dev/null', 'w'))
1c48c9bc 487 res = cmd.stdout.read().decode()
ead573d8
JM
488 cmd.stdout.close()
489 logger.info("ip macsec show (ns1):\n" + res)
490
491def log_ip_link_ns():
fab49f61 492 cmd = subprocess.Popen(["ip", "link", "show"],
ead573d8 493 stdout=subprocess.PIPE)
1c48c9bc 494 res = cmd.stdout.read().decode()
ead573d8
JM
495 cmd.stdout.close()
496 logger.info("ip link:\n" + res)
497
fab49f61
JM
498 cmd = subprocess.Popen(["ip", "netns", "exec", "ns0",
499 "ip", "link", "show"],
ead573d8
JM
500 stdout=subprocess.PIPE,
501 stderr=open('/dev/null', 'w'))
1c48c9bc 502 res = cmd.stdout.read().decode()
ead573d8
JM
503 cmd.stdout.close()
504 logger.info("ip link show (ns0):\n" + res)
505
fab49f61
JM
506 cmd = subprocess.Popen(["ip", "netns", "exec", "ns1",
507 "ip", "link", "show"],
ead573d8
JM
508 stdout=subprocess.PIPE,
509 stderr=open('/dev/null', 'w'))
1c48c9bc 510 res = cmd.stdout.read().decode()
ead573d8
JM
511 cmd.stdout.close()
512 logger.info("ip link show (ns1):\n" + res)
513
514def write_conf(conffile, mka_priority=None):
515 with open(conffile, 'w') as f:
516 f.write("ctrl_interface=DIR=/var/run/wpa_supplicant\n")
517 f.write("eapol_version=3\n")
518 f.write("ap_scan=0\n")
519 f.write("fast_reauth=1\n")
520 f.write("network={\n")
26b0c290
MH
521 f.write(" key_mgmt=NONE\n")
522 f.write(" mka_cak=000102030405060708090a0b0c0d0e0f\n")
523 f.write(" mka_ckn=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f\n")
ead573d8
JM
524 if mka_priority is not None:
525 f.write(" mka_priority=%d\n" % mka_priority)
26b0c290
MH
526 f.write(" eapol_flags=0\n")
527 f.write(" macsec_policy=1\n")
ead573d8
JM
528 f.write("}\n")
529
530def run_macsec_psk_ns(dev, apdev, params):
531 try:
fab49f61
JM
532 subprocess.check_call(["ip", "link", "add", "veth0", "type", "veth",
533 "peer", "name", "veth1"])
ead573d8
JM
534 except subprocess.CalledProcessError:
535 raise HwsimSkip("veth not supported (kernel CONFIG_VETH)")
536
537 prefix = "macsec_psk_ns"
538 conffile = os.path.join(params['logdir'], prefix + ".conf")
539 pidfile = os.path.join(params['logdir'], prefix + ".pid")
540 logfile0 = os.path.join(params['logdir'], prefix + ".veth0.log")
541 logfile1 = os.path.join(params['logdir'], prefix + ".veth1.log")
542 cap_veth0 = os.path.join(params['logdir'], prefix + ".veth0.pcap")
543 cap_veth1 = os.path.join(params['logdir'], prefix + ".veth1.pcap")
544 cap_macsec0 = os.path.join(params['logdir'], prefix + ".macsec0.pcap")
545 cap_macsec1 = os.path.join(params['logdir'], prefix + ".macsec1.pcap")
546
547 for i in range(2):
548 try:
fab49f61 549 subprocess.check_call(["ip", "netns", "add", "ns%d" % i])
ead573d8
JM
550 except subprocess.CalledProcessError:
551 raise HwsimSkip("network namespace not supported (kernel CONFIG_NAMESPACES, CONFIG_NET_NS)")
fab49f61
JM
552 subprocess.check_call(["ip", "link", "set", "veth%d" % i,
553 "netns", "ns%d" %i])
554 subprocess.check_call(["ip", "netns", "exec", "ns%d" % i,
555 "ip", "link", "set", "dev", "veth%d" % i,
556 "up"])
ead573d8
JM
557
558 cmd = {}
559 cmd[0] = subprocess.Popen(['ip', 'netns', 'exec', 'ns0',
560 'tcpdump', '-p', '-U', '-i', 'veth0',
561 '-w', cap_veth0, '-s', '2000',
562 '--immediate-mode'],
563 stderr=open('/dev/null', 'w'))
564 cmd[1] = subprocess.Popen(['ip', 'netns', 'exec', 'ns1',
565 'tcpdump', '-p', '-U', '-i', 'veth1',
566 '-w', cap_veth1, '-s', '2000',
567 '--immediate-mode'],
568 stderr=open('/dev/null', 'w'))
569
570 write_conf(conffile + '0')
571 write_conf(conffile + '1', mka_priority=100)
572
573 prg = os.path.join(params['logdir'],
574 'alt-wpa_supplicant/wpa_supplicant/wpa_supplicant')
575 if not os.path.exists(prg):
576 prg = '../../wpa_supplicant/wpa_supplicant'
577
fab49f61
JM
578 arg = ["ip", "netns", "exec", "ns0",
579 prg, '-BdddtKW', '-P', pidfile + '0', '-f', logfile0,
580 '-g', '/tmp/wpas-veth0',
581 '-Dmacsec_linux', '-c', conffile + '0', '-i', "veth0"]
ead573d8
JM
582 logger.info("Start wpa_supplicant: " + str(arg))
583 try:
584 subprocess.check_call(arg)
585 except subprocess.CalledProcessError:
3281c159 586 raise HwsimSkip("macsec supported (wpa_supplicant CONFIG_MACSEC, CONFIG_DRIVER_MACSEC_LINUX; kernel CONFIG_MACSEC)")
ead573d8
JM
587
588 if os.path.exists("wpa_supplicant-macsec2"):
589 logger.info("Use alternative wpa_supplicant binary for one of the macsec devices")
590 prg = "wpa_supplicant-macsec2"
591
fab49f61
JM
592 arg = ["ip", "netns", "exec", "ns1",
593 prg, '-BdddtKW', '-P', pidfile + '1', '-f', logfile1,
594 '-g', '/tmp/wpas-veth1',
595 '-Dmacsec_linux', '-c', conffile + '1', '-i', "veth1"]
ead573d8
JM
596 logger.info("Start wpa_supplicant: " + str(arg))
597 subprocess.check_call(arg)
598
599 wpas0 = WpaSupplicant('veth0', '/tmp/wpas-veth0')
600 wpas1 = WpaSupplicant('veth1', '/tmp/wpas-veth1')
601
602 log_ip_macsec_ns()
603 log_ip_link_ns()
604
605 logger.info("wpas0 STATUS:\n" + wpas0.request("STATUS"))
606 logger.info("wpas1 STATUS:\n" + wpas1.request("STATUS"))
607 logger.info("wpas0 STATUS-DRIVER:\n" + wpas0.request("STATUS-DRIVER"))
608 logger.info("wpas1 STATUS-DRIVER:\n" + wpas1.request("STATUS-DRIVER"))
ead573d8
JM
609
610 for i in range(10):
658ed3ba
JM
611 macsec_ifname0 = wpas0.get_driver_status_field("parent_ifname")
612 macsec_ifname1 = wpas1.get_driver_status_field("parent_ifname")
613 if "Number of Keys" in wpas0.request("STATUS"):
614 key_tx0 = int(wpas0.get_status_field("Number of Keys Distributed"))
615 key_rx0 = int(wpas0.get_status_field("Number of Keys Received"))
616 else:
617 key_tx0 = 0
618 key_rx0 = 0
619 if "Number of Keys" in wpas1.request("STATUS"):
620 key_tx1 = int(wpas1.get_status_field("Number of Keys Distributed"))
621 key_rx1 = int(wpas1.get_status_field("Number of Keys Received"))
622 else:
623 key_tx1 = 0
624 key_rx1 = 0
ead573d8
JM
625 if key_rx0 > 0 and key_tx1 > 0:
626 break
627 time.sleep(1)
628
629 cmd[2] = subprocess.Popen(['ip', 'netns', 'exec', 'ns0',
630 'tcpdump', '-p', '-U', '-i', macsec_ifname0,
631 '-w', cap_macsec0, '-s', '2000',
632 '--immediate-mode'],
633 stderr=open('/dev/null', 'w'))
634 cmd[3] = subprocess.Popen(['ip', 'netns', 'exec', 'ns0',
635 'tcpdump', '-p', '-U', '-i', macsec_ifname1,
636 '-w', cap_macsec1, '-s', '2000',
637 '--immediate-mode'],
638 stderr=open('/dev/null', 'w'))
639 time.sleep(0.5)
640
641 logger.info("wpas0 STATUS:\n" + wpas0.request("STATUS"))
642 logger.info("wpas1 STATUS:\n" + wpas1.request("STATUS"))
643 log_ip_macsec_ns()
644 hwsim_utils.test_connectivity(wpas0, wpas1,
645 ifname1=macsec_ifname0,
646 ifname2=macsec_ifname1,
647 send_len=1400)
648 log_ip_macsec_ns()
649
650 subprocess.check_call(['ip', 'netns', 'exec', 'ns0',
651 'ip', 'addr', 'add', '192.168.248.17/30',
652 'dev', macsec_ifname0])
653 subprocess.check_call(['ip', 'netns', 'exec', 'ns1',
654 'ip', 'addr', 'add', '192.168.248.18/30',
655 'dev', macsec_ifname1])
656 c = subprocess.Popen(['ip', 'netns', 'exec', 'ns0',
657 'ping', '-c', '2', '192.168.248.18'],
658 stdout=subprocess.PIPE)
1c48c9bc 659 res = c.stdout.read().decode()
ead573d8
JM
660 c.stdout.close()
661 logger.info("ping:\n" + res)
662 if "2 packets transmitted, 2 received" not in res:
663 raise Exception("ping did not work")
664
b21540e6 665 wpas0.close_monitor()
ead573d8 666 wpas0.request("TERMINATE")
b21540e6 667 wpas0.close_control()
ead573d8 668 del wpas0
b21540e6 669 wpas1.close_monitor()
ead573d8 670 wpas1.request("TERMINATE")
b21540e6 671 wpas1.close_control()
ead573d8
JM
672 del wpas1
673
674 time.sleep(1)
675 for i in range(len(cmd)):
676 cmd[i].terminate()
344929a9
JM
677
678def test_macsec_psk_fail_cp(dev, apdev):
679 """MACsec PSK local failures in CP state machine"""
680 try:
681 add_veth()
682 wpa = add_wpas_interfaces()
683 set_mka_psk_config(wpa[0])
684 with alloc_fail(wpa[0], 1, "sm_CP_RECEIVE_Enter"):
685 set_mka_psk_config(wpa[1])
686 wait_fail_trigger(wpa[0], "GET_ALLOC_FAIL", max_iter=100)
687
0d09bd08 688 wait_mka_done(wpa)
344929a9
JM
689 finally:
690 cleanup_macsec()
691
692def test_macsec_psk_fail_cp2(dev, apdev):
693 """MACsec PSK local failures in CP state machine (2)"""
694 try:
695 add_veth()
696 wpa = add_wpas_interfaces()
697 set_mka_psk_config(wpa[0])
698 with alloc_fail(wpa[1], 1, "ieee802_1x_cp_sm_init"):
699 set_mka_psk_config(wpa[1])
700 wait_fail_trigger(wpa[1], "GET_ALLOC_FAIL", max_iter=100)
701
0d09bd08 702 wait_mka_done(wpa)
344929a9
JM
703 finally:
704 cleanup_macsec()