blob: bb3dcc6b9540c5b1de7c3542e562e16c1dd9653c [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0
Joe Hershberger4c197242015-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 Hershberger4c197242015-03-22 17:09:15 -05007 */
8
9#include <common.h>
10#include <dm.h>
Simon Glass5e6201b2019-08-01 09:46:51 -060011#include <env.h>
Joe Hershberger4c197242015-03-22 17:09:15 -050012#include <fdtdec.h>
Simon Glass0f2af882020-05-10 11:40:05 -060013#include <log.h>
Joe Hershberger4c197242015-03-22 17:09:15 -050014#include <malloc.h>
15#include <net.h>
Viacheslav Mitrofanovf96b1092022-12-02 12:18:09 +030016#include <net6.h>
Simon Glass75c4d412020-07-19 10:15:37 -060017#include <asm/eth.h>
Joe Hershberger3a77be52015-05-20 14:27:27 -050018#include <dm/test.h>
Bin Meng111473a2015-10-07 21:45:43 -070019#include <dm/device-internal.h>
20#include <dm/uclass-internal.h>
Simon Glass75c4d412020-07-19 10:15:37 -060021#include <test/test.h>
Joe Hershberger3a77be52015-05-20 14:27:27 -050022#include <test/ut.h>
Ehsan Mohandesi63c76c02023-04-21 17:08:23 -070023#include <ndisc.h>
Joe Hershberger4c197242015-03-22 17:09:15 -050024
Bin Meng111473a2015-10-07 21:45:43 -070025#define DM_TEST_ETH_NUM 4
26
Viacheslav Mitrofanovf96b1092022-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 Mitrofanov224f5632022-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 Mitrofanovac6a9ce2022-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 Mitrofanov3b673c02022-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 Mitrofanov5c8e0a62022-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 Mitrofanovf96b1092022-12-02 12:18:09 +0300171#endif
172
Joe Hershberger3a77be52015-05-20 14:27:27 -0500173static int dm_test_eth(struct unit_test_state *uts)
Joe Hershberger4c197242015-03-22 17:09:15 -0500174{
Joe Hershberger5874dec2015-04-08 01:41:01 -0500175 net_ping_ip = string_to_ip("1.1.2.2");
Joe Hershberger4c197242015-03-22 17:09:15 -0500176
Simon Glass6a38e412017-08-03 12:22:09 -0600177 env_set("ethact", "eth@10002000");
Joe Hershbergerc80b41b02015-04-08 01:41:21 -0500178 ut_assertok(net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600179 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershberger4c197242015-03-22 17:09:15 -0500180
Simon Glass6a38e412017-08-03 12:22:09 -0600181 env_set("ethact", "eth@10003000");
Joe Hershbergerc80b41b02015-04-08 01:41:21 -0500182 ut_assertok(net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600183 ut_asserteq_str("eth@10003000", env_get("ethact"));
Joe Hershberger4c197242015-03-22 17:09:15 -0500184
Simon Glass6a38e412017-08-03 12:22:09 -0600185 env_set("ethact", "eth@10004000");
Joe Hershbergerc80b41b02015-04-08 01:41:21 -0500186 ut_assertok(net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600187 ut_asserteq_str("eth@10004000", env_get("ethact"));
Joe Hershberger4c197242015-03-22 17:09:15 -0500188
189 return 0;
190}
Simon Glass974dccd2020-07-28 19:41:12 -0600191DM_TEST(dm_test_eth, UT_TESTF_SCAN_FDT);
Joe Hershberger279d2f62015-03-22 17:09:16 -0500192
Joe Hershberger3a77be52015-05-20 14:27:27 -0500193static int dm_test_eth_alias(struct unit_test_state *uts)
Joe Hershberger279d2f62015-03-22 17:09:16 -0500194{
Joe Hershberger5874dec2015-04-08 01:41:01 -0500195 net_ping_ip = string_to_ip("1.1.2.2");
Simon Glass6a38e412017-08-03 12:22:09 -0600196 env_set("ethact", "eth0");
Joe Hershbergerc80b41b02015-04-08 01:41:21 -0500197 ut_assertok(net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600198 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershberger279d2f62015-03-22 17:09:16 -0500199
Michael Walle7c41a222020-06-02 01:47:09 +0200200 env_set("ethact", "eth6");
Joe Hershbergerc80b41b02015-04-08 01:41:21 -0500201 ut_assertok(net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600202 ut_asserteq_str("eth@10004000", env_get("ethact"));
Joe Hershberger279d2f62015-03-22 17:09:16 -0500203
Claudiu Manoild9eaa922021-03-14 20:14:57 +0800204 /* Expected to fail since eth1 is not defined in the device tree */
205 env_set("ethact", "eth1");
Joe Hershbergerc80b41b02015-04-08 01:41:21 -0500206 ut_assertok(net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600207 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershberger279d2f62015-03-22 17:09:16 -0500208
Simon Glass6a38e412017-08-03 12:22:09 -0600209 env_set("ethact", "eth5");
Joe Hershbergerc80b41b02015-04-08 01:41:21 -0500210 ut_assertok(net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600211 ut_asserteq_str("eth@10003000", env_get("ethact"));
Joe Hershberger279d2f62015-03-22 17:09:16 -0500212
213 return 0;
214}
Simon Glass974dccd2020-07-28 19:41:12 -0600215DM_TEST(dm_test_eth_alias, UT_TESTF_SCAN_FDT);
Joe Hershbergeraa52edd2015-03-22 17:09:17 -0500216
Joe Hershberger3a77be52015-05-20 14:27:27 -0500217static int dm_test_eth_prime(struct unit_test_state *uts)
Joe Hershbergeraa52edd2015-03-22 17:09:17 -0500218{
Joe Hershberger5874dec2015-04-08 01:41:01 -0500219 net_ping_ip = string_to_ip("1.1.2.2");
Joe Hershbergeraa52edd2015-03-22 17:09:17 -0500220
221 /* Expected to be "eth@10003000" because of ethprime variable */
Simon Glass6a38e412017-08-03 12:22:09 -0600222 env_set("ethact", NULL);
223 env_set("ethprime", "eth5");
Joe Hershbergerc80b41b02015-04-08 01:41:21 -0500224 ut_assertok(net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600225 ut_asserteq_str("eth@10003000", env_get("ethact"));
Joe Hershbergeraa52edd2015-03-22 17:09:17 -0500226
227 /* Expected to be "eth@10002000" because it is first */
Simon Glass6a38e412017-08-03 12:22:09 -0600228 env_set("ethact", NULL);
229 env_set("ethprime", NULL);
Joe Hershbergerc80b41b02015-04-08 01:41:21 -0500230 ut_assertok(net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600231 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershbergeraa52edd2015-03-22 17:09:17 -0500232
233 return 0;
234}
Simon Glass974dccd2020-07-28 19:41:12 -0600235DM_TEST(dm_test_eth_prime, UT_TESTF_SCAN_FDT);
Joe Hershbergerf340e542015-03-22 17:09:18 -0500236
Bin Meng111473a2015-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 Walle7c41a222020-06-02 01:47:09 +0200257 "eth3addr", "eth6addr"};
Bin Meng111473a2015-10-07 21:45:43 -0700258 char ethaddr[DM_TEST_ETH_NUM][18];
259 int i;
260
Tom Rini0ac17d82017-09-26 14:08:30 -0400261 memset(ethaddr, '\0', sizeof(ethaddr));
Bin Meng111473a2015-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 Anderson85e8fc82023-10-28 18:57:27 -0400266 char *addr;
267
Bin Meng111473a2015-10-07 21:45:43 -0700268 ut_assertok(uclass_find_device_by_name(UCLASS_ETH,
269 ethname[i], &dev[i]));
Stefan Roese80b5bc92017-03-20 12:51:48 +0100270 ut_assertok(device_remove(dev[i], DM_REMOVE_NORMAL));
Bin Meng111473a2015-10-07 21:45:43 -0700271
272 /* Invalidate MAC address */
Sean Anderson85e8fc82023-10-28 18:57:27 -0400273 addr = env_get(addrname[i]);
274 ut_assertnonnull(addr);
275 strncpy(ethaddr[i], addr, 17);
Bin Meng111473a2015-10-07 21:45:43 -0700276 /* Must disable access protection for ethaddr before clearing */
Simon Glass6a38e412017-08-03 12:22:09 -0600277 env_set(".flags", addrname[i]);
278 env_set(addrname[i], NULL);
Bin Meng111473a2015-10-07 21:45:43 -0700279 }
280
281 /* Set ethact to "eth@10002000" */
Simon Glass6a38e412017-08-03 12:22:09 -0600282 env_set("ethact", ethname[0]);
Bin Meng111473a2015-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 Glass6a38e412017-08-03 12:22:09 -0600289 env_set(".flags", addrname[i]);
290 env_set(addrname[i], ethaddr[i]);
Bin Meng111473a2015-10-07 21:45:43 -0700291
292 /* Probe the device again */
293 ut_assertok(device_probe(dev[i]));
294 }
Simon Glass6a38e412017-08-03 12:22:09 -0600295 env_set(".flags", NULL);
296 env_set("ethact", NULL);
Bin Meng111473a2015-10-07 21:45:43 -0700297
298 return 0;
299}
Simon Glass974dccd2020-07-28 19:41:12 -0600300DM_TEST(dm_test_eth_act, UT_TESTF_SCAN_FDT);
Bin Meng111473a2015-10-07 21:45:43 -0700301
Sean Anderson86f5cc72022-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 Anderson85e8fc82023-10-28 18:57:27 -0400319 char *env_addr;
Sean Anderson86f5cc72022-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 Anderson85e8fc82023-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 Anderson86f5cc72022-05-05 13:11:32 -0400329 }
330
331 return 0;
332}
333DM_TEST(dm_test_ethaddr, UT_TESTF_SCAN_FDT);
334
Joe Hershbergerfc755f92015-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 Hershbergerf340e542015-03-22 17:09:18 -0500337{
Joe Hershbergerf340e542015-03-22 17:09:18 -0500338 /* Make sure that the default is to rotate to the next interface */
Simon Glass6a38e412017-08-03 12:22:09 -0600339 env_set("ethact", "eth@10004000");
Joe Hershbergerc80b41b02015-04-08 01:41:21 -0500340 ut_assertok(net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600341 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershbergerf340e542015-03-22 17:09:18 -0500342
343 /* If ethrotate is no, then we should fail on a bad MAC */
Simon Glass6a38e412017-08-03 12:22:09 -0600344 env_set("ethact", "eth@10004000");
345 env_set("ethrotate", "no");
Joe Hershbergerc80b41b02015-04-08 01:41:21 -0500346 ut_asserteq(-EINVAL, net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600347 ut_asserteq_str("eth@10004000", env_get("ethact"));
Joe Hershbergerf340e542015-03-22 17:09:18 -0500348
Joe Hershbergerfc755f92015-05-20 14:27:33 -0500349 return 0;
350}
Joe Hershbergerf340e542015-03-22 17:09:18 -0500351
Joe Hershbergerfc755f92015-05-20 14:27:33 -0500352static int _dm_test_eth_rotate2(struct unit_test_state *uts)
353{
Joe Hershbergerf340e542015-03-22 17:09:18 -0500354 /* Make sure we can skip invalid devices */
Simon Glass6a38e412017-08-03 12:22:09 -0600355 env_set("ethact", "eth@10004000");
Joe Hershbergerc80b41b02015-04-08 01:41:21 -0500356 ut_assertok(net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600357 ut_asserteq_str("eth@10004000", env_get("ethact"));
Joe Hershbergerf340e542015-03-22 17:09:18 -0500358
Bin Meng04a11cb2015-08-27 22:25:53 -0700359 /* Make sure we can handle device name which is not eth# */
Simon Glass6a38e412017-08-03 12:22:09 -0600360 env_set("ethact", "sbe5");
Bin Meng04a11cb2015-08-27 22:25:53 -0700361 ut_assertok(net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600362 ut_asserteq_str("sbe5", env_get("ethact"));
Bin Meng04a11cb2015-08-27 22:25:53 -0700363
Joe Hershbergerfc755f92015-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 Rini0ac17d82017-09-26 14:08:30 -0400376 memset(ethaddr, '\0', sizeof(ethaddr));
Michael Walle7c41a222020-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 Hershbergerfc755f92015-05-20 14:27:33 -0500381
382 retval = _dm_test_eth_rotate1(uts);
383
Joe Hershbergerf340e542015-03-22 17:09:18 -0500384 /* Restore the env */
Michael Walle7c41a222020-06-02 01:47:09 +0200385 env_set("eth6addr", ethaddr);
Simon Glass6a38e412017-08-03 12:22:09 -0600386 env_set("ethrotate", NULL);
Joe Hershbergerfc755f92015-05-20 14:27:33 -0500387
388 if (!retval) {
389 /* Invalidate eth0's MAC address */
Tom Rini0ac17d82017-09-26 14:08:30 -0400390 strncpy(ethaddr, env_get("ethaddr"), 17);
Joe Hershbergerfc755f92015-05-20 14:27:33 -0500391 /* Must disable access protection for ethaddr before clearing */
Simon Glass6a38e412017-08-03 12:22:09 -0600392 env_set(".flags", "ethaddr");
393 env_set("ethaddr", NULL);
Joe Hershbergerfc755f92015-05-20 14:27:33 -0500394
395 retval = _dm_test_eth_rotate2(uts);
396
397 /* Restore the env */
Simon Glass6a38e412017-08-03 12:22:09 -0600398 env_set("ethaddr", ethaddr);
Joe Hershbergerfc755f92015-05-20 14:27:33 -0500399 }
400 /* Restore the env */
Simon Glass6a38e412017-08-03 12:22:09 -0600401 env_set(".flags", NULL);
Joe Hershbergerf340e542015-03-22 17:09:18 -0500402
Joe Hershbergerfc755f92015-05-20 14:27:33 -0500403 return retval;
Joe Hershbergerf340e542015-03-22 17:09:18 -0500404}
Simon Glass974dccd2020-07-28 19:41:12 -0600405DM_TEST(dm_test_eth_rotate, UT_TESTF_SCAN_FDT);
Joe Hershbergerf933a932015-03-22 17:09:20 -0500406
Joe Hershbergerfc755f92015-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 Hershbergerf933a932015-03-22 17:09:20 -0500409{
Joe Hershbergerf933a932015-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 Manoild9eaa922021-03-14 20:14:57 +0800415 env_set("ethact", "lan1");
Simon Glass6a38e412017-08-03 12:22:09 -0600416 env_set("netretry", "yes");
Joe Hershberger6901f432015-04-21 13:57:20 -0500417 sandbox_eth_skip_timeout();
Joe Hershbergerc80b41b02015-04-08 01:41:21 -0500418 ut_assertok(net_loop(PING));
Simon Glass64b723f2017-08-03 12:22:12 -0600419 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershbergerf933a932015-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 Manoild9eaa922021-03-14 20:14:57 +0800425 env_set("ethact", "lan1");
Simon Glass6a38e412017-08-03 12:22:09 -0600426 env_set("netretry", "no");
Joe Hershberger6901f432015-04-21 13:57:20 -0500427 sandbox_eth_skip_timeout();
Thomas RIENOESSL2dee4192018-11-21 15:56:07 +0100428 ut_asserteq(-ENONET, net_loop(PING));
Claudiu Manoild9eaa922021-03-14 20:14:57 +0800429 ut_asserteq_str("lan1", env_get("ethact"));
Joe Hershbergerf933a932015-03-22 17:09:20 -0500430
Joe Hershbergerfc755f92015-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 Hershbergerf933a932015-03-22 17:09:20 -0500442 /* Restore the env */
Simon Glass6a38e412017-08-03 12:22:09 -0600443 env_set("netretry", NULL);
Joe Hershbergerf933a932015-03-22 17:09:20 -0500444 sandbox_eth_disable_response(1, false);
445
Joe Hershbergerfc755f92015-05-20 14:27:33 -0500446 return retval;
Joe Hershbergerf933a932015-03-22 17:09:20 -0500447}
Simon Glass974dccd2020-07-28 19:41:12 -0600448DM_TEST(dm_test_net_retry, UT_TESTF_SCAN_FDT);
Joe Hershberger54418d02018-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 Glassa3186e62020-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 Hershberger54418d02018-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 Glassa3186e62020-05-10 12:52:45 -0600479 ut_asserteq_mem(&arp->ar_sha, net_ethaddr, ARP_HLEN);
Joe Hershberger54418d02018-09-26 16:49:00 -0500480 ut_assert(net_read_ip(&arp->ar_spa).s_addr == net_ip.s_addr);
Simon Glassa3186e62020-05-10 12:52:45 -0600481 ut_asserteq_mem(&arp->ar_tha, priv->fake_host_hwaddr, ARP_HLEN);
Joe Hershberger54418d02018-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 Hershberger54418d02018-09-26 16:49:00 -0500523
524 env_set("ethact", "eth@10002000");
Joe Hershbergere79a5182018-09-26 16:49:02 -0500525 ut_assertok(net_loop(PING));
Joe Hershberger54418d02018-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 Glass974dccd2020-07-28 19:41:12 -0600533DM_TEST(dm_test_eth_async_arp_reply, UT_TESTF_SCAN_FDT);
Joe Hershberger9716dc12018-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 Glassa3186e62020-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 Hershberger9716dc12018-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 Hershberger9716dc12018-09-26 16:49:01 -0500608
609 env_set("ethact", "eth@10002000");
Joe Hershbergere79a5182018-09-26 16:49:02 -0500610 ut_assertok(net_loop(PING));
Joe Hershberger9716dc12018-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 Glass974dccd2020-07-28 19:41:12 -0600618DM_TEST(dm_test_eth_async_ping_reply, UT_TESTF_SCAN_FDT);
Ehsan Mohandesi63c76c02023-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