eth.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2015 National Instruments
  4. *
  5. * (C) Copyright 2015
  6. * Joe Hershberger <joe.hershberger@ni.com>
  7. */
  8. #include <common.h>
  9. #include <dm.h>
  10. #include <env.h>
  11. #include <fdtdec.h>
  12. #include <log.h>
  13. #include <malloc.h>
  14. #include <net.h>
  15. #include <net6.h>
  16. #include <asm/eth.h>
  17. #include <dm/test.h>
  18. #include <dm/device-internal.h>
  19. #include <dm/uclass-internal.h>
  20. #include <test/test.h>
  21. #include <test/ut.h>
  22. #include <ndisc.h>
  23. #define DM_TEST_ETH_NUM 4
  24. #if IS_ENABLED(CONFIG_IPV6)
  25. static int dm_test_string_to_ip6(struct unit_test_state *uts)
  26. {
  27. char *str;
  28. struct test_ip6_pair {
  29. char *string_addr;
  30. struct in6_addr ip6_addr;
  31. };
  32. struct in6_addr ip6 = {0};
  33. /* Correct statements */
  34. struct test_ip6_pair test_suite[] = {
  35. {"2001:db8::0:1234:1", {.s6_addr32[0] = 0xb80d0120,
  36. .s6_addr32[1] = 0x00000000,
  37. .s6_addr32[2] = 0x00000000,
  38. .s6_addr32[3] = 0x01003412}},
  39. {"2001:0db8:0000:0000:0000:0000:1234:0001",
  40. {.s6_addr32[0] = 0xb80d0120,
  41. .s6_addr32[1] = 0x00000000,
  42. .s6_addr32[2] = 0x00000000,
  43. .s6_addr32[3] = 0x01003412}},
  44. {"::1", {.s6_addr32[0] = 0x00000000,
  45. .s6_addr32[1] = 0x00000000,
  46. .s6_addr32[2] = 0x00000000,
  47. .s6_addr32[3] = 0x01000000}},
  48. {"::ffff:192.168.1.1", {.s6_addr32[0] = 0x00000000,
  49. .s6_addr32[1] = 0x00000000,
  50. .s6_addr32[2] = 0xffff0000,
  51. .s6_addr32[3] = 0x0101a8c0}},
  52. };
  53. for (int i = 0; i < ARRAY_SIZE(test_suite); ++i) {
  54. ut_assertok(string_to_ip6(test_suite[i].string_addr,
  55. strlen(test_suite[i].string_addr), &ip6));
  56. ut_asserteq_mem(&ip6, &test_suite[i].ip6_addr,
  57. sizeof(struct in6_addr));
  58. }
  59. /* Incorrect statements */
  60. str = "hello:world";
  61. ut_assertok(!string_to_ip6(str, strlen(str), &ip6));
  62. str = "2001:db8::0::0";
  63. ut_assertok(!string_to_ip6(str, strlen(str), &ip6));
  64. str = "2001:db8:192.168.1.1::1";
  65. ut_assertok(!string_to_ip6(str, strlen(str), &ip6));
  66. str = "192.168.1.1";
  67. ut_assertok(!string_to_ip6(str, strlen(str), &ip6));
  68. return 0;
  69. }
  70. DM_TEST(dm_test_string_to_ip6, 0);
  71. static int dm_test_csum_ipv6_magic(struct unit_test_state *uts)
  72. {
  73. unsigned short csum = 0xbeef;
  74. /* Predefined correct parameters */
  75. unsigned short correct_csum = 0xd8ac;
  76. struct in6_addr saddr = {.s6_addr32[0] = 0x000080fe,
  77. .s6_addr32[1] = 0x00000000,
  78. .s6_addr32[2] = 0xffe9f242,
  79. .s6_addr32[3] = 0xe8f66dfe};
  80. struct in6_addr daddr = {.s6_addr32[0] = 0x000080fe,
  81. .s6_addr32[1] = 0x00000000,
  82. .s6_addr32[2] = 0xffd5b372,
  83. .s6_addr32[3] = 0x3ef692fe};
  84. u16 len = 1460;
  85. unsigned short proto = 17;
  86. unsigned int head_csum = 0x91f0;
  87. csum = csum_ipv6_magic(&saddr, &daddr, len, proto, head_csum);
  88. ut_asserteq(csum, correct_csum);
  89. /* Broke a parameter */
  90. proto--;
  91. csum = csum_ipv6_magic(&saddr, &daddr, len, proto, head_csum);
  92. ut_assert(csum != correct_csum);
  93. return 0;
  94. }
  95. DM_TEST(dm_test_csum_ipv6_magic, 0);
  96. static int dm_test_ip6_addr_in_subnet(struct unit_test_state *uts)
  97. {
  98. struct in6_addr our = {.s6_addr32[0] = 0x000080fe,
  99. .s6_addr32[1] = 0x00000000,
  100. .s6_addr32[2] = 0xffe9f242,
  101. .s6_addr32[3] = 0xe8f66dfe};
  102. struct in6_addr neigh1 = {.s6_addr32[0] = 0x000080fe,
  103. .s6_addr32[1] = 0x00000000,
  104. .s6_addr32[2] = 0xffd5b372,
  105. .s6_addr32[3] = 0x3ef692fe};
  106. struct in6_addr neigh2 = {.s6_addr32[0] = 0x60480120,
  107. .s6_addr32[1] = 0x00006048,
  108. .s6_addr32[2] = 0x00000000,
  109. .s6_addr32[3] = 0x00008888};
  110. /* in */
  111. ut_assert(ip6_addr_in_subnet(&our, &neigh1, 64));
  112. /* outside */
  113. ut_assert(!ip6_addr_in_subnet(&our, &neigh2, 64));
  114. ut_assert(!ip6_addr_in_subnet(&our, &neigh1, 128));
  115. return 0;
  116. }
  117. DM_TEST(dm_test_ip6_addr_in_subnet, 0);
  118. static int dm_test_ip6_make_snma(struct unit_test_state *uts)
  119. {
  120. struct in6_addr mult = {0};
  121. struct in6_addr correct_addr = {
  122. .s6_addr32[0] = 0x000002ff,
  123. .s6_addr32[1] = 0x00000000,
  124. .s6_addr32[2] = 0x01000000,
  125. .s6_addr32[3] = 0xe8f66dff};
  126. struct in6_addr addr = { .s6_addr32[0] = 0x000080fe,
  127. .s6_addr32[1] = 0x00000000,
  128. .s6_addr32[2] = 0xffe9f242,
  129. .s6_addr32[3] = 0xe8f66dfe};
  130. ip6_make_snma(&mult, &addr);
  131. ut_asserteq_mem(&mult, &correct_addr, sizeof(struct in6_addr));
  132. return 0;
  133. }
  134. DM_TEST(dm_test_ip6_make_snma, 0);
  135. static int dm_test_ip6_make_lladdr(struct unit_test_state *uts)
  136. {
  137. struct in6_addr generated_lladdr = {0};
  138. struct in6_addr correct_lladdr = {
  139. .s6_addr32[0] = 0x000080fe,
  140. .s6_addr32[1] = 0x00000000,
  141. .s6_addr32[2] = 0xffabf33a,
  142. .s6_addr32[3] = 0xfbb352fe};
  143. const unsigned char mac[6] = {0x38, 0xf3, 0xab, 0x52, 0xb3, 0xfb};
  144. ip6_make_lladdr(&generated_lladdr, mac);
  145. ut_asserteq_mem(&generated_lladdr, &correct_lladdr,
  146. sizeof(struct in6_addr));
  147. return 0;
  148. }
  149. DM_TEST(dm_test_ip6_make_lladdr, UT_TESTF_SCAN_FDT);
  150. #endif
  151. static int dm_test_eth(struct unit_test_state *uts)
  152. {
  153. net_ping_ip = string_to_ip("1.1.2.2");
  154. env_set("ethact", "eth@10002000");
  155. ut_assertok(net_loop(PING));
  156. ut_asserteq_str("eth@10002000", env_get("ethact"));
  157. env_set("ethact", "eth@10003000");
  158. ut_assertok(net_loop(PING));
  159. ut_asserteq_str("eth@10003000", env_get("ethact"));
  160. env_set("ethact", "eth@10004000");
  161. ut_assertok(net_loop(PING));
  162. ut_asserteq_str("eth@10004000", env_get("ethact"));
  163. return 0;
  164. }
  165. DM_TEST(dm_test_eth, UT_TESTF_SCAN_FDT);
  166. static int dm_test_eth_alias(struct unit_test_state *uts)
  167. {
  168. net_ping_ip = string_to_ip("1.1.2.2");
  169. env_set("ethact", "eth0");
  170. ut_assertok(net_loop(PING));
  171. ut_asserteq_str("eth@10002000", env_get("ethact"));
  172. env_set("ethact", "eth6");
  173. ut_assertok(net_loop(PING));
  174. ut_asserteq_str("eth@10004000", env_get("ethact"));
  175. /* Expected to fail since eth1 is not defined in the device tree */
  176. env_set("ethact", "eth1");
  177. ut_assertok(net_loop(PING));
  178. ut_asserteq_str("eth@10002000", env_get("ethact"));
  179. env_set("ethact", "eth5");
  180. ut_assertok(net_loop(PING));
  181. ut_asserteq_str("eth@10003000", env_get("ethact"));
  182. return 0;
  183. }
  184. DM_TEST(dm_test_eth_alias, UT_TESTF_SCAN_FDT);
  185. static int dm_test_eth_prime(struct unit_test_state *uts)
  186. {
  187. net_ping_ip = string_to_ip("1.1.2.2");
  188. /* Expected to be "eth@10003000" because of ethprime variable */
  189. env_set("ethact", NULL);
  190. env_set("ethprime", "eth5");
  191. ut_assertok(net_loop(PING));
  192. ut_asserteq_str("eth@10003000", env_get("ethact"));
  193. /* Expected to be "eth@10002000" because it is first */
  194. env_set("ethact", NULL);
  195. env_set("ethprime", NULL);
  196. ut_assertok(net_loop(PING));
  197. ut_asserteq_str("eth@10002000", env_get("ethact"));
  198. return 0;
  199. }
  200. DM_TEST(dm_test_eth_prime, UT_TESTF_SCAN_FDT);
  201. /**
  202. * This test case is trying to test the following scenario:
  203. * - All ethernet devices are not probed
  204. * - "ethaddr" for all ethernet devices are not set
  205. * - "ethact" is set to a valid ethernet device name
  206. *
  207. * With Sandbox default test configuration, all ethernet devices are
  208. * probed after power-up, so we have to manually create such scenario:
  209. * - Remove all ethernet devices
  210. * - Remove all "ethaddr" environment variables
  211. * - Set "ethact" to the first ethernet device
  212. *
  213. * Do a ping test to see if anything goes wrong.
  214. */
  215. static int dm_test_eth_act(struct unit_test_state *uts)
  216. {
  217. struct udevice *dev[DM_TEST_ETH_NUM];
  218. const char *ethname[DM_TEST_ETH_NUM] = {"eth@10002000", "eth@10003000",
  219. "sbe5", "eth@10004000"};
  220. const char *addrname[DM_TEST_ETH_NUM] = {"ethaddr", "eth5addr",
  221. "eth3addr", "eth6addr"};
  222. char ethaddr[DM_TEST_ETH_NUM][18];
  223. int i;
  224. memset(ethaddr, '\0', sizeof(ethaddr));
  225. net_ping_ip = string_to_ip("1.1.2.2");
  226. /* Prepare the test scenario */
  227. for (i = 0; i < DM_TEST_ETH_NUM; i++) {
  228. ut_assertok(uclass_find_device_by_name(UCLASS_ETH,
  229. ethname[i], &dev[i]));
  230. ut_assertok(device_remove(dev[i], DM_REMOVE_NORMAL));
  231. /* Invalidate MAC address */
  232. strncpy(ethaddr[i], env_get(addrname[i]), 17);
  233. /* Must disable access protection for ethaddr before clearing */
  234. env_set(".flags", addrname[i]);
  235. env_set(addrname[i], NULL);
  236. }
  237. /* Set ethact to "eth@10002000" */
  238. env_set("ethact", ethname[0]);
  239. /* Segment fault might happen if something is wrong */
  240. ut_asserteq(-ENODEV, net_loop(PING));
  241. for (i = 0; i < DM_TEST_ETH_NUM; i++) {
  242. /* Restore the env */
  243. env_set(".flags", addrname[i]);
  244. env_set(addrname[i], ethaddr[i]);
  245. /* Probe the device again */
  246. ut_assertok(device_probe(dev[i]));
  247. }
  248. env_set(".flags", NULL);
  249. env_set("ethact", NULL);
  250. return 0;
  251. }
  252. DM_TEST(dm_test_eth_act, UT_TESTF_SCAN_FDT);
  253. /* Ensure that all addresses are loaded properly */
  254. static int dm_test_ethaddr(struct unit_test_state *uts)
  255. {
  256. static const char *const addr[] = {
  257. "02:00:11:22:33:44",
  258. "02:00:11:22:33:48", /* dsa slave */
  259. "02:00:11:22:33:45",
  260. "02:00:11:22:33:48", /* dsa master */
  261. "02:00:11:22:33:46",
  262. "02:00:11:22:33:47",
  263. "02:00:11:22:33:48", /* dsa slave */
  264. "02:00:11:22:33:49",
  265. };
  266. int i;
  267. for (i = 0; i < ARRAY_SIZE(addr); i++) {
  268. char addrname[10];
  269. if (i)
  270. snprintf(addrname, sizeof(addrname), "eth%daddr", i + 1);
  271. else
  272. strcpy(addrname, "ethaddr");
  273. ut_asserteq_str(addr[i], env_get(addrname));
  274. }
  275. return 0;
  276. }
  277. DM_TEST(dm_test_ethaddr, UT_TESTF_SCAN_FDT);
  278. /* The asserts include a return on fail; cleanup in the caller */
  279. static int _dm_test_eth_rotate1(struct unit_test_state *uts)
  280. {
  281. /* Make sure that the default is to rotate to the next interface */
  282. env_set("ethact", "eth@10004000");
  283. ut_assertok(net_loop(PING));
  284. ut_asserteq_str("eth@10002000", env_get("ethact"));
  285. /* If ethrotate is no, then we should fail on a bad MAC */
  286. env_set("ethact", "eth@10004000");
  287. env_set("ethrotate", "no");
  288. ut_asserteq(-EINVAL, net_loop(PING));
  289. ut_asserteq_str("eth@10004000", env_get("ethact"));
  290. return 0;
  291. }
  292. static int _dm_test_eth_rotate2(struct unit_test_state *uts)
  293. {
  294. /* Make sure we can skip invalid devices */
  295. env_set("ethact", "eth@10004000");
  296. ut_assertok(net_loop(PING));
  297. ut_asserteq_str("eth@10004000", env_get("ethact"));
  298. /* Make sure we can handle device name which is not eth# */
  299. env_set("ethact", "sbe5");
  300. ut_assertok(net_loop(PING));
  301. ut_asserteq_str("sbe5", env_get("ethact"));
  302. return 0;
  303. }
  304. static int dm_test_eth_rotate(struct unit_test_state *uts)
  305. {
  306. char ethaddr[18];
  307. int retval;
  308. /* Set target IP to mock ping */
  309. net_ping_ip = string_to_ip("1.1.2.2");
  310. /* Invalidate eth1's MAC address */
  311. memset(ethaddr, '\0', sizeof(ethaddr));
  312. strncpy(ethaddr, env_get("eth6addr"), 17);
  313. /* Must disable access protection for eth6addr before clearing */
  314. env_set(".flags", "eth6addr");
  315. env_set("eth6addr", NULL);
  316. retval = _dm_test_eth_rotate1(uts);
  317. /* Restore the env */
  318. env_set("eth6addr", ethaddr);
  319. env_set("ethrotate", NULL);
  320. if (!retval) {
  321. /* Invalidate eth0's MAC address */
  322. strncpy(ethaddr, env_get("ethaddr"), 17);
  323. /* Must disable access protection for ethaddr before clearing */
  324. env_set(".flags", "ethaddr");
  325. env_set("ethaddr", NULL);
  326. retval = _dm_test_eth_rotate2(uts);
  327. /* Restore the env */
  328. env_set("ethaddr", ethaddr);
  329. }
  330. /* Restore the env */
  331. env_set(".flags", NULL);
  332. return retval;
  333. }
  334. DM_TEST(dm_test_eth_rotate, UT_TESTF_SCAN_FDT);
  335. /* The asserts include a return on fail; cleanup in the caller */
  336. static int _dm_test_net_retry(struct unit_test_state *uts)
  337. {
  338. /*
  339. * eth1 is disabled and netretry is yes, so the ping should succeed and
  340. * the active device should be eth0
  341. */
  342. sandbox_eth_disable_response(1, true);
  343. env_set("ethact", "lan1");
  344. env_set("netretry", "yes");
  345. sandbox_eth_skip_timeout();
  346. ut_assertok(net_loop(PING));
  347. ut_asserteq_str("eth@10002000", env_get("ethact"));
  348. /*
  349. * eth1 is disabled and netretry is no, so the ping should fail and the
  350. * active device should be eth1
  351. */
  352. env_set("ethact", "lan1");
  353. env_set("netretry", "no");
  354. sandbox_eth_skip_timeout();
  355. ut_asserteq(-ENONET, net_loop(PING));
  356. ut_asserteq_str("lan1", env_get("ethact"));
  357. return 0;
  358. }
  359. static int dm_test_net_retry(struct unit_test_state *uts)
  360. {
  361. int retval;
  362. net_ping_ip = string_to_ip("1.1.2.2");
  363. retval = _dm_test_net_retry(uts);
  364. /* Restore the env */
  365. env_set("netretry", NULL);
  366. sandbox_eth_disable_response(1, false);
  367. return retval;
  368. }
  369. DM_TEST(dm_test_net_retry, UT_TESTF_SCAN_FDT);
  370. static int sb_check_arp_reply(struct udevice *dev, void *packet,
  371. unsigned int len)
  372. {
  373. struct eth_sandbox_priv *priv = dev_get_priv(dev);
  374. struct ethernet_hdr *eth = packet;
  375. struct arp_hdr *arp;
  376. /* Used by all of the ut_assert macros */
  377. struct unit_test_state *uts = priv->priv;
  378. if (ntohs(eth->et_protlen) != PROT_ARP)
  379. return 0;
  380. arp = packet + ETHER_HDR_SIZE;
  381. if (ntohs(arp->ar_op) != ARPOP_REPLY)
  382. return 0;
  383. /* This test would be worthless if we are not waiting */
  384. ut_assert(arp_is_waiting());
  385. /* Validate response */
  386. ut_asserteq_mem(eth->et_src, net_ethaddr, ARP_HLEN);
  387. ut_asserteq_mem(eth->et_dest, priv->fake_host_hwaddr, ARP_HLEN);
  388. ut_assert(eth->et_protlen == htons(PROT_ARP));
  389. ut_assert(arp->ar_hrd == htons(ARP_ETHER));
  390. ut_assert(arp->ar_pro == htons(PROT_IP));
  391. ut_assert(arp->ar_hln == ARP_HLEN);
  392. ut_assert(arp->ar_pln == ARP_PLEN);
  393. ut_asserteq_mem(&arp->ar_sha, net_ethaddr, ARP_HLEN);
  394. ut_assert(net_read_ip(&arp->ar_spa).s_addr == net_ip.s_addr);
  395. ut_asserteq_mem(&arp->ar_tha, priv->fake_host_hwaddr, ARP_HLEN);
  396. ut_assert(net_read_ip(&arp->ar_tpa).s_addr ==
  397. string_to_ip("1.1.2.4").s_addr);
  398. return 0;
  399. }
  400. static int sb_with_async_arp_handler(struct udevice *dev, void *packet,
  401. unsigned int len)
  402. {
  403. struct eth_sandbox_priv *priv = dev_get_priv(dev);
  404. struct ethernet_hdr *eth = packet;
  405. struct arp_hdr *arp = packet + ETHER_HDR_SIZE;
  406. int ret;
  407. /*
  408. * If we are about to generate a reply to ARP, first inject a request
  409. * from another host
  410. */
  411. if (ntohs(eth->et_protlen) == PROT_ARP &&
  412. ntohs(arp->ar_op) == ARPOP_REQUEST) {
  413. /* Make sure sandbox_eth_recv_arp_req() knows who is asking */
  414. priv->fake_host_ipaddr = string_to_ip("1.1.2.4");
  415. ret = sandbox_eth_recv_arp_req(dev);
  416. if (ret)
  417. return ret;
  418. }
  419. sandbox_eth_arp_req_to_reply(dev, packet, len);
  420. sandbox_eth_ping_req_to_reply(dev, packet, len);
  421. return sb_check_arp_reply(dev, packet, len);
  422. }
  423. static int dm_test_eth_async_arp_reply(struct unit_test_state *uts)
  424. {
  425. net_ping_ip = string_to_ip("1.1.2.2");
  426. sandbox_eth_set_tx_handler(0, sb_with_async_arp_handler);
  427. /* Used by all of the ut_assert macros in the tx_handler */
  428. sandbox_eth_set_priv(0, uts);
  429. env_set("ethact", "eth@10002000");
  430. ut_assertok(net_loop(PING));
  431. ut_asserteq_str("eth@10002000", env_get("ethact"));
  432. sandbox_eth_set_tx_handler(0, NULL);
  433. return 0;
  434. }
  435. DM_TEST(dm_test_eth_async_arp_reply, UT_TESTF_SCAN_FDT);
  436. static int sb_check_ping_reply(struct udevice *dev, void *packet,
  437. unsigned int len)
  438. {
  439. struct eth_sandbox_priv *priv = dev_get_priv(dev);
  440. struct ethernet_hdr *eth = packet;
  441. struct ip_udp_hdr *ip;
  442. struct icmp_hdr *icmp;
  443. /* Used by all of the ut_assert macros */
  444. struct unit_test_state *uts = priv->priv;
  445. if (ntohs(eth->et_protlen) != PROT_IP)
  446. return 0;
  447. ip = packet + ETHER_HDR_SIZE;
  448. if (ip->ip_p != IPPROTO_ICMP)
  449. return 0;
  450. icmp = (struct icmp_hdr *)&ip->udp_src;
  451. if (icmp->type != ICMP_ECHO_REPLY)
  452. return 0;
  453. /* This test would be worthless if we are not waiting */
  454. ut_assert(arp_is_waiting());
  455. /* Validate response */
  456. ut_asserteq_mem(eth->et_src, net_ethaddr, ARP_HLEN);
  457. ut_asserteq_mem(eth->et_dest, priv->fake_host_hwaddr, ARP_HLEN);
  458. ut_assert(eth->et_protlen == htons(PROT_IP));
  459. ut_assert(net_read_ip(&ip->ip_src).s_addr == net_ip.s_addr);
  460. ut_assert(net_read_ip(&ip->ip_dst).s_addr ==
  461. string_to_ip("1.1.2.4").s_addr);
  462. return 0;
  463. }
  464. static int sb_with_async_ping_handler(struct udevice *dev, void *packet,
  465. unsigned int len)
  466. {
  467. struct eth_sandbox_priv *priv = dev_get_priv(dev);
  468. struct ethernet_hdr *eth = packet;
  469. struct arp_hdr *arp = packet + ETHER_HDR_SIZE;
  470. int ret;
  471. /*
  472. * If we are about to generate a reply to ARP, first inject a request
  473. * from another host
  474. */
  475. if (ntohs(eth->et_protlen) == PROT_ARP &&
  476. ntohs(arp->ar_op) == ARPOP_REQUEST) {
  477. /* Make sure sandbox_eth_recv_arp_req() knows who is asking */
  478. priv->fake_host_ipaddr = string_to_ip("1.1.2.4");
  479. ret = sandbox_eth_recv_ping_req(dev);
  480. if (ret)
  481. return ret;
  482. }
  483. sandbox_eth_arp_req_to_reply(dev, packet, len);
  484. sandbox_eth_ping_req_to_reply(dev, packet, len);
  485. return sb_check_ping_reply(dev, packet, len);
  486. }
  487. static int dm_test_eth_async_ping_reply(struct unit_test_state *uts)
  488. {
  489. net_ping_ip = string_to_ip("1.1.2.2");
  490. sandbox_eth_set_tx_handler(0, sb_with_async_ping_handler);
  491. /* Used by all of the ut_assert macros in the tx_handler */
  492. sandbox_eth_set_priv(0, uts);
  493. env_set("ethact", "eth@10002000");
  494. ut_assertok(net_loop(PING));
  495. ut_asserteq_str("eth@10002000", env_get("ethact"));
  496. sandbox_eth_set_tx_handler(0, NULL);
  497. return 0;
  498. }
  499. DM_TEST(dm_test_eth_async_ping_reply, UT_TESTF_SCAN_FDT);
  500. #if IS_ENABLED(CONFIG_IPV6_ROUTER_DISCOVERY)
  501. static u8 ip6_ra_buf[] = {0x60, 0xf, 0xc5, 0x4a, 0x0, 0x38, 0x3a, 0xff, 0xfe,
  502. 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x85, 0xe6,
  503. 0x29, 0x77, 0xcb, 0xc8, 0x53, 0xff, 0x2, 0x0, 0x0,
  504. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  505. 0x1, 0x86, 0x0, 0xdc, 0x90, 0x40, 0x80, 0x15, 0x18,
  506. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x4,
  507. 0x40, 0xc0, 0x0, 0x0, 0x37, 0xdc, 0x0, 0x0, 0x37,
  508. 0x78, 0x0, 0x0, 0x0, 0x0, 0x20, 0x1, 0xca, 0xfe, 0xca,
  509. 0xfe, 0xca, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  510. 0x0, 0x1, 0x1, 0x0, 0x15, 0x5d, 0xe2, 0x8a, 0x2};
  511. static int dm_test_validate_ra(struct unit_test_state *uts)
  512. {
  513. struct ip6_hdr *ip6 = (struct ip6_hdr *)ip6_ra_buf;
  514. struct icmp6hdr *icmp = (struct icmp6hdr *)(ip6 + 1);
  515. __be16 temp = 0;
  516. ut_assert(validate_ra(ip6) == true);
  517. temp = ip6->payload_len;
  518. ip6->payload_len = 15;
  519. ut_assert(validate_ra(ip6) == false);
  520. ip6->payload_len = temp;
  521. temp = ip6->saddr.s6_addr16[0];
  522. ip6->saddr.s6_addr16[0] = 0x2001;
  523. ut_assert(validate_ra(ip6) == false);
  524. ip6->saddr.s6_addr16[0] = temp;
  525. temp = ip6->hop_limit;
  526. ip6->hop_limit = 15;
  527. ut_assert(validate_ra(ip6) == false);
  528. ip6->hop_limit = temp;
  529. temp = icmp->icmp6_code;
  530. icmp->icmp6_code = 15;
  531. ut_assert(validate_ra(ip6) == false);
  532. icmp->icmp6_code = temp;
  533. return 0;
  534. }
  535. DM_TEST(dm_test_validate_ra, 0);
  536. static int dm_test_process_ra(struct unit_test_state *uts)
  537. {
  538. int len = sizeof(ip6_ra_buf);
  539. struct ip6_hdr *ip6 = (struct ip6_hdr *)ip6_ra_buf;
  540. struct icmp6hdr *icmp = (struct icmp6hdr *)(ip6 + 1);
  541. struct ra_msg *msg = (struct ra_msg *)icmp;
  542. unsigned char *option = msg->opt;
  543. struct icmp6_ra_prefix_info *prefix =
  544. (struct icmp6_ra_prefix_info *)option;
  545. __be16 temp = 0;
  546. unsigned char option_len = option[1];
  547. ut_assert(process_ra(ip6, len) == 0);
  548. temp = icmp->icmp6_rt_lifetime;
  549. icmp->icmp6_rt_lifetime = 0;
  550. ut_assert(process_ra(ip6, len) != 0);
  551. icmp->icmp6_rt_lifetime = temp;
  552. ut_assert(process_ra(ip6, 0) != 0);
  553. option[1] = 0;
  554. ut_assert(process_ra(ip6, len) != 0);
  555. option[1] = option_len;
  556. prefix->on_link = false;
  557. ut_assert(process_ra(ip6, len) != 0);
  558. prefix->on_link = true;
  559. temp = prefix->prefix.s6_addr16[0];
  560. prefix->prefix.s6_addr16[0] = 0x80fe;
  561. ut_assert(process_ra(ip6, len) != 0);
  562. prefix->prefix.s6_addr16[0] = temp;
  563. return 0;
  564. }
  565. DM_TEST(dm_test_process_ra, 0);
  566. #endif