blob: 820b8cbfc29d29aab0448602567fc1259abd799b [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
Joe Hershbergerbfacad72015-03-22 17:09:15 -05009#include <dm.h>
Simon Glass9fb625c2019-08-01 09:46:51 -060010#include <env.h>
Joe Hershbergerbfacad72015-03-22 17:09:15 -050011#include <fdtdec.h>
Simon Glassf7ae49f2020-05-10 11:40:05 -060012#include <log.h>
Joe Hershbergerbfacad72015-03-22 17:09:15 -050013#include <malloc.h>
14#include <net.h>
Viacheslav Mitrofanov184ded42022-12-02 12:18:09 +030015#include <net6.h>
Simon Glass0e1fad42020-07-19 10:15:37 -060016#include <asm/eth.h>
Joe Hershbergere721b882015-05-20 14:27:27 -050017#include <dm/test.h>
Bin Meng6d9764c2015-10-07 21:45:43 -070018#include <dm/device-internal.h>
19#include <dm/uclass-internal.h>
Simon Glass0e1fad42020-07-19 10:15:37 -060020#include <test/test.h>
Joe Hershbergere721b882015-05-20 14:27:27 -050021#include <test/ut.h>
Ehsan Mohandesi4c516802023-04-21 17:08:23 -070022#include <ndisc.h>
Joe Hershbergerbfacad72015-03-22 17:09:15 -050023
Bin Meng6d9764c2015-10-07 21:45:43 -070024#define DM_TEST_ETH_NUM 4
25
Viacheslav Mitrofanov184ded42022-12-02 12:18:09 +030026#if IS_ENABLED(CONFIG_IPV6)
27static int dm_test_string_to_ip6(struct unit_test_state *uts)
28{
29 char *str;
30 struct test_ip6_pair {
31 char *string_addr;
32 struct in6_addr ip6_addr;
33 };
34
35 struct in6_addr ip6 = {0};
36
37 /* Correct statements */
38 struct test_ip6_pair test_suite[] = {
39 {"2001:db8::0:1234:1", {.s6_addr32[0] = 0xb80d0120,
40 .s6_addr32[1] = 0x00000000,
41 .s6_addr32[2] = 0x00000000,
42 .s6_addr32[3] = 0x01003412}},
43 {"2001:0db8:0000:0000:0000:0000:1234:0001",
44 {.s6_addr32[0] = 0xb80d0120,
45 .s6_addr32[1] = 0x00000000,
46 .s6_addr32[2] = 0x00000000,
47 .s6_addr32[3] = 0x01003412}},
48 {"::1", {.s6_addr32[0] = 0x00000000,
49 .s6_addr32[1] = 0x00000000,
50 .s6_addr32[2] = 0x00000000,
51 .s6_addr32[3] = 0x01000000}},
52 {"::ffff:192.168.1.1", {.s6_addr32[0] = 0x00000000,
53 .s6_addr32[1] = 0x00000000,
54 .s6_addr32[2] = 0xffff0000,
55 .s6_addr32[3] = 0x0101a8c0}},
56 };
57
58 for (int i = 0; i < ARRAY_SIZE(test_suite); ++i) {
59 ut_assertok(string_to_ip6(test_suite[i].string_addr,
60 strlen(test_suite[i].string_addr), &ip6));
61 ut_asserteq_mem(&ip6, &test_suite[i].ip6_addr,
62 sizeof(struct in6_addr));
63 }
64
65 /* Incorrect statements */
66 str = "hello:world";
67 ut_assertok(!string_to_ip6(str, strlen(str), &ip6));
68 str = "2001:db8::0::0";
69 ut_assertok(!string_to_ip6(str, strlen(str), &ip6));
70 str = "2001:db8:192.168.1.1::1";
71 ut_assertok(!string_to_ip6(str, strlen(str), &ip6));
72 str = "192.168.1.1";
73 ut_assertok(!string_to_ip6(str, strlen(str), &ip6));
74
75 return 0;
76}
77DM_TEST(dm_test_string_to_ip6, 0);
Viacheslav Mitrofanovd9f5c412022-12-02 12:18:10 +030078
79static int dm_test_csum_ipv6_magic(struct unit_test_state *uts)
80{
81 unsigned short csum = 0xbeef;
82 /* Predefined correct parameters */
83 unsigned short correct_csum = 0xd8ac;
84 struct in6_addr saddr = {.s6_addr32[0] = 0x000080fe,
85 .s6_addr32[1] = 0x00000000,
86 .s6_addr32[2] = 0xffe9f242,
87 .s6_addr32[3] = 0xe8f66dfe};
88 struct in6_addr daddr = {.s6_addr32[0] = 0x000080fe,
89 .s6_addr32[1] = 0x00000000,
90 .s6_addr32[2] = 0xffd5b372,
91 .s6_addr32[3] = 0x3ef692fe};
92 u16 len = 1460;
93 unsigned short proto = 17;
94 unsigned int head_csum = 0x91f0;
95
96 csum = csum_ipv6_magic(&saddr, &daddr, len, proto, head_csum);
97 ut_asserteq(csum, correct_csum);
98
99 /* Broke a parameter */
100 proto--;
101 csum = csum_ipv6_magic(&saddr, &daddr, len, proto, head_csum);
102 ut_assert(csum != correct_csum);
103
104 return 0;
105}
106DM_TEST(dm_test_csum_ipv6_magic, 0);
Viacheslav Mitrofanov8576dcd2022-12-02 12:18:11 +0300107
108static int dm_test_ip6_addr_in_subnet(struct unit_test_state *uts)
109{
110 struct in6_addr our = {.s6_addr32[0] = 0x000080fe,
111 .s6_addr32[1] = 0x00000000,
112 .s6_addr32[2] = 0xffe9f242,
113 .s6_addr32[3] = 0xe8f66dfe};
114 struct in6_addr neigh1 = {.s6_addr32[0] = 0x000080fe,
115 .s6_addr32[1] = 0x00000000,
116 .s6_addr32[2] = 0xffd5b372,
117 .s6_addr32[3] = 0x3ef692fe};
118 struct in6_addr neigh2 = {.s6_addr32[0] = 0x60480120,
119 .s6_addr32[1] = 0x00006048,
120 .s6_addr32[2] = 0x00000000,
121 .s6_addr32[3] = 0x00008888};
122
123 /* in */
124 ut_assert(ip6_addr_in_subnet(&our, &neigh1, 64));
125 /* outside */
126 ut_assert(!ip6_addr_in_subnet(&our, &neigh2, 64));
127 ut_assert(!ip6_addr_in_subnet(&our, &neigh1, 128));
128
129 return 0;
130}
131DM_TEST(dm_test_ip6_addr_in_subnet, 0);
Viacheslav Mitrofanov789a2c72022-12-02 12:18:12 +0300132
133static int dm_test_ip6_make_snma(struct unit_test_state *uts)
134{
135 struct in6_addr mult = {0};
136 struct in6_addr correct_addr = {
137 .s6_addr32[0] = 0x000002ff,
138 .s6_addr32[1] = 0x00000000,
139 .s6_addr32[2] = 0x01000000,
140 .s6_addr32[3] = 0xe8f66dff};
141 struct in6_addr addr = { .s6_addr32[0] = 0x000080fe,
142 .s6_addr32[1] = 0x00000000,
143 .s6_addr32[2] = 0xffe9f242,
144 .s6_addr32[3] = 0xe8f66dfe};
145
146 ip6_make_snma(&mult, &addr);
147 ut_asserteq_mem(&mult, &correct_addr, sizeof(struct in6_addr));
148
149 return 0;
150}
151DM_TEST(dm_test_ip6_make_snma, 0);
Viacheslav Mitrofanove4d30fd2022-12-02 12:18:13 +0300152
153static int dm_test_ip6_make_lladdr(struct unit_test_state *uts)
154{
155 struct in6_addr generated_lladdr = {0};
156 struct in6_addr correct_lladdr = {
157 .s6_addr32[0] = 0x000080fe,
158 .s6_addr32[1] = 0x00000000,
159 .s6_addr32[2] = 0xffabf33a,
160 .s6_addr32[3] = 0xfbb352fe};
161 const unsigned char mac[6] = {0x38, 0xf3, 0xab, 0x52, 0xb3, 0xfb};
162
163 ip6_make_lladdr(&generated_lladdr, mac);
164 ut_asserteq_mem(&generated_lladdr, &correct_lladdr,
165 sizeof(struct in6_addr));
166
167 return 0;
168}
169DM_TEST(dm_test_ip6_make_lladdr, UT_TESTF_SCAN_FDT);
Viacheslav Mitrofanov184ded42022-12-02 12:18:09 +0300170#endif
171
Joe Hershbergere721b882015-05-20 14:27:27 -0500172static int dm_test_eth(struct unit_test_state *uts)
Joe Hershbergerbfacad72015-03-22 17:09:15 -0500173{
Joe Hershberger049a95a2015-04-08 01:41:01 -0500174 net_ping_ip = string_to_ip("1.1.2.2");
Joe Hershbergerbfacad72015-03-22 17:09:15 -0500175
Simon Glass382bee52017-08-03 12:22:09 -0600176 env_set("ethact", "eth@10002000");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500177 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600178 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershbergerbfacad72015-03-22 17:09:15 -0500179
Simon Glass382bee52017-08-03 12:22:09 -0600180 env_set("ethact", "eth@10003000");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500181 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600182 ut_asserteq_str("eth@10003000", env_get("ethact"));
Joe Hershbergerbfacad72015-03-22 17:09:15 -0500183
Simon Glass382bee52017-08-03 12:22:09 -0600184 env_set("ethact", "eth@10004000");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500185 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600186 ut_asserteq_str("eth@10004000", env_get("ethact"));
Joe Hershbergerbfacad72015-03-22 17:09:15 -0500187
188 return 0;
189}
Simon Glasse180c2b2020-07-28 19:41:12 -0600190DM_TEST(dm_test_eth, UT_TESTF_SCAN_FDT);
Joe Hershbergere58780d2015-03-22 17:09:16 -0500191
Joe Hershbergere721b882015-05-20 14:27:27 -0500192static int dm_test_eth_alias(struct unit_test_state *uts)
Joe Hershbergere58780d2015-03-22 17:09:16 -0500193{
Joe Hershberger049a95a2015-04-08 01:41:01 -0500194 net_ping_ip = string_to_ip("1.1.2.2");
Simon Glass382bee52017-08-03 12:22:09 -0600195 env_set("ethact", "eth0");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500196 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600197 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershbergere58780d2015-03-22 17:09:16 -0500198
Michael Wallebe1a6e92020-06-02 01:47:09 +0200199 env_set("ethact", "eth6");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500200 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600201 ut_asserteq_str("eth@10004000", env_get("ethact"));
Joe Hershbergere58780d2015-03-22 17:09:16 -0500202
Claudiu Manoilff98da02021-03-14 20:14:57 +0800203 /* Expected to fail since eth1 is not defined in the device tree */
204 env_set("ethact", "eth1");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500205 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600206 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershbergere58780d2015-03-22 17:09:16 -0500207
Simon Glass382bee52017-08-03 12:22:09 -0600208 env_set("ethact", "eth5");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500209 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600210 ut_asserteq_str("eth@10003000", env_get("ethact"));
Joe Hershbergere58780d2015-03-22 17:09:16 -0500211
212 return 0;
213}
Simon Glasse180c2b2020-07-28 19:41:12 -0600214DM_TEST(dm_test_eth_alias, UT_TESTF_SCAN_FDT);
Joe Hershberger6536b9b2015-03-22 17:09:17 -0500215
Joe Hershbergere721b882015-05-20 14:27:27 -0500216static int dm_test_eth_prime(struct unit_test_state *uts)
Joe Hershberger6536b9b2015-03-22 17:09:17 -0500217{
Joe Hershberger049a95a2015-04-08 01:41:01 -0500218 net_ping_ip = string_to_ip("1.1.2.2");
Joe Hershberger6536b9b2015-03-22 17:09:17 -0500219
220 /* Expected to be "eth@10003000" because of ethprime variable */
Simon Glass382bee52017-08-03 12:22:09 -0600221 env_set("ethact", NULL);
222 env_set("ethprime", "eth5");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500223 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600224 ut_asserteq_str("eth@10003000", env_get("ethact"));
Joe Hershberger6536b9b2015-03-22 17:09:17 -0500225
226 /* Expected to be "eth@10002000" because it is first */
Simon Glass382bee52017-08-03 12:22:09 -0600227 env_set("ethact", NULL);
228 env_set("ethprime", NULL);
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500229 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600230 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershberger6536b9b2015-03-22 17:09:17 -0500231
232 return 0;
233}
Simon Glasse180c2b2020-07-28 19:41:12 -0600234DM_TEST(dm_test_eth_prime, UT_TESTF_SCAN_FDT);
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500235
Bin Meng6d9764c2015-10-07 21:45:43 -0700236/**
237 * This test case is trying to test the following scenario:
238 * - All ethernet devices are not probed
239 * - "ethaddr" for all ethernet devices are not set
240 * - "ethact" is set to a valid ethernet device name
241 *
242 * With Sandbox default test configuration, all ethernet devices are
243 * probed after power-up, so we have to manually create such scenario:
244 * - Remove all ethernet devices
245 * - Remove all "ethaddr" environment variables
246 * - Set "ethact" to the first ethernet device
247 *
248 * Do a ping test to see if anything goes wrong.
249 */
250static int dm_test_eth_act(struct unit_test_state *uts)
251{
252 struct udevice *dev[DM_TEST_ETH_NUM];
253 const char *ethname[DM_TEST_ETH_NUM] = {"eth@10002000", "eth@10003000",
254 "sbe5", "eth@10004000"};
255 const char *addrname[DM_TEST_ETH_NUM] = {"ethaddr", "eth5addr",
Michael Wallebe1a6e92020-06-02 01:47:09 +0200256 "eth3addr", "eth6addr"};
Bin Meng6d9764c2015-10-07 21:45:43 -0700257 char ethaddr[DM_TEST_ETH_NUM][18];
258 int i;
259
Tom Rinie2e6dae2017-09-26 14:08:30 -0400260 memset(ethaddr, '\0', sizeof(ethaddr));
Bin Meng6d9764c2015-10-07 21:45:43 -0700261 net_ping_ip = string_to_ip("1.1.2.2");
262
263 /* Prepare the test scenario */
264 for (i = 0; i < DM_TEST_ETH_NUM; i++) {
Sean Anderson2a1812d2023-10-28 18:57:27 -0400265 char *addr;
266
Bin Meng6d9764c2015-10-07 21:45:43 -0700267 ut_assertok(uclass_find_device_by_name(UCLASS_ETH,
268 ethname[i], &dev[i]));
Stefan Roese706865a2017-03-20 12:51:48 +0100269 ut_assertok(device_remove(dev[i], DM_REMOVE_NORMAL));
Bin Meng6d9764c2015-10-07 21:45:43 -0700270
271 /* Invalidate MAC address */
Sean Anderson2a1812d2023-10-28 18:57:27 -0400272 addr = env_get(addrname[i]);
273 ut_assertnonnull(addr);
274 strncpy(ethaddr[i], addr, 17);
Bin Meng6d9764c2015-10-07 21:45:43 -0700275 /* Must disable access protection for ethaddr before clearing */
Simon Glass382bee52017-08-03 12:22:09 -0600276 env_set(".flags", addrname[i]);
277 env_set(addrname[i], NULL);
Bin Meng6d9764c2015-10-07 21:45:43 -0700278 }
279
280 /* Set ethact to "eth@10002000" */
Simon Glass382bee52017-08-03 12:22:09 -0600281 env_set("ethact", ethname[0]);
Bin Meng6d9764c2015-10-07 21:45:43 -0700282
283 /* Segment fault might happen if something is wrong */
284 ut_asserteq(-ENODEV, net_loop(PING));
285
286 for (i = 0; i < DM_TEST_ETH_NUM; i++) {
287 /* Restore the env */
Simon Glass382bee52017-08-03 12:22:09 -0600288 env_set(".flags", addrname[i]);
289 env_set(addrname[i], ethaddr[i]);
Bin Meng6d9764c2015-10-07 21:45:43 -0700290
291 /* Probe the device again */
292 ut_assertok(device_probe(dev[i]));
293 }
Simon Glass382bee52017-08-03 12:22:09 -0600294 env_set(".flags", NULL);
295 env_set("ethact", NULL);
Bin Meng6d9764c2015-10-07 21:45:43 -0700296
297 return 0;
298}
Simon Glasse180c2b2020-07-28 19:41:12 -0600299DM_TEST(dm_test_eth_act, UT_TESTF_SCAN_FDT);
Bin Meng6d9764c2015-10-07 21:45:43 -0700300
Sean Andersondf33fd22022-05-05 13:11:32 -0400301/* Ensure that all addresses are loaded properly */
302static int dm_test_ethaddr(struct unit_test_state *uts)
303{
304 static const char *const addr[] = {
305 "02:00:11:22:33:44",
306 "02:00:11:22:33:48", /* dsa slave */
307 "02:00:11:22:33:45",
308 "02:00:11:22:33:48", /* dsa master */
309 "02:00:11:22:33:46",
310 "02:00:11:22:33:47",
311 "02:00:11:22:33:48", /* dsa slave */
312 "02:00:11:22:33:49",
313 };
314 int i;
315
316 for (i = 0; i < ARRAY_SIZE(addr); i++) {
317 char addrname[10];
Sean Anderson2a1812d2023-10-28 18:57:27 -0400318 char *env_addr;
Sean Andersondf33fd22022-05-05 13:11:32 -0400319
320 if (i)
321 snprintf(addrname, sizeof(addrname), "eth%daddr", i + 1);
322 else
323 strcpy(addrname, "ethaddr");
Sean Anderson2a1812d2023-10-28 18:57:27 -0400324
325 env_addr = env_get(addrname);
326 ut_assertnonnull(env_addr);
327 ut_asserteq_str(addr[i], env_addr);
Sean Andersondf33fd22022-05-05 13:11:32 -0400328 }
329
330 return 0;
331}
332DM_TEST(dm_test_ethaddr, UT_TESTF_SCAN_FDT);
333
Joe Hershberger09129be2015-05-20 14:27:33 -0500334/* The asserts include a return on fail; cleanup in the caller */
335static int _dm_test_eth_rotate1(struct unit_test_state *uts)
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500336{
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500337 /* Make sure that the default is to rotate to the next interface */
Simon Glass382bee52017-08-03 12:22:09 -0600338 env_set("ethact", "eth@10004000");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500339 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600340 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500341
342 /* If ethrotate is no, then we should fail on a bad MAC */
Simon Glass382bee52017-08-03 12:22:09 -0600343 env_set("ethact", "eth@10004000");
344 env_set("ethrotate", "no");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500345 ut_asserteq(-EINVAL, net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600346 ut_asserteq_str("eth@10004000", env_get("ethact"));
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500347
Joe Hershberger09129be2015-05-20 14:27:33 -0500348 return 0;
349}
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500350
Joe Hershberger09129be2015-05-20 14:27:33 -0500351static int _dm_test_eth_rotate2(struct unit_test_state *uts)
352{
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500353 /* Make sure we can skip invalid devices */
Simon Glass382bee52017-08-03 12:22:09 -0600354 env_set("ethact", "eth@10004000");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500355 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600356 ut_asserteq_str("eth@10004000", env_get("ethact"));
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500357
Bin Meng71d79712015-08-27 22:25:53 -0700358 /* Make sure we can handle device name which is not eth# */
Simon Glass382bee52017-08-03 12:22:09 -0600359 env_set("ethact", "sbe5");
Bin Meng71d79712015-08-27 22:25:53 -0700360 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600361 ut_asserteq_str("sbe5", env_get("ethact"));
Bin Meng71d79712015-08-27 22:25:53 -0700362
Joe Hershberger09129be2015-05-20 14:27:33 -0500363 return 0;
364}
365
366static int dm_test_eth_rotate(struct unit_test_state *uts)
367{
368 char ethaddr[18];
369 int retval;
370
371 /* Set target IP to mock ping */
372 net_ping_ip = string_to_ip("1.1.2.2");
373
374 /* Invalidate eth1's MAC address */
Tom Rinie2e6dae2017-09-26 14:08:30 -0400375 memset(ethaddr, '\0', sizeof(ethaddr));
Michael Wallebe1a6e92020-06-02 01:47:09 +0200376 strncpy(ethaddr, env_get("eth6addr"), 17);
377 /* Must disable access protection for eth6addr before clearing */
378 env_set(".flags", "eth6addr");
379 env_set("eth6addr", NULL);
Joe Hershberger09129be2015-05-20 14:27:33 -0500380
381 retval = _dm_test_eth_rotate1(uts);
382
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500383 /* Restore the env */
Michael Wallebe1a6e92020-06-02 01:47:09 +0200384 env_set("eth6addr", ethaddr);
Simon Glass382bee52017-08-03 12:22:09 -0600385 env_set("ethrotate", NULL);
Joe Hershberger09129be2015-05-20 14:27:33 -0500386
387 if (!retval) {
388 /* Invalidate eth0's MAC address */
Tom Rinie2e6dae2017-09-26 14:08:30 -0400389 strncpy(ethaddr, env_get("ethaddr"), 17);
Joe Hershberger09129be2015-05-20 14:27:33 -0500390 /* Must disable access protection for ethaddr before clearing */
Simon Glass382bee52017-08-03 12:22:09 -0600391 env_set(".flags", "ethaddr");
392 env_set("ethaddr", NULL);
Joe Hershberger09129be2015-05-20 14:27:33 -0500393
394 retval = _dm_test_eth_rotate2(uts);
395
396 /* Restore the env */
Simon Glass382bee52017-08-03 12:22:09 -0600397 env_set("ethaddr", ethaddr);
Joe Hershberger09129be2015-05-20 14:27:33 -0500398 }
399 /* Restore the env */
Simon Glass382bee52017-08-03 12:22:09 -0600400 env_set(".flags", NULL);
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500401
Joe Hershberger09129be2015-05-20 14:27:33 -0500402 return retval;
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500403}
Simon Glasse180c2b2020-07-28 19:41:12 -0600404DM_TEST(dm_test_eth_rotate, UT_TESTF_SCAN_FDT);
Joe Hershberger7ece1c62015-03-22 17:09:20 -0500405
Joe Hershberger09129be2015-05-20 14:27:33 -0500406/* The asserts include a return on fail; cleanup in the caller */
407static int _dm_test_net_retry(struct unit_test_state *uts)
Joe Hershberger7ece1c62015-03-22 17:09:20 -0500408{
Joe Hershberger7ece1c62015-03-22 17:09:20 -0500409 /*
410 * eth1 is disabled and netretry is yes, so the ping should succeed and
411 * the active device should be eth0
412 */
413 sandbox_eth_disable_response(1, true);
Claudiu Manoilff98da02021-03-14 20:14:57 +0800414 env_set("ethact", "lan1");
Simon Glass382bee52017-08-03 12:22:09 -0600415 env_set("netretry", "yes");
Joe Hershberger172a31b2015-04-21 13:57:20 -0500416 sandbox_eth_skip_timeout();
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500417 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600418 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershberger7ece1c62015-03-22 17:09:20 -0500419
420 /*
421 * eth1 is disabled and netretry is no, so the ping should fail and the
422 * active device should be eth1
423 */
Claudiu Manoilff98da02021-03-14 20:14:57 +0800424 env_set("ethact", "lan1");
Simon Glass382bee52017-08-03 12:22:09 -0600425 env_set("netretry", "no");
Joe Hershberger172a31b2015-04-21 13:57:20 -0500426 sandbox_eth_skip_timeout();
Thomas RIENOESSLa735e6e2018-11-21 15:56:07 +0100427 ut_asserteq(-ENONET, net_loop(PING));
Claudiu Manoilff98da02021-03-14 20:14:57 +0800428 ut_asserteq_str("lan1", env_get("ethact"));
Joe Hershberger7ece1c62015-03-22 17:09:20 -0500429
Joe Hershberger09129be2015-05-20 14:27:33 -0500430 return 0;
431}
432
433static int dm_test_net_retry(struct unit_test_state *uts)
434{
435 int retval;
436
437 net_ping_ip = string_to_ip("1.1.2.2");
438
439 retval = _dm_test_net_retry(uts);
440
Joe Hershberger7ece1c62015-03-22 17:09:20 -0500441 /* Restore the env */
Simon Glass382bee52017-08-03 12:22:09 -0600442 env_set("netretry", NULL);
Joe Hershberger7ece1c62015-03-22 17:09:20 -0500443 sandbox_eth_disable_response(1, false);
444
Joe Hershberger09129be2015-05-20 14:27:33 -0500445 return retval;
Joe Hershberger7ece1c62015-03-22 17:09:20 -0500446}
Simon Glasse180c2b2020-07-28 19:41:12 -0600447DM_TEST(dm_test_net_retry, UT_TESTF_SCAN_FDT);
Joe Hershberger45988da2018-09-26 16:49:00 -0500448
449static int sb_check_arp_reply(struct udevice *dev, void *packet,
450 unsigned int len)
451{
452 struct eth_sandbox_priv *priv = dev_get_priv(dev);
453 struct ethernet_hdr *eth = packet;
454 struct arp_hdr *arp;
455 /* Used by all of the ut_assert macros */
456 struct unit_test_state *uts = priv->priv;
457
458 if (ntohs(eth->et_protlen) != PROT_ARP)
459 return 0;
460
461 arp = packet + ETHER_HDR_SIZE;
462
463 if (ntohs(arp->ar_op) != ARPOP_REPLY)
464 return 0;
465
466 /* This test would be worthless if we are not waiting */
467 ut_assert(arp_is_waiting());
468
469 /* Validate response */
Simon Glassf91f3662020-05-10 12:52:45 -0600470 ut_asserteq_mem(eth->et_src, net_ethaddr, ARP_HLEN);
471 ut_asserteq_mem(eth->et_dest, priv->fake_host_hwaddr, ARP_HLEN);
Joe Hershberger45988da2018-09-26 16:49:00 -0500472 ut_assert(eth->et_protlen == htons(PROT_ARP));
473
474 ut_assert(arp->ar_hrd == htons(ARP_ETHER));
475 ut_assert(arp->ar_pro == htons(PROT_IP));
476 ut_assert(arp->ar_hln == ARP_HLEN);
477 ut_assert(arp->ar_pln == ARP_PLEN);
Simon Glassf91f3662020-05-10 12:52:45 -0600478 ut_asserteq_mem(&arp->ar_sha, net_ethaddr, ARP_HLEN);
Joe Hershberger45988da2018-09-26 16:49:00 -0500479 ut_assert(net_read_ip(&arp->ar_spa).s_addr == net_ip.s_addr);
Simon Glassf91f3662020-05-10 12:52:45 -0600480 ut_asserteq_mem(&arp->ar_tha, priv->fake_host_hwaddr, ARP_HLEN);
Joe Hershberger45988da2018-09-26 16:49:00 -0500481 ut_assert(net_read_ip(&arp->ar_tpa).s_addr ==
482 string_to_ip("1.1.2.4").s_addr);
483
484 return 0;
485}
486
487static int sb_with_async_arp_handler(struct udevice *dev, void *packet,
488 unsigned int len)
489{
490 struct eth_sandbox_priv *priv = dev_get_priv(dev);
491 struct ethernet_hdr *eth = packet;
492 struct arp_hdr *arp = packet + ETHER_HDR_SIZE;
493 int ret;
494
495 /*
496 * If we are about to generate a reply to ARP, first inject a request
497 * from another host
498 */
499 if (ntohs(eth->et_protlen) == PROT_ARP &&
500 ntohs(arp->ar_op) == ARPOP_REQUEST) {
501 /* Make sure sandbox_eth_recv_arp_req() knows who is asking */
502 priv->fake_host_ipaddr = string_to_ip("1.1.2.4");
503
504 ret = sandbox_eth_recv_arp_req(dev);
505 if (ret)
506 return ret;
507 }
508
509 sandbox_eth_arp_req_to_reply(dev, packet, len);
510 sandbox_eth_ping_req_to_reply(dev, packet, len);
511
512 return sb_check_arp_reply(dev, packet, len);
513}
514
515static int dm_test_eth_async_arp_reply(struct unit_test_state *uts)
516{
517 net_ping_ip = string_to_ip("1.1.2.2");
518
519 sandbox_eth_set_tx_handler(0, sb_with_async_arp_handler);
520 /* Used by all of the ut_assert macros in the tx_handler */
521 sandbox_eth_set_priv(0, uts);
Joe Hershberger45988da2018-09-26 16:49:00 -0500522
523 env_set("ethact", "eth@10002000");
Joe Hershbergerac3f26c2018-09-26 16:49:02 -0500524 ut_assertok(net_loop(PING));
Joe Hershberger45988da2018-09-26 16:49:00 -0500525 ut_asserteq_str("eth@10002000", env_get("ethact"));
526
527 sandbox_eth_set_tx_handler(0, NULL);
528
529 return 0;
530}
531
Simon Glasse180c2b2020-07-28 19:41:12 -0600532DM_TEST(dm_test_eth_async_arp_reply, UT_TESTF_SCAN_FDT);
Joe Hershberger72ff0042018-09-26 16:49:01 -0500533
534static int sb_check_ping_reply(struct udevice *dev, void *packet,
535 unsigned int len)
536{
537 struct eth_sandbox_priv *priv = dev_get_priv(dev);
538 struct ethernet_hdr *eth = packet;
539 struct ip_udp_hdr *ip;
540 struct icmp_hdr *icmp;
541 /* Used by all of the ut_assert macros */
542 struct unit_test_state *uts = priv->priv;
543
544 if (ntohs(eth->et_protlen) != PROT_IP)
545 return 0;
546
547 ip = packet + ETHER_HDR_SIZE;
548
549 if (ip->ip_p != IPPROTO_ICMP)
550 return 0;
551
552 icmp = (struct icmp_hdr *)&ip->udp_src;
553
554 if (icmp->type != ICMP_ECHO_REPLY)
555 return 0;
556
557 /* This test would be worthless if we are not waiting */
558 ut_assert(arp_is_waiting());
559
560 /* Validate response */
Simon Glassf91f3662020-05-10 12:52:45 -0600561 ut_asserteq_mem(eth->et_src, net_ethaddr, ARP_HLEN);
562 ut_asserteq_mem(eth->et_dest, priv->fake_host_hwaddr, ARP_HLEN);
Joe Hershberger72ff0042018-09-26 16:49:01 -0500563 ut_assert(eth->et_protlen == htons(PROT_IP));
564
565 ut_assert(net_read_ip(&ip->ip_src).s_addr == net_ip.s_addr);
566 ut_assert(net_read_ip(&ip->ip_dst).s_addr ==
567 string_to_ip("1.1.2.4").s_addr);
568
569 return 0;
570}
571
572static int sb_with_async_ping_handler(struct udevice *dev, void *packet,
573 unsigned int len)
574{
575 struct eth_sandbox_priv *priv = dev_get_priv(dev);
576 struct ethernet_hdr *eth = packet;
577 struct arp_hdr *arp = packet + ETHER_HDR_SIZE;
578 int ret;
579
580 /*
581 * If we are about to generate a reply to ARP, first inject a request
582 * from another host
583 */
584 if (ntohs(eth->et_protlen) == PROT_ARP &&
585 ntohs(arp->ar_op) == ARPOP_REQUEST) {
586 /* Make sure sandbox_eth_recv_arp_req() knows who is asking */
587 priv->fake_host_ipaddr = string_to_ip("1.1.2.4");
588
589 ret = sandbox_eth_recv_ping_req(dev);
590 if (ret)
591 return ret;
592 }
593
594 sandbox_eth_arp_req_to_reply(dev, packet, len);
595 sandbox_eth_ping_req_to_reply(dev, packet, len);
596
597 return sb_check_ping_reply(dev, packet, len);
598}
599
600static int dm_test_eth_async_ping_reply(struct unit_test_state *uts)
601{
602 net_ping_ip = string_to_ip("1.1.2.2");
603
604 sandbox_eth_set_tx_handler(0, sb_with_async_ping_handler);
605 /* Used by all of the ut_assert macros in the tx_handler */
606 sandbox_eth_set_priv(0, uts);
Joe Hershberger72ff0042018-09-26 16:49:01 -0500607
608 env_set("ethact", "eth@10002000");
Joe Hershbergerac3f26c2018-09-26 16:49:02 -0500609 ut_assertok(net_loop(PING));
Joe Hershberger72ff0042018-09-26 16:49:01 -0500610 ut_asserteq_str("eth@10002000", env_get("ethact"));
611
612 sandbox_eth_set_tx_handler(0, NULL);
613
614 return 0;
615}
616
Simon Glasse180c2b2020-07-28 19:41:12 -0600617DM_TEST(dm_test_eth_async_ping_reply, UT_TESTF_SCAN_FDT);
Ehsan Mohandesi4c516802023-04-21 17:08:23 -0700618
619#if IS_ENABLED(CONFIG_IPV6_ROUTER_DISCOVERY)
620
621static u8 ip6_ra_buf[] = {0x60, 0xf, 0xc5, 0x4a, 0x0, 0x38, 0x3a, 0xff, 0xfe,
622 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x85, 0xe6,
623 0x29, 0x77, 0xcb, 0xc8, 0x53, 0xff, 0x2, 0x0, 0x0,
624 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
625 0x1, 0x86, 0x0, 0xdc, 0x90, 0x40, 0x80, 0x15, 0x18,
626 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x4,
627 0x40, 0xc0, 0x0, 0x0, 0x37, 0xdc, 0x0, 0x0, 0x37,
628 0x78, 0x0, 0x0, 0x0, 0x0, 0x20, 0x1, 0xca, 0xfe, 0xca,
629 0xfe, 0xca, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
630 0x0, 0x1, 0x1, 0x0, 0x15, 0x5d, 0xe2, 0x8a, 0x2};
631
632static int dm_test_validate_ra(struct unit_test_state *uts)
633{
634 struct ip6_hdr *ip6 = (struct ip6_hdr *)ip6_ra_buf;
635 struct icmp6hdr *icmp = (struct icmp6hdr *)(ip6 + 1);
636 __be16 temp = 0;
637
638 ut_assert(validate_ra(ip6) == true);
639
640 temp = ip6->payload_len;
641 ip6->payload_len = 15;
642 ut_assert(validate_ra(ip6) == false);
643 ip6->payload_len = temp;
644
645 temp = ip6->saddr.s6_addr16[0];
646 ip6->saddr.s6_addr16[0] = 0x2001;
647 ut_assert(validate_ra(ip6) == false);
648 ip6->saddr.s6_addr16[0] = temp;
649
650 temp = ip6->hop_limit;
651 ip6->hop_limit = 15;
652 ut_assert(validate_ra(ip6) == false);
653 ip6->hop_limit = temp;
654
655 temp = icmp->icmp6_code;
656 icmp->icmp6_code = 15;
657 ut_assert(validate_ra(ip6) == false);
658 icmp->icmp6_code = temp;
659
660 return 0;
661}
662
663DM_TEST(dm_test_validate_ra, 0);
664
665static int dm_test_process_ra(struct unit_test_state *uts)
666{
667 int len = sizeof(ip6_ra_buf);
668 struct ip6_hdr *ip6 = (struct ip6_hdr *)ip6_ra_buf;
669 struct icmp6hdr *icmp = (struct icmp6hdr *)(ip6 + 1);
670 struct ra_msg *msg = (struct ra_msg *)icmp;
671 unsigned char *option = msg->opt;
672 struct icmp6_ra_prefix_info *prefix =
673 (struct icmp6_ra_prefix_info *)option;
674 __be16 temp = 0;
675 unsigned char option_len = option[1];
676
677 ut_assert(process_ra(ip6, len) == 0);
678
679 temp = icmp->icmp6_rt_lifetime;
680 icmp->icmp6_rt_lifetime = 0;
681 ut_assert(process_ra(ip6, len) != 0);
682 icmp->icmp6_rt_lifetime = temp;
683
684 ut_assert(process_ra(ip6, 0) != 0);
685
686 option[1] = 0;
687 ut_assert(process_ra(ip6, len) != 0);
688 option[1] = option_len;
689
690 prefix->on_link = false;
691 ut_assert(process_ra(ip6, len) != 0);
692 prefix->on_link = true;
693
694 temp = prefix->prefix.s6_addr16[0];
695 prefix->prefix.s6_addr16[0] = 0x80fe;
696 ut_assert(process_ra(ip6, len) != 0);
697 prefix->prefix.s6_addr16[0] = temp;
698
699 return 0;
700}
701
702DM_TEST(dm_test_process_ra, 0);
703
704#endif