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