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