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