test_wpas_mesh.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. #!/usr/bin/python
  2. #
  3. # wpa_supplicant mesh mode tests
  4. # Copyright (c) 2014, cozybit Inc.
  5. #
  6. # This software may be distributed under the terms of the BSD license.
  7. # See README for more details.
  8. import logging
  9. logger = logging.getLogger()
  10. import hwsim_utils
  11. from wpasupplicant import WpaSupplicant
  12. def check_mesh_scan(dev, params, other_started=False):
  13. if not other_started:
  14. dev.dump_monitor()
  15. id = dev.request("SCAN " + params)
  16. if "FAIL" in id:
  17. raise Exception("Failed to start scan")
  18. id = int(id)
  19. if other_started:
  20. ev = dev.wait_event(["CTRL-EVENT-SCAN-STARTED"])
  21. if ev is None:
  22. raise Exception("Other scan did not start")
  23. if "id=" + str(id) in ev:
  24. raise Exception("Own scan id unexpectedly included in start event")
  25. ev = dev.wait_event(["CTRL-EVENT-SCAN-RESULTS"])
  26. if ev is None:
  27. raise Exception("Other scan did not complete")
  28. if "id=" + str(id) in ev:
  29. raise Exception(
  30. "Own scan id unexpectedly included in completed event")
  31. ev = dev.wait_event(["CTRL-EVENT-SCAN-STARTED"])
  32. if ev is None:
  33. raise Exception("Scan did not start")
  34. if "id=" + str(id) not in ev:
  35. raise Exception("Scan id not included in start event")
  36. ev = dev.wait_event(["CTRL-EVENT-SCAN-RESULTS"])
  37. if ev is None:
  38. raise Exception("Scan did not complete")
  39. if "id=" + str(id) not in ev:
  40. raise Exception("Scan id not included in completed event")
  41. res = dev.request("SCAN_RESULTS")
  42. if res.find("[MESH]") < 0:
  43. raise Exception("Scan did not contain a MESH network")
  44. bssid = res.splitlines()[1].split(' ')[0]
  45. bss = dev.get_bss(bssid)
  46. if bss is None:
  47. raise Exception("Could not get BSS entry for mesh")
  48. if 'mesh_capability' not in bss:
  49. raise Exception("mesh_capability missing from BSS entry")
  50. def check_mesh_group_added(dev):
  51. ev = dev.wait_event(["MESH-GROUP-STARTED"])
  52. if ev is None:
  53. raise Exception("Test exception: Couldn't join mesh")
  54. def check_mesh_group_removed(dev):
  55. ev = dev.wait_event(["MESH-GROUP-REMOVED"])
  56. if ev is None:
  57. raise Exception("Test exception: Couldn't leave mesh")
  58. def check_mesh_peer_connected(dev):
  59. ev = dev.wait_event(["MESH-PEER-CONNECTED"])
  60. if ev is None:
  61. raise Exception("Test exception: Remote peer did not connect.")
  62. def check_mesh_peer_disconnected(dev):
  63. ev = dev.wait_event(["MESH-PEER-DISCONNECTED"])
  64. if ev is None:
  65. raise Exception("Test exception: Peer disconnect event not detected.")
  66. def test_wpas_add_set_remove_support(dev):
  67. """wpa_supplicant MESH add/set/remove network support"""
  68. id = dev[0].add_network()
  69. dev[0].set_network(id, "mode", "5")
  70. dev[0].remove_network(id)
  71. def add_open_mesh_network(dev):
  72. id = dev.add_network()
  73. dev.set_network(id, "mode", "5")
  74. dev.set_network_quoted(id, "ssid", "wpas-mesh-open")
  75. dev.set_network(id, "key_mgmt", "NONE")
  76. dev.set_network(id, "frequency", "2412")
  77. dev.mesh_group_add(id)
  78. return id
  79. def test_wpas_mesh_group_added(dev):
  80. """wpa_supplicant MESH group add"""
  81. id = dev[0].add_network()
  82. dev[0].set_network(id, "mode", "5")
  83. dev[0].set_network_quoted(id, "ssid", "wpas-mesh-open")
  84. dev[0].set_network(id, "key_mgmt", "NONE")
  85. dev[0].set_network(id, "frequency", "2412")
  86. dev[0].mesh_group_add(id)
  87. # Check for MESH-GROUP-STARTED event
  88. check_mesh_group_added(dev[0])
  89. def test_wpas_mesh_group_remove(dev):
  90. """wpa_supplicant MESH group remove"""
  91. id = dev[0].add_network()
  92. dev[0].set_network(id, "mode", "5")
  93. dev[0].set_network_quoted(id, "ssid", "wpas-mesh-open")
  94. dev[0].set_network(id, "key_mgmt", "NONE")
  95. dev[0].set_network(id, "frequency", "2412")
  96. dev[0].mesh_group_add(id)
  97. # Check for MESH-GROUP-STARTED event
  98. check_mesh_group_added(dev[0])
  99. dev[0].mesh_group_remove()
  100. # Check for MESH-GROUP-REMOVED event
  101. check_mesh_group_removed(dev[0])
  102. dev[0].mesh_group_remove()
  103. def test_wpas_mesh_peer_connected(dev):
  104. """wpa_supplicant MESH peer connected"""
  105. id = dev[0].add_network()
  106. dev[0].set_network(id, "mode", "5")
  107. dev[0].set_network_quoted(id, "ssid", "wpas-mesh-open")
  108. dev[0].set_network(id, "key_mgmt", "NONE")
  109. dev[0].set_network(id, "frequency", "2412")
  110. dev[0].mesh_group_add(id)
  111. id = dev[1].add_network()
  112. dev[1].set_network(id, "mode", "5")
  113. dev[1].set_network_quoted(id, "ssid", "wpas-mesh-open")
  114. dev[1].set_network(id, "key_mgmt", "NONE")
  115. dev[1].set_network(id, "frequency", "2412")
  116. dev[1].mesh_group_add(id)
  117. # Check for mesh joined
  118. check_mesh_group_added(dev[0])
  119. check_mesh_group_added(dev[1])
  120. # Check for peer connected
  121. check_mesh_peer_connected(dev[0])
  122. check_mesh_peer_connected(dev[1])
  123. def test_wpas_mesh_peer_disconnected(dev):
  124. """wpa_supplicant MESH peer disconnected"""
  125. id = dev[0].add_network()
  126. dev[0].set_network(id, "mode", "5")
  127. dev[0].set_network_quoted(id, "ssid", "wpas-mesh-open")
  128. dev[0].set_network(id, "key_mgmt", "NONE")
  129. dev[0].set_network(id, "frequency", "2412")
  130. dev[0].mesh_group_add(id)
  131. id = dev[1].add_network()
  132. dev[1].set_network(id, "mode", "5")
  133. dev[1].set_network_quoted(id, "ssid", "wpas-mesh-open")
  134. dev[1].set_network(id, "key_mgmt", "NONE")
  135. dev[1].set_network(id, "frequency", "2412")
  136. dev[1].mesh_group_add(id)
  137. # Check for mesh joined
  138. check_mesh_group_added(dev[0])
  139. check_mesh_group_added(dev[1])
  140. # Check for peer connected
  141. check_mesh_peer_connected(dev[0])
  142. check_mesh_peer_connected(dev[1])
  143. # Remove group on dev 1
  144. dev[1].mesh_group_remove()
  145. # Device 0 should get a disconnection event
  146. check_mesh_peer_disconnected(dev[0])
  147. def test_wpas_mesh_mode_scan(dev):
  148. """wpa_supplicant MESH scan support"""
  149. id = dev[0].add_network()
  150. dev[0].set_network(id, "mode", "5")
  151. dev[0].set_network_quoted(id, "ssid", "wpas-mesh-open")
  152. dev[0].set_network(id, "key_mgmt", "NONE")
  153. dev[0].set_network(id, "frequency", "2412")
  154. dev[0].set_network(id, "mesh_ht_mode", "HT40+")
  155. dev[0].mesh_group_add(id)
  156. id = dev[1].add_network()
  157. dev[1].set_network(id, "mode", "5")
  158. dev[1].set_network_quoted(id, "ssid", "wpas-mesh-open")
  159. dev[1].set_network(id, "key_mgmt", "NONE")
  160. dev[1].set_network(id, "frequency", "2412")
  161. dev[1].set_network(id, "mesh_ht_mode", "HT40+")
  162. dev[1].mesh_group_add(id)
  163. # Check for mesh joined
  164. check_mesh_group_added(dev[0])
  165. check_mesh_group_added(dev[1])
  166. # Check for Mesh scan
  167. check_mesh_scan(dev[0], "use_id=1")
  168. def wrap_wpas_mesh_test(test, dev, apdev):
  169. def _test_connectivity(dev1, dev2):
  170. return hwsim_utils.test_connectivity(dev1, dev2)
  171. return test(dev, apdev, _test_connectivity)
  172. def _test_wpas_mesh_open(dev, apdev, test_connectivity):
  173. id = dev[0].add_network()
  174. dev[0].set_network(id, "mode", "5")
  175. dev[0].set_network_quoted(id, "ssid", "wpas-mesh-open")
  176. dev[0].set_network(id, "key_mgmt", "NONE")
  177. dev[0].set_network(id, "frequency", "2412")
  178. dev[0].set_network(id, "mesh_ht_mode", "HT40+")
  179. dev[0].mesh_group_add(id)
  180. id = dev[1].add_network()
  181. dev[1].set_network(id, "mode", "5")
  182. dev[1].set_network_quoted(id, "ssid", "wpas-mesh-open")
  183. dev[1].set_network(id, "key_mgmt", "NONE")
  184. dev[1].set_network(id, "frequency", "2412")
  185. dev[1].set_network(id, "mesh_ht_mode", "HT40+")
  186. dev[1].mesh_group_add(id)
  187. # Check for mesh joined
  188. check_mesh_group_added(dev[0])
  189. check_mesh_group_added(dev[1])
  190. # Check for peer connected
  191. check_mesh_peer_connected(dev[0])
  192. check_mesh_peer_connected(dev[1])
  193. # Test connectivity 0->1 and 1->0
  194. test_connectivity(dev[0], dev[1])
  195. def test_wpas_mesh_open(dev, apdev):
  196. """wpa_supplicant open MESH network connectivity"""
  197. return wrap_wpas_mesh_test(_test_wpas_mesh_open, dev, apdev)
  198. def _test_wpas_mesh_open_no_auto(dev, apdev, test_connectivity):
  199. id = dev[0].add_network()
  200. dev[0].set_network(id, "mode", "5")
  201. dev[0].set_network_quoted(id, "ssid", "wpas-mesh-open")
  202. dev[0].set_network(id, "key_mgmt", "NONE")
  203. dev[0].set_network(id, "frequency", "2412")
  204. dev[0].set_network(id, "dot11MeshMaxRetries", "16")
  205. dev[0].set_network(id, "dot11MeshRetryTimeout", "255")
  206. dev[0].mesh_group_add(id)
  207. id = dev[1].add_network()
  208. dev[1].set_network(id, "mode", "5")
  209. dev[1].set_network_quoted(id, "ssid", "wpas-mesh-open")
  210. dev[1].set_network(id, "key_mgmt", "NONE")
  211. dev[1].set_network(id, "frequency", "2412")
  212. dev[1].set_network(id, "no_auto_peer", "1")
  213. dev[1].mesh_group_add(id)
  214. # Check for mesh joined
  215. check_mesh_group_added(dev[0])
  216. check_mesh_group_added(dev[1])
  217. # Check for peer connected
  218. check_mesh_peer_connected(dev[0])
  219. check_mesh_peer_connected(dev[1])
  220. # Test connectivity 0->1 and 1->0
  221. test_connectivity(dev[0], dev[1])
  222. def test_wpas_mesh_open_no_auto(dev, apdev):
  223. """wpa_supplicant open MESH network connectivity"""
  224. return wrap_wpas_mesh_test(_test_wpas_mesh_open_no_auto, dev, apdev)
  225. def add_mesh_secure_net(dev, psk=True):
  226. id = dev.add_network()
  227. dev.set_network(id, "mode", "5")
  228. dev.set_network_quoted(id, "ssid", "wpas-mesh-sec")
  229. dev.set_network(id, "key_mgmt", "SAE")
  230. dev.set_network(id, "frequency", "2412")
  231. if psk:
  232. dev.set_network_quoted(id, "psk", "thisismypassphrase!")
  233. return id
  234. def _test_wpas_mesh_secure(dev, apdev, test_connectivity):
  235. dev[0].request("SET sae_groups ")
  236. id = add_mesh_secure_net(dev[0])
  237. dev[0].mesh_group_add(id)
  238. dev[1].request("SET sae_groups ")
  239. id = add_mesh_secure_net(dev[1])
  240. dev[1].mesh_group_add(id)
  241. # Check for mesh joined
  242. check_mesh_group_added(dev[0])
  243. check_mesh_group_added(dev[1])
  244. # Check for peer connected
  245. check_mesh_peer_connected(dev[0])
  246. check_mesh_peer_connected(dev[1])
  247. # Test connectivity 0->1 and 1->0
  248. test_connectivity(dev[0], dev[1])
  249. def test_wpas_mesh_secure(dev, apdev):
  250. """wpa_supplicant secure MESH network connectivity"""
  251. return wrap_wpas_mesh_test(_test_wpas_mesh_secure, dev, apdev)
  252. def test_wpas_mesh_secure_sae_group_mismatch(dev, apdev):
  253. """wpa_supplicant secure MESH and SAE group mismatch"""
  254. addr0 = dev[0].p2p_interface_addr()
  255. addr1 = dev[1].p2p_interface_addr()
  256. addr2 = dev[2].p2p_interface_addr()
  257. dev[0].request("SET sae_groups 19 25")
  258. id = add_mesh_secure_net(dev[0])
  259. dev[0].mesh_group_add(id)
  260. dev[1].request("SET sae_groups 19")
  261. id = add_mesh_secure_net(dev[1])
  262. dev[1].mesh_group_add(id)
  263. dev[2].request("SET sae_groups 26")
  264. id = add_mesh_secure_net(dev[2])
  265. dev[2].mesh_group_add(id)
  266. check_mesh_group_added(dev[0])
  267. check_mesh_group_added(dev[1])
  268. check_mesh_group_added(dev[2])
  269. ev = dev[0].wait_event(["MESH-PEER-CONNECTED"])
  270. if ev is None:
  271. raise Exception("Remote peer did not connect")
  272. if addr1 not in ev:
  273. raise Exception("Unexpected peer connected: " + ev)
  274. ev = dev[1].wait_event(["MESH-PEER-CONNECTED"])
  275. if ev is None:
  276. raise Exception("Remote peer did not connect")
  277. if addr0 not in ev:
  278. raise Exception("Unexpected peer connected: " + ev)
  279. ev = dev[2].wait_event(["MESH-PEER-CONNECTED"], timeout=1)
  280. if ev is not None:
  281. raise Exception("Unexpected peer connection at dev[2]: " + ev)
  282. ev = dev[0].wait_event(["MESH-PEER-CONNECTED"], timeout=0.1)
  283. if ev is not None:
  284. raise Exception("Unexpected peer connection: " + ev)
  285. ev = dev[1].wait_event(["MESH-PEER-CONNECTED"], timeout=0.1)
  286. if ev is not None:
  287. raise Exception("Unexpected peer connection: " + ev)
  288. dev[0].request("SET sae_groups ")
  289. dev[1].request("SET sae_groups ")
  290. dev[2].request("SET sae_groups ")
  291. def test_wpas_mesh_secure_sae_missing_password(dev, apdev):
  292. """wpa_supplicant secure MESH and missing SAE password"""
  293. id = add_mesh_secure_net(dev[0], psk=False)
  294. dev[0].set_network(id, "psk", "8f20b381f9b84371d61b5080ad85cac3c61ab3ca9525be5b2d0f4da3d979187a")
  295. dev[0].mesh_group_add(id)
  296. ev = dev[0].wait_event(["MESH-GROUP-STARTED", "Could not join mesh"],
  297. timeout=5)
  298. if ev is None:
  299. raise Exception("Timeout on mesh start event")
  300. if "MESH-GROUP-STARTED" in ev:
  301. raise Exception("Unexpected mesh group start")
  302. ev = dev[0].wait_event(["MESH-GROUP-STARTED"], timeout=0.1)
  303. if ev is not None:
  304. raise Exception("Unexpected mesh group start")
  305. def _test_wpas_mesh_secure_no_auto(dev, apdev, test_connectivity):
  306. dev[0].request("SET sae_groups 19")
  307. id = add_mesh_secure_net(dev[0])
  308. dev[0].mesh_group_add(id)
  309. dev[1].request("SET sae_groups 19")
  310. id = add_mesh_secure_net(dev[1])
  311. dev[1].set_network(id, "no_auto_peer", "1")
  312. dev[1].mesh_group_add(id)
  313. # Check for mesh joined
  314. check_mesh_group_added(dev[0])
  315. check_mesh_group_added(dev[1])
  316. # Check for peer connected
  317. check_mesh_peer_connected(dev[0])
  318. check_mesh_peer_connected(dev[1])
  319. # Test connectivity 0->1 and 1->0
  320. test_connectivity(dev[0], dev[1])
  321. dev[0].request("SET sae_groups ")
  322. dev[1].request("SET sae_groups ")
  323. def test_wpas_mesh_secure_no_auto(dev, apdev):
  324. """wpa_supplicant secure MESH network connectivity"""
  325. return wrap_wpas_mesh_test(_test_wpas_mesh_secure_no_auto, dev, apdev)
  326. def test_wpas_mesh_ctrl(dev):
  327. """wpa_supplicant ctrl_iface mesh command error cases"""
  328. if "FAIL" not in dev[0].request("MESH_GROUP_ADD 123"):
  329. raise Exception("Unexpected MESH_GROUP_ADD success")
  330. id = dev[0].add_network()
  331. if "FAIL" not in dev[0].request("MESH_GROUP_ADD %d" % id):
  332. raise Exception("Unexpected MESH_GROUP_ADD success")
  333. dev[0].set_network(id, "mode", "5")
  334. dev[0].set_network(id, "key_mgmt", "WPA-PSK")
  335. if "FAIL" not in dev[0].request("MESH_GROUP_ADD %d" % id):
  336. raise Exception("Unexpected MESH_GROUP_ADD success")
  337. if "FAIL" not in dev[0].request("MESH_GROUP_REMOVE foo"):
  338. raise Exception("Unexpected MESH_GROUP_REMOVE success")
  339. def test_wpas_mesh_dynamic_interface(dev):
  340. """wpa_supplicant mesh with dynamic interface"""
  341. mesh0 = None
  342. mesh1 = None
  343. try:
  344. mesh0 = dev[0].request("MESH_INTERFACE_ADD ifname=mesh0")
  345. if "FAIL" in mesh0:
  346. raise Exception("MESH_INTERFACE_ADD failed")
  347. mesh1 = dev[1].request("MESH_INTERFACE_ADD")
  348. if "FAIL" in mesh1:
  349. raise Exception("MESH_INTERFACE_ADD failed")
  350. wpas0 = WpaSupplicant(ifname=mesh0)
  351. wpas1 = WpaSupplicant(ifname=mesh1)
  352. logger.info(mesh0 + " address " + wpas0.get_status_field("address"))
  353. logger.info(mesh1 + " address " + wpas1.get_status_field("address"))
  354. add_open_mesh_network(wpas0)
  355. add_open_mesh_network(wpas1)
  356. check_mesh_group_added(wpas0)
  357. check_mesh_group_added(wpas1)
  358. check_mesh_peer_connected(wpas0)
  359. check_mesh_peer_connected(wpas1)
  360. hwsim_utils.test_connectivity(wpas0, wpas1)
  361. # Must not allow MESH_GROUP_REMOVE on dynamic interface
  362. if "FAIL" not in wpas0.request("MESH_GROUP_REMOVE " + mesh0):
  363. raise Exception("Invalid MESH_GROUP_REMOVE accepted")
  364. if "FAIL" not in wpas1.request("MESH_GROUP_REMOVE " + mesh1):
  365. raise Exception("Invalid MESH_GROUP_REMOVE accepted")
  366. # Must not allow MESH_GROUP_REMOVE on another radio interface
  367. if "FAIL" not in wpas0.request("MESH_GROUP_REMOVE " + mesh1):
  368. raise Exception("Invalid MESH_GROUP_REMOVE accepted")
  369. if "FAIL" not in wpas1.request("MESH_GROUP_REMOVE " + mesh0):
  370. raise Exception("Invalid MESH_GROUP_REMOVE accepted")
  371. wpas0.remove_ifname()
  372. wpas1.remove_ifname()
  373. if "OK" not in dev[0].request("MESH_GROUP_REMOVE " + mesh0):
  374. raise Exception("MESH_GROUP_REMOVE failed")
  375. if "OK" not in dev[1].request("MESH_GROUP_REMOVE " + mesh1):
  376. raise Exception("MESH_GROUP_REMOVE failed")
  377. if "FAIL" not in dev[0].request("MESH_GROUP_REMOVE " + mesh0):
  378. raise Exception("Invalid MESH_GROUP_REMOVE accepted")
  379. if "FAIL" not in dev[1].request("MESH_GROUP_REMOVE " + mesh1):
  380. raise Exception("Invalid MESH_GROUP_REMOVE accepted")
  381. logger.info("Make sure another dynamic group can be added")
  382. mesh0 = dev[0].request("MESH_INTERFACE_ADD ifname=mesh0")
  383. if "FAIL" in mesh0:
  384. raise Exception("MESH_INTERFACE_ADD failed")
  385. mesh1 = dev[1].request("MESH_INTERFACE_ADD")
  386. if "FAIL" in mesh1:
  387. raise Exception("MESH_INTERFACE_ADD failed")
  388. wpas0 = WpaSupplicant(ifname=mesh0)
  389. wpas1 = WpaSupplicant(ifname=mesh1)
  390. logger.info(mesh0 + " address " + wpas0.get_status_field("address"))
  391. logger.info(mesh1 + " address " + wpas1.get_status_field("address"))
  392. add_open_mesh_network(wpas0)
  393. add_open_mesh_network(wpas1)
  394. check_mesh_group_added(wpas0)
  395. check_mesh_group_added(wpas1)
  396. check_mesh_peer_connected(wpas0)
  397. check_mesh_peer_connected(wpas1)
  398. hwsim_utils.test_connectivity(wpas0, wpas1)
  399. finally:
  400. if mesh0:
  401. dev[0].request("MESH_GROUP_REMOVE " + mesh0)
  402. if mesh1:
  403. dev[1].request("MESH_GROUP_REMOVE " + mesh1)