blob: bb3dcc6b9540c5b1de7c3542e562e16c1dd9653c [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0
Joe Hershbergerbfacad72015-03-22 17:09:15 -05002/*
3 * Copyright (c) 2015 National Instruments
4 *
5 * (C) Copyright 2015
6 * Joe Hershberger <joe.hershberger@ni.com>
Joe Hershbergerbfacad72015-03-22 17:09:15 -05007 */
8
9#include <common.h>
10#include <dm.h>
Simon Glass9fb625c2019-08-01 09:46:51 -060011#include <env.h>
Joe Hershbergerbfacad72015-03-22 17:09:15 -050012#include <fdtdec.h>
Simon Glassf7ae49f2020-05-10 11:40:05 -060013#include <log.h>
Joe Hershbergerbfacad72015-03-22 17:09:15 -050014#include <malloc.h>
15#include <net.h>
Viacheslav Mitrofanov184ded42022-12-02 12:18:09 +030016#include <net6.h>
Simon Glass0e1fad42020-07-19 10:15:37 -060017#include <asm/eth.h>
Joe Hershbergere721b882015-05-20 14:27:27 -050018#include <dm/test.h>
Bin Meng6d9764c2015-10-07 21:45:43 -070019#include <dm/device-internal.h>
20#include <dm/uclass-internal.h>
Simon Glass0e1fad42020-07-19 10:15:37 -060021#include <test/test.h>
Joe Hershbergere721b882015-05-20 14:27:27 -050022#include <test/ut.h>
Ehsan Mohandesi4c516802023-04-21 17:08:23 -070023#include <ndisc.h>
Joe Hershbergerbfacad72015-03-22 17:09:15 -050024
Bin Meng6d9764c2015-10-07 21:45:43 -070025#define DM_TEST_ETH_NUM 4
26
Viacheslav Mitrofanov184ded42022-12-02 12:18:09 +030027#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);
Viacheslav Mitrofanovd9f5c412022-12-02 12:18:10 +030079
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);
Viacheslav Mitrofanov8576dcd2022-12-02 12:18:11 +0300108
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);
Viacheslav Mitrofanov789a2c72022-12-02 12:18:12 +0300133
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);
Viacheslav Mitrofanove4d30fd2022-12-02 12:18:13 +0300153
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);
Viacheslav Mitrofanov184ded42022-12-02 12:18:09 +0300171#endif
172
Joe Hershbergere721b882015-05-20 14:27:27 -0500173static int dm_test_eth(struct unit_test_state *uts)
Joe Hershbergerbfacad72015-03-22 17:09:15 -0500174{
Joe Hershberger049a95a2015-04-08 01:41:01 -0500175 net_ping_ip = string_to_ip("1.1.2.2");
Joe Hershbergerbfacad72015-03-22 17:09:15 -0500176
Simon Glass382bee52017-08-03 12:22:09 -0600177 env_set("ethact", "eth@10002000");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500178 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600179 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershbergerbfacad72015-03-22 17:09:15 -0500180
Simon Glass382bee52017-08-03 12:22:09 -0600181 env_set("ethact", "eth@10003000");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500182 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600183 ut_asserteq_str("eth@10003000", env_get("ethact"));
Joe Hershbergerbfacad72015-03-22 17:09:15 -0500184
Simon Glass382bee52017-08-03 12:22:09 -0600185 env_set("ethact", "eth@10004000");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500186 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600187 ut_asserteq_str("eth@10004000", env_get("ethact"));
Joe Hershbergerbfacad72015-03-22 17:09:15 -0500188
189 return 0;
190}
Simon Glasse180c2b2020-07-28 19:41:12 -0600191DM_TEST(dm_test_eth, UT_TESTF_SCAN_FDT);
Joe Hershbergere58780d2015-03-22 17:09:16 -0500192
Joe Hershbergere721b882015-05-20 14:27:27 -0500193static int dm_test_eth_alias(struct unit_test_state *uts)
Joe Hershbergere58780d2015-03-22 17:09:16 -0500194{
Joe Hershberger049a95a2015-04-08 01:41:01 -0500195 net_ping_ip = string_to_ip("1.1.2.2");
Simon Glass382bee52017-08-03 12:22:09 -0600196 env_set("ethact", "eth0");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500197 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600198 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershbergere58780d2015-03-22 17:09:16 -0500199
Michael Wallebe1a6e92020-06-02 01:47:09 +0200200 env_set("ethact", "eth6");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500201 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600202 ut_asserteq_str("eth@10004000", env_get("ethact"));
Joe Hershbergere58780d2015-03-22 17:09:16 -0500203
Claudiu Manoilff98da02021-03-14 20:14:57 +0800204 /* Expected to fail since eth1 is not defined in the device tree */
205 env_set("ethact", "eth1");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500206 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600207 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershbergere58780d2015-03-22 17:09:16 -0500208
Simon Glass382bee52017-08-03 12:22:09 -0600209 env_set("ethact", "eth5");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500210 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600211 ut_asserteq_str("eth@10003000", env_get("ethact"));
Joe Hershbergere58780d2015-03-22 17:09:16 -0500212
213 return 0;
214}
Simon Glasse180c2b2020-07-28 19:41:12 -0600215DM_TEST(dm_test_eth_alias, UT_TESTF_SCAN_FDT);
Joe Hershberger6536b9b2015-03-22 17:09:17 -0500216
Joe Hershbergere721b882015-05-20 14:27:27 -0500217static int dm_test_eth_prime(struct unit_test_state *uts)
Joe Hershberger6536b9b2015-03-22 17:09:17 -0500218{
Joe Hershberger049a95a2015-04-08 01:41:01 -0500219 net_ping_ip = string_to_ip("1.1.2.2");
Joe Hershberger6536b9b2015-03-22 17:09:17 -0500220
221 /* Expected to be "eth@10003000" because of ethprime variable */
Simon Glass382bee52017-08-03 12:22:09 -0600222 env_set("ethact", NULL);
223 env_set("ethprime", "eth5");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500224 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600225 ut_asserteq_str("eth@10003000", env_get("ethact"));
Joe Hershberger6536b9b2015-03-22 17:09:17 -0500226
227 /* Expected to be "eth@10002000" because it is first */
Simon Glass382bee52017-08-03 12:22:09 -0600228 env_set("ethact", NULL);
229 env_set("ethprime", NULL);
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500230 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600231 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershberger6536b9b2015-03-22 17:09:17 -0500232
233 return 0;
234}
Simon Glasse180c2b2020-07-28 19:41:12 -0600235DM_TEST(dm_test_eth_prime, UT_TESTF_SCAN_FDT);
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500236
Bin Meng6d9764c2015-10-07 21:45:43 -0700237/**
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",
Michael Wallebe1a6e92020-06-02 01:47:09 +0200257 "eth3addr", "eth6addr"};
Bin Meng6d9764c2015-10-07 21:45:43 -0700258 char ethaddr[DM_TEST_ETH_NUM][18];
259 int i;
260
Tom Rinie2e6dae2017-09-26 14:08:30 -0400261 memset(ethaddr, '\0', sizeof(ethaddr));
Bin Meng6d9764c2015-10-07 21:45:43 -0700262 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++) {
Sean Anderson2a1812d2023-10-28 18:57:27 -0400266 char *addr;
267
Bin Meng6d9764c2015-10-07 21:45:43 -0700268 ut_assertok(uclass_find_device_by_name(UCLASS_ETH,
269 ethname[i], &dev[i]));
Stefan Roese706865a2017-03-20 12:51:48 +0100270 ut_assertok(device_remove(dev[i], DM_REMOVE_NORMAL));
Bin Meng6d9764c2015-10-07 21:45:43 -0700271
272 /* Invalidate MAC address */
Sean Anderson2a1812d2023-10-28 18:57:27 -0400273 addr = env_get(addrname[i]);
274 ut_assertnonnull(addr);
275 strncpy(ethaddr[i], addr, 17);
Bin Meng6d9764c2015-10-07 21:45:43 -0700276 /* Must disable access protection for ethaddr before clearing */
Simon Glass382bee52017-08-03 12:22:09 -0600277 env_set(".flags", addrname[i]);
278 env_set(addrname[i], NULL);
Bin Meng6d9764c2015-10-07 21:45:43 -0700279 }
280
281 /* Set ethact to "eth@10002000" */
Simon Glass382bee52017-08-03 12:22:09 -0600282 env_set("ethact", ethname[0]);
Bin Meng6d9764c2015-10-07 21:45:43 -0700283
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 */
Simon Glass382bee52017-08-03 12:22:09 -0600289 env_set(".flags", addrname[i]);
290 env_set(addrname[i], ethaddr[i]);
Bin Meng6d9764c2015-10-07 21:45:43 -0700291
292 /* Probe the device again */
293 ut_assertok(device_probe(dev[i]));
294 }
Simon Glass382bee52017-08-03 12:22:09 -0600295 env_set(".flags", NULL);
296 env_set("ethact", NULL);
Bin Meng6d9764c2015-10-07 21:45:43 -0700297
298 return 0;
299}
Simon Glasse180c2b2020-07-28 19:41:12 -0600300DM_TEST(dm_test_eth_act, UT_TESTF_SCAN_FDT);
Bin Meng6d9764c2015-10-07 21:45:43 -0700301
Sean Andersondf33fd22022-05-05 13:11:32 -0400302/* 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];
Sean Anderson2a1812d2023-10-28 18:57:27 -0400319 char *env_addr;
Sean Andersondf33fd22022-05-05 13:11:32 -0400320
321 if (i)
322 snprintf(addrname, sizeof(addrname), "eth%daddr", i + 1);
323 else
324 strcpy(addrname, "ethaddr");
Sean Anderson2a1812d2023-10-28 18:57:27 -0400325
326 env_addr = env_get(addrname);
327 ut_assertnonnull(env_addr);
328 ut_asserteq_str(addr[i], env_addr);
Sean Andersondf33fd22022-05-05 13:11:32 -0400329 }
330
331 return 0;
332}
333DM_TEST(dm_test_ethaddr, UT_TESTF_SCAN_FDT);
334
Joe Hershberger09129be2015-05-20 14:27:33 -0500335/* The asserts include a return on fail; cleanup in the caller */
336static int _dm_test_eth_rotate1(struct unit_test_state *uts)
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500337{
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500338 /* Make sure that the default is to rotate to the next interface */
Simon Glass382bee52017-08-03 12:22:09 -0600339 env_set("ethact", "eth@10004000");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500340 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600341 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500342
343 /* If ethrotate is no, then we should fail on a bad MAC */
Simon Glass382bee52017-08-03 12:22:09 -0600344 env_set("ethact", "eth@10004000");
345 env_set("ethrotate", "no");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500346 ut_asserteq(-EINVAL, net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600347 ut_asserteq_str("eth@10004000", env_get("ethact"));
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500348
Joe Hershberger09129be2015-05-20 14:27:33 -0500349 return 0;
350}
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500351
Joe Hershberger09129be2015-05-20 14:27:33 -0500352static int _dm_test_eth_rotate2(struct unit_test_state *uts)
353{
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500354 /* Make sure we can skip invalid devices */
Simon Glass382bee52017-08-03 12:22:09 -0600355 env_set("ethact", "eth@10004000");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500356 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600357 ut_asserteq_str("eth@10004000", env_get("ethact"));
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500358
Bin Meng71d79712015-08-27 22:25:53 -0700359 /* Make sure we can handle device name which is not eth# */
Simon Glass382bee52017-08-03 12:22:09 -0600360 env_set("ethact", "sbe5");
Bin Meng71d79712015-08-27 22:25:53 -0700361 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600362 ut_asserteq_str("sbe5", env_get("ethact"));
Bin Meng71d79712015-08-27 22:25:53 -0700363
Joe Hershberger09129be2015-05-20 14:27:33 -0500364 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 */
Tom Rinie2e6dae2017-09-26 14:08:30 -0400376 memset(ethaddr, '\0', sizeof(ethaddr));
Michael Wallebe1a6e92020-06-02 01:47:09 +0200377 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);
Joe Hershberger09129be2015-05-20 14:27:33 -0500381
382 retval = _dm_test_eth_rotate1(uts);
383
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500384 /* Restore the env */
Michael Wallebe1a6e92020-06-02 01:47:09 +0200385 env_set("eth6addr", ethaddr);
Simon Glass382bee52017-08-03 12:22:09 -0600386 env_set("ethrotate", NULL);
Joe Hershberger09129be2015-05-20 14:27:33 -0500387
388 if (!retval) {
389 /* Invalidate eth0's MAC address */
Tom Rinie2e6dae2017-09-26 14:08:30 -0400390 strncpy(ethaddr, env_get("ethaddr"), 17);
Joe Hershberger09129be2015-05-20 14:27:33 -0500391 /* Must disable access protection for ethaddr before clearing */
Simon Glass382bee52017-08-03 12:22:09 -0600392 env_set(".flags", "ethaddr");
393 env_set("ethaddr", NULL);
Joe Hershberger09129be2015-05-20 14:27:33 -0500394
395 retval = _dm_test_eth_rotate2(uts);
396
397 /* Restore the env */
Simon Glass382bee52017-08-03 12:22:09 -0600398 env_set("ethaddr", ethaddr);
Joe Hershberger09129be2015-05-20 14:27:33 -0500399 }
400 /* Restore the env */
Simon Glass382bee52017-08-03 12:22:09 -0600401 env_set(".flags", NULL);
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500402
Joe Hershberger09129be2015-05-20 14:27:33 -0500403 return retval;
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500404}
Simon Glasse180c2b2020-07-28 19:41:12 -0600405DM_TEST(dm_test_eth_rotate, UT_TESTF_SCAN_FDT);
Joe Hershberger7ece1c62015-03-22 17:09:20 -0500406
Joe Hershberger09129be2015-05-20 14:27:33 -0500407/* The asserts include a return on fail; cleanup in the caller */
408static int _dm_test_net_retry(struct unit_test_state *uts)
Joe Hershberger7ece1c62015-03-22 17:09:20 -0500409{
Joe Hershberger7ece1c62015-03-22 17:09:20 -0500410 /*
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);
Claudiu Manoilff98da02021-03-14 20:14:57 +0800415 env_set("ethact", "lan1");
Simon Glass382bee52017-08-03 12:22:09 -0600416 env_set("netretry", "yes");
Joe Hershberger172a31b2015-04-21 13:57:20 -0500417 sandbox_eth_skip_timeout();
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500418 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600419 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershberger7ece1c62015-03-22 17:09:20 -0500420
421 /*
422 * eth1 is disabled and netretry is no, so the ping should fail and the
423 * active device should be eth1
424 */
Claudiu Manoilff98da02021-03-14 20:14:57 +0800425 env_set("ethact", "lan1");
Simon Glass382bee52017-08-03 12:22:09 -0600426 env_set("netretry", "no");
Joe Hershberger172a31b2015-04-21 13:57:20 -0500427 sandbox_eth_skip_timeout();
Thomas RIENOESSLa735e6e2018-11-21 15:56:07 +0100428 ut_asserteq(-ENONET, net_loop(PING));
Claudiu Manoilff98da02021-03-14 20:14:57 +0800429 ut_asserteq_str("lan1", env_get("ethact"));
Joe Hershberger7ece1c62015-03-22 17:09:20 -0500430
Joe Hershberger09129be2015-05-20 14:27:33 -0500431 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
Joe Hershberger7ece1c62015-03-22 17:09:20 -0500442 /* Restore the env */
Simon Glass382bee52017-08-03 12:22:09 -0600443 env_set("netretry", NULL);
Joe Hershberger7ece1c62015-03-22 17:09:20 -0500444 sandbox_eth_disable_response(1, false);
445
Joe Hershberger09129be2015-05-20 14:27:33 -0500446 return retval;
Joe Hershberger7ece1c62015-03-22 17:09:20 -0500447}
Simon Glasse180c2b2020-07-28 19:41:12 -0600448DM_TEST(dm_test_net_retry, UT_TESTF_SCAN_FDT);
Joe Hershberger45988da2018-09-26 16:49:00 -0500449
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 */
Simon Glassf91f3662020-05-10 12:52:45 -0600471 ut_asserteq_mem(eth->et_src, net_ethaddr, ARP_HLEN);
472 ut_asserteq_mem(eth->et_dest, priv->fake_host_hwaddr, ARP_HLEN);
Joe Hershberger45988da2018-09-26 16:49:00 -0500473 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);
Simon Glassf91f3662020-05-10 12:52:45 -0600479 ut_asserteq_mem(&arp->ar_sha, net_ethaddr, ARP_HLEN);
Joe Hershberger45988da2018-09-26 16:49:00 -0500480 ut_assert(net_read_ip(&arp->ar_spa).s_addr == net_ip.s_addr);
Simon Glassf91f3662020-05-10 12:52:45 -0600481 ut_asserteq_mem(&arp->ar_tha, priv->fake_host_hwaddr, ARP_HLEN);
Joe Hershberger45988da2018-09-26 16:49:00 -0500482 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);
Joe Hershberger45988da2018-09-26 16:49:00 -0500523
524 env_set("ethact", "eth@10002000");
Joe Hershbergerac3f26c2018-09-26 16:49:02 -0500525 ut_assertok(net_loop(PING));
Joe Hershberger45988da2018-09-26 16:49:00 -0500526 ut_asserteq_str("eth@10002000", env_get("ethact"));
527
528 sandbox_eth_set_tx_handler(0, NULL);
529
530 return 0;
531}
532
Simon Glasse180c2b2020-07-28 19:41:12 -0600533DM_TEST(dm_test_eth_async_arp_reply, UT_TESTF_SCAN_FDT);
Joe Hershberger72ff0042018-09-26 16:49:01 -0500534
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 */
Simon Glassf91f3662020-05-10 12:52:45 -0600562 ut_asserteq_mem(eth->et_src, net_ethaddr, ARP_HLEN);
563 ut_asserteq_mem(eth->et_dest, priv->fake_host_hwaddr, ARP_HLEN);
Joe Hershberger72ff0042018-09-26 16:49:01 -0500564 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);
Joe Hershberger72ff0042018-09-26 16:49:01 -0500608
609 env_set("ethact", "eth@10002000");
Joe Hershbergerac3f26c2018-09-26 16:49:02 -0500610 ut_assertok(net_loop(PING));
Joe Hershberger72ff0042018-09-26 16:49:01 -0500611 ut_asserteq_str("eth@10002000", env_get("ethact"));
612
613 sandbox_eth_set_tx_handler(0, NULL);
614
615 return 0;
616}
617
Simon Glasse180c2b2020-07-28 19:41:12 -0600618DM_TEST(dm_test_eth_async_ping_reply, UT_TESTF_SCAN_FDT);
Ehsan Mohandesi4c516802023-04-21 17:08:23 -0700619
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