1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2015 National Instruments
4  *
5  * (C) Copyright 2015
6  * Joe Hershberger <joe.hershberger@ni.com>
7  */
8 
9 #include <common.h>
10 #include <dm.h>
11 #include <env.h>
12 #include <fdtdec.h>
13 #include <log.h>
14 #include <malloc.h>
15 #include <net.h>
16 #include <net6.h>
17 #include <asm/eth.h>
18 #include <dm/test.h>
19 #include <dm/device-internal.h>
20 #include <dm/uclass-internal.h>
21 #include <test/test.h>
22 #include <test/ut.h>
23 #include <ndisc.h>
24 
25 #define DM_TEST_ETH_NUM		4
26 
27 #if IS_ENABLED(CONFIG_IPV6)
dm_test_string_to_ip6(struct unit_test_state * uts)28 static 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 }
78 DM_TEST(dm_test_string_to_ip6, 0);
79 
dm_test_csum_ipv6_magic(struct unit_test_state * uts)80 static 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 }
107 DM_TEST(dm_test_csum_ipv6_magic, 0);
108 
dm_test_ip6_addr_in_subnet(struct unit_test_state * uts)109 static 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 }
132 DM_TEST(dm_test_ip6_addr_in_subnet, 0);
133 
dm_test_ip6_make_snma(struct unit_test_state * uts)134 static 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 }
152 DM_TEST(dm_test_ip6_make_snma, 0);
153 
dm_test_ip6_make_lladdr(struct unit_test_state * uts)154 static 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 }
170 DM_TEST(dm_test_ip6_make_lladdr, UT_TESTF_SCAN_FDT);
171 #endif
172 
dm_test_eth(struct unit_test_state * uts)173 static int dm_test_eth(struct unit_test_state *uts)
174 {
175 	net_ping_ip = string_to_ip("1.1.2.2");
176 
177 	env_set("ethact", "eth@10002000");
178 	ut_assertok(net_loop(PING));
179 	ut_asserteq_str("eth@10002000", env_get("ethact"));
180 
181 	env_set("ethact", "eth@10003000");
182 	ut_assertok(net_loop(PING));
183 	ut_asserteq_str("eth@10003000", env_get("ethact"));
184 
185 	env_set("ethact", "eth@10004000");
186 	ut_assertok(net_loop(PING));
187 	ut_asserteq_str("eth@10004000", env_get("ethact"));
188 
189 	return 0;
190 }
191 DM_TEST(dm_test_eth, UT_TESTF_SCAN_FDT);
192 
dm_test_eth_alias(struct unit_test_state * uts)193 static int dm_test_eth_alias(struct unit_test_state *uts)
194 {
195 	net_ping_ip = string_to_ip("1.1.2.2");
196 	env_set("ethact", "eth0");
197 	ut_assertok(net_loop(PING));
198 	ut_asserteq_str("eth@10002000", env_get("ethact"));
199 
200 	env_set("ethact", "eth6");
201 	ut_assertok(net_loop(PING));
202 	ut_asserteq_str("eth@10004000", env_get("ethact"));
203 
204 	/* Expected to fail since eth1 is not defined in the device tree */
205 	env_set("ethact", "eth1");
206 	ut_assertok(net_loop(PING));
207 	ut_asserteq_str("eth@10002000", env_get("ethact"));
208 
209 	env_set("ethact", "eth5");
210 	ut_assertok(net_loop(PING));
211 	ut_asserteq_str("eth@10003000", env_get("ethact"));
212 
213 	return 0;
214 }
215 DM_TEST(dm_test_eth_alias, UT_TESTF_SCAN_FDT);
216 
dm_test_eth_prime(struct unit_test_state * uts)217 static int dm_test_eth_prime(struct unit_test_state *uts)
218 {
219 	net_ping_ip = string_to_ip("1.1.2.2");
220 
221 	/* Expected to be "eth@10003000" because of ethprime variable */
222 	env_set("ethact", NULL);
223 	env_set("ethprime", "eth5");
224 	ut_assertok(net_loop(PING));
225 	ut_asserteq_str("eth@10003000", env_get("ethact"));
226 
227 	/* Expected to be "eth@10002000" because it is first */
228 	env_set("ethact", NULL);
229 	env_set("ethprime", NULL);
230 	ut_assertok(net_loop(PING));
231 	ut_asserteq_str("eth@10002000", env_get("ethact"));
232 
233 	return 0;
234 }
235 DM_TEST(dm_test_eth_prime, UT_TESTF_SCAN_FDT);
236 
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  */
dm_test_eth_act(struct unit_test_state * uts)251 static 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",
257 						 "eth3addr", "eth6addr"};
258 	char ethaddr[DM_TEST_ETH_NUM][18];
259 	int i;
260 
261 	memset(ethaddr, '\0', sizeof(ethaddr));
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++) {
266 		ut_assertok(uclass_find_device_by_name(UCLASS_ETH,
267 						       ethname[i], &dev[i]));
268 		ut_assertok(device_remove(dev[i], DM_REMOVE_NORMAL));
269 
270 		/* Invalidate MAC address */
271 		strncpy(ethaddr[i], env_get(addrname[i]), 17);
272 		/* Must disable access protection for ethaddr before clearing */
273 		env_set(".flags", addrname[i]);
274 		env_set(addrname[i], NULL);
275 	}
276 
277 	/* Set ethact to "eth@10002000" */
278 	env_set("ethact", ethname[0]);
279 
280 	/* Segment fault might happen if something is wrong */
281 	ut_asserteq(-ENODEV, net_loop(PING));
282 
283 	for (i = 0; i < DM_TEST_ETH_NUM; i++) {
284 		/* Restore the env */
285 		env_set(".flags", addrname[i]);
286 		env_set(addrname[i], ethaddr[i]);
287 
288 		/* Probe the device again */
289 		ut_assertok(device_probe(dev[i]));
290 	}
291 	env_set(".flags", NULL);
292 	env_set("ethact", NULL);
293 
294 	return 0;
295 }
296 DM_TEST(dm_test_eth_act, UT_TESTF_SCAN_FDT);
297 
298 /* Ensure that all addresses are loaded properly */
dm_test_ethaddr(struct unit_test_state * uts)299 static int dm_test_ethaddr(struct unit_test_state *uts)
300 {
301 	static const char *const addr[] = {
302 		"02:00:11:22:33:44",
303 		"02:00:11:22:33:48", /* dsa slave */
304 		"02:00:11:22:33:45",
305 		"02:00:11:22:33:48", /* dsa master */
306 		"02:00:11:22:33:46",
307 		"02:00:11:22:33:47",
308 		"02:00:11:22:33:48", /* dsa slave */
309 		"02:00:11:22:33:49",
310 	};
311 	int i;
312 
313 	for (i = 0; i < ARRAY_SIZE(addr); i++) {
314 		char addrname[10];
315 
316 		if (i)
317 			snprintf(addrname, sizeof(addrname), "eth%daddr", i + 1);
318 		else
319 			strcpy(addrname, "ethaddr");
320 		ut_asserteq_str(addr[i], env_get(addrname));
321 	}
322 
323 	return 0;
324 }
325 DM_TEST(dm_test_ethaddr, UT_TESTF_SCAN_FDT);
326 
327 /* The asserts include a return on fail; cleanup in the caller */
_dm_test_eth_rotate1(struct unit_test_state * uts)328 static int _dm_test_eth_rotate1(struct unit_test_state *uts)
329 {
330 	/* Make sure that the default is to rotate to the next interface */
331 	env_set("ethact", "eth@10004000");
332 	ut_assertok(net_loop(PING));
333 	ut_asserteq_str("eth@10002000", env_get("ethact"));
334 
335 	/* If ethrotate is no, then we should fail on a bad MAC */
336 	env_set("ethact", "eth@10004000");
337 	env_set("ethrotate", "no");
338 	ut_asserteq(-EINVAL, net_loop(PING));
339 	ut_asserteq_str("eth@10004000", env_get("ethact"));
340 
341 	return 0;
342 }
343 
_dm_test_eth_rotate2(struct unit_test_state * uts)344 static int _dm_test_eth_rotate2(struct unit_test_state *uts)
345 {
346 	/* Make sure we can skip invalid devices */
347 	env_set("ethact", "eth@10004000");
348 	ut_assertok(net_loop(PING));
349 	ut_asserteq_str("eth@10004000", env_get("ethact"));
350 
351 	/* Make sure we can handle device name which is not eth# */
352 	env_set("ethact", "sbe5");
353 	ut_assertok(net_loop(PING));
354 	ut_asserteq_str("sbe5", env_get("ethact"));
355 
356 	return 0;
357 }
358 
dm_test_eth_rotate(struct unit_test_state * uts)359 static int dm_test_eth_rotate(struct unit_test_state *uts)
360 {
361 	char ethaddr[18];
362 	int retval;
363 
364 	/* Set target IP to mock ping */
365 	net_ping_ip = string_to_ip("1.1.2.2");
366 
367 	/* Invalidate eth1's MAC address */
368 	memset(ethaddr, '\0', sizeof(ethaddr));
369 	strncpy(ethaddr, env_get("eth6addr"), 17);
370 	/* Must disable access protection for eth6addr before clearing */
371 	env_set(".flags", "eth6addr");
372 	env_set("eth6addr", NULL);
373 
374 	retval = _dm_test_eth_rotate1(uts);
375 
376 	/* Restore the env */
377 	env_set("eth6addr", ethaddr);
378 	env_set("ethrotate", NULL);
379 
380 	if (!retval) {
381 		/* Invalidate eth0's MAC address */
382 		strncpy(ethaddr, env_get("ethaddr"), 17);
383 		/* Must disable access protection for ethaddr before clearing */
384 		env_set(".flags", "ethaddr");
385 		env_set("ethaddr", NULL);
386 
387 		retval = _dm_test_eth_rotate2(uts);
388 
389 		/* Restore the env */
390 		env_set("ethaddr", ethaddr);
391 	}
392 	/* Restore the env */
393 	env_set(".flags", NULL);
394 
395 	return retval;
396 }
397 DM_TEST(dm_test_eth_rotate, UT_TESTF_SCAN_FDT);
398 
399 /* The asserts include a return on fail; cleanup in the caller */
_dm_test_net_retry(struct unit_test_state * uts)400 static int _dm_test_net_retry(struct unit_test_state *uts)
401 {
402 	/*
403 	 * eth1 is disabled and netretry is yes, so the ping should succeed and
404 	 * the active device should be eth0
405 	 */
406 	sandbox_eth_disable_response(1, true);
407 	env_set("ethact", "lan1");
408 	env_set("netretry", "yes");
409 	sandbox_eth_skip_timeout();
410 	ut_assertok(net_loop(PING));
411 	ut_asserteq_str("eth@10002000", env_get("ethact"));
412 
413 	/*
414 	 * eth1 is disabled and netretry is no, so the ping should fail and the
415 	 * active device should be eth1
416 	 */
417 	env_set("ethact", "lan1");
418 	env_set("netretry", "no");
419 	sandbox_eth_skip_timeout();
420 	ut_asserteq(-ENONET, net_loop(PING));
421 	ut_asserteq_str("lan1", env_get("ethact"));
422 
423 	return 0;
424 }
425 
dm_test_net_retry(struct unit_test_state * uts)426 static int dm_test_net_retry(struct unit_test_state *uts)
427 {
428 	int retval;
429 
430 	net_ping_ip = string_to_ip("1.1.2.2");
431 
432 	retval = _dm_test_net_retry(uts);
433 
434 	/* Restore the env */
435 	env_set("netretry", NULL);
436 	sandbox_eth_disable_response(1, false);
437 
438 	return retval;
439 }
440 DM_TEST(dm_test_net_retry, UT_TESTF_SCAN_FDT);
441 
sb_check_arp_reply(struct udevice * dev,void * packet,unsigned int len)442 static int sb_check_arp_reply(struct udevice *dev, void *packet,
443 			      unsigned int len)
444 {
445 	struct eth_sandbox_priv *priv = dev_get_priv(dev);
446 	struct ethernet_hdr *eth = packet;
447 	struct arp_hdr *arp;
448 	/* Used by all of the ut_assert macros */
449 	struct unit_test_state *uts = priv->priv;
450 
451 	if (ntohs(eth->et_protlen) != PROT_ARP)
452 		return 0;
453 
454 	arp = packet + ETHER_HDR_SIZE;
455 
456 	if (ntohs(arp->ar_op) != ARPOP_REPLY)
457 		return 0;
458 
459 	/* This test would be worthless if we are not waiting */
460 	ut_assert(arp_is_waiting());
461 
462 	/* Validate response */
463 	ut_asserteq_mem(eth->et_src, net_ethaddr, ARP_HLEN);
464 	ut_asserteq_mem(eth->et_dest, priv->fake_host_hwaddr, ARP_HLEN);
465 	ut_assert(eth->et_protlen == htons(PROT_ARP));
466 
467 	ut_assert(arp->ar_hrd == htons(ARP_ETHER));
468 	ut_assert(arp->ar_pro == htons(PROT_IP));
469 	ut_assert(arp->ar_hln == ARP_HLEN);
470 	ut_assert(arp->ar_pln == ARP_PLEN);
471 	ut_asserteq_mem(&arp->ar_sha, net_ethaddr, ARP_HLEN);
472 	ut_assert(net_read_ip(&arp->ar_spa).s_addr == net_ip.s_addr);
473 	ut_asserteq_mem(&arp->ar_tha, priv->fake_host_hwaddr, ARP_HLEN);
474 	ut_assert(net_read_ip(&arp->ar_tpa).s_addr ==
475 		  string_to_ip("1.1.2.4").s_addr);
476 
477 	return 0;
478 }
479 
sb_with_async_arp_handler(struct udevice * dev,void * packet,unsigned int len)480 static int sb_with_async_arp_handler(struct udevice *dev, void *packet,
481 				     unsigned int len)
482 {
483 	struct eth_sandbox_priv *priv = dev_get_priv(dev);
484 	struct ethernet_hdr *eth = packet;
485 	struct arp_hdr *arp = packet + ETHER_HDR_SIZE;
486 	int ret;
487 
488 	/*
489 	 * If we are about to generate a reply to ARP, first inject a request
490 	 * from another host
491 	 */
492 	if (ntohs(eth->et_protlen) == PROT_ARP &&
493 	    ntohs(arp->ar_op) == ARPOP_REQUEST) {
494 		/* Make sure sandbox_eth_recv_arp_req() knows who is asking */
495 		priv->fake_host_ipaddr = string_to_ip("1.1.2.4");
496 
497 		ret = sandbox_eth_recv_arp_req(dev);
498 		if (ret)
499 			return ret;
500 	}
501 
502 	sandbox_eth_arp_req_to_reply(dev, packet, len);
503 	sandbox_eth_ping_req_to_reply(dev, packet, len);
504 
505 	return sb_check_arp_reply(dev, packet, len);
506 }
507 
dm_test_eth_async_arp_reply(struct unit_test_state * uts)508 static int dm_test_eth_async_arp_reply(struct unit_test_state *uts)
509 {
510 	net_ping_ip = string_to_ip("1.1.2.2");
511 
512 	sandbox_eth_set_tx_handler(0, sb_with_async_arp_handler);
513 	/* Used by all of the ut_assert macros in the tx_handler */
514 	sandbox_eth_set_priv(0, uts);
515 
516 	env_set("ethact", "eth@10002000");
517 	ut_assertok(net_loop(PING));
518 	ut_asserteq_str("eth@10002000", env_get("ethact"));
519 
520 	sandbox_eth_set_tx_handler(0, NULL);
521 
522 	return 0;
523 }
524 
525 DM_TEST(dm_test_eth_async_arp_reply, UT_TESTF_SCAN_FDT);
526 
sb_check_ping_reply(struct udevice * dev,void * packet,unsigned int len)527 static int sb_check_ping_reply(struct udevice *dev, void *packet,
528 			       unsigned int len)
529 {
530 	struct eth_sandbox_priv *priv = dev_get_priv(dev);
531 	struct ethernet_hdr *eth = packet;
532 	struct ip_udp_hdr *ip;
533 	struct icmp_hdr *icmp;
534 	/* Used by all of the ut_assert macros */
535 	struct unit_test_state *uts = priv->priv;
536 
537 	if (ntohs(eth->et_protlen) != PROT_IP)
538 		return 0;
539 
540 	ip = packet + ETHER_HDR_SIZE;
541 
542 	if (ip->ip_p != IPPROTO_ICMP)
543 		return 0;
544 
545 	icmp = (struct icmp_hdr *)&ip->udp_src;
546 
547 	if (icmp->type != ICMP_ECHO_REPLY)
548 		return 0;
549 
550 	/* This test would be worthless if we are not waiting */
551 	ut_assert(arp_is_waiting());
552 
553 	/* Validate response */
554 	ut_asserteq_mem(eth->et_src, net_ethaddr, ARP_HLEN);
555 	ut_asserteq_mem(eth->et_dest, priv->fake_host_hwaddr, ARP_HLEN);
556 	ut_assert(eth->et_protlen == htons(PROT_IP));
557 
558 	ut_assert(net_read_ip(&ip->ip_src).s_addr == net_ip.s_addr);
559 	ut_assert(net_read_ip(&ip->ip_dst).s_addr ==
560 		  string_to_ip("1.1.2.4").s_addr);
561 
562 	return 0;
563 }
564 
sb_with_async_ping_handler(struct udevice * dev,void * packet,unsigned int len)565 static int sb_with_async_ping_handler(struct udevice *dev, void *packet,
566 				      unsigned int len)
567 {
568 	struct eth_sandbox_priv *priv = dev_get_priv(dev);
569 	struct ethernet_hdr *eth = packet;
570 	struct arp_hdr *arp = packet + ETHER_HDR_SIZE;
571 	int ret;
572 
573 	/*
574 	 * If we are about to generate a reply to ARP, first inject a request
575 	 * from another host
576 	 */
577 	if (ntohs(eth->et_protlen) == PROT_ARP &&
578 	    ntohs(arp->ar_op) == ARPOP_REQUEST) {
579 		/* Make sure sandbox_eth_recv_arp_req() knows who is asking */
580 		priv->fake_host_ipaddr = string_to_ip("1.1.2.4");
581 
582 		ret = sandbox_eth_recv_ping_req(dev);
583 		if (ret)
584 			return ret;
585 	}
586 
587 	sandbox_eth_arp_req_to_reply(dev, packet, len);
588 	sandbox_eth_ping_req_to_reply(dev, packet, len);
589 
590 	return sb_check_ping_reply(dev, packet, len);
591 }
592 
dm_test_eth_async_ping_reply(struct unit_test_state * uts)593 static int dm_test_eth_async_ping_reply(struct unit_test_state *uts)
594 {
595 	net_ping_ip = string_to_ip("1.1.2.2");
596 
597 	sandbox_eth_set_tx_handler(0, sb_with_async_ping_handler);
598 	/* Used by all of the ut_assert macros in the tx_handler */
599 	sandbox_eth_set_priv(0, uts);
600 
601 	env_set("ethact", "eth@10002000");
602 	ut_assertok(net_loop(PING));
603 	ut_asserteq_str("eth@10002000", env_get("ethact"));
604 
605 	sandbox_eth_set_tx_handler(0, NULL);
606 
607 	return 0;
608 }
609 
610 DM_TEST(dm_test_eth_async_ping_reply, UT_TESTF_SCAN_FDT);
611 
612 #if IS_ENABLED(CONFIG_IPV6_ROUTER_DISCOVERY)
613 
614 static u8 ip6_ra_buf[] = {0x60, 0xf, 0xc5, 0x4a, 0x0, 0x38, 0x3a, 0xff, 0xfe,
615 			  0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x85, 0xe6,
616 			  0x29, 0x77, 0xcb, 0xc8, 0x53, 0xff, 0x2, 0x0, 0x0,
617 			  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
618 			  0x1, 0x86, 0x0, 0xdc, 0x90, 0x40, 0x80, 0x15, 0x18,
619 			  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x4,
620 			  0x40, 0xc0, 0x0, 0x0, 0x37, 0xdc, 0x0, 0x0, 0x37,
621 			  0x78, 0x0, 0x0, 0x0, 0x0, 0x20, 0x1, 0xca, 0xfe, 0xca,
622 			  0xfe, 0xca, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
623 			  0x0, 0x1, 0x1, 0x0, 0x15, 0x5d, 0xe2, 0x8a, 0x2};
624 
dm_test_validate_ra(struct unit_test_state * uts)625 static int dm_test_validate_ra(struct unit_test_state *uts)
626 {
627 	struct ip6_hdr *ip6 = (struct ip6_hdr *)ip6_ra_buf;
628 	struct icmp6hdr *icmp = (struct icmp6hdr *)(ip6 + 1);
629 	__be16 temp = 0;
630 
631 	ut_assert(validate_ra(ip6) == true);
632 
633 	temp = ip6->payload_len;
634 	ip6->payload_len = 15;
635 	ut_assert(validate_ra(ip6) == false);
636 	ip6->payload_len = temp;
637 
638 	temp = ip6->saddr.s6_addr16[0];
639 	ip6->saddr.s6_addr16[0] = 0x2001;
640 	ut_assert(validate_ra(ip6) == false);
641 	ip6->saddr.s6_addr16[0] = temp;
642 
643 	temp = ip6->hop_limit;
644 	ip6->hop_limit = 15;
645 	ut_assert(validate_ra(ip6) == false);
646 	ip6->hop_limit = temp;
647 
648 	temp = icmp->icmp6_code;
649 	icmp->icmp6_code = 15;
650 	ut_assert(validate_ra(ip6) == false);
651 	icmp->icmp6_code = temp;
652 
653 	return 0;
654 }
655 
656 DM_TEST(dm_test_validate_ra, 0);
657 
dm_test_process_ra(struct unit_test_state * uts)658 static int dm_test_process_ra(struct unit_test_state *uts)
659 {
660 	int len = sizeof(ip6_ra_buf);
661 	struct ip6_hdr *ip6 = (struct ip6_hdr *)ip6_ra_buf;
662 	struct icmp6hdr *icmp = (struct icmp6hdr *)(ip6 + 1);
663 	struct ra_msg *msg = (struct ra_msg *)icmp;
664 	unsigned char *option = msg->opt;
665 	struct icmp6_ra_prefix_info *prefix =
666 					(struct icmp6_ra_prefix_info *)option;
667 	__be16 temp = 0;
668 	unsigned char option_len = option[1];
669 
670 	ut_assert(process_ra(ip6, len) == 0);
671 
672 	temp = icmp->icmp6_rt_lifetime;
673 	icmp->icmp6_rt_lifetime = 0;
674 	ut_assert(process_ra(ip6, len) != 0);
675 	icmp->icmp6_rt_lifetime = temp;
676 
677 	ut_assert(process_ra(ip6, 0) != 0);
678 
679 	option[1] = 0;
680 	ut_assert(process_ra(ip6, len) != 0);
681 	option[1] = option_len;
682 
683 	prefix->on_link = false;
684 	ut_assert(process_ra(ip6, len) != 0);
685 	prefix->on_link = true;
686 
687 	temp = prefix->prefix.s6_addr16[0];
688 	prefix->prefix.s6_addr16[0] = 0x80fe;
689 	ut_assert(process_ra(ip6, len) != 0);
690 	prefix->prefix.s6_addr16[0] = temp;
691 
692 	return 0;
693 }
694 
695 DM_TEST(dm_test_process_ra, 0);
696 
697 #endif
698