blob: b58c9640a277618ac994c756ab701ef9f5a24ab5 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0
Joe Hershbergerbfacad72015-03-22 17:09:15 -05002/*
3 * Copyright (c) 2015 National Instruments
4 *
5 * (C) Copyright 2015
6 * Joe Hershberger <joe.hershberger@ni.com>
Joe Hershbergerbfacad72015-03-22 17:09:15 -05007 */
8
9#include <common.h>
10#include <dm.h>
Simon Glass9fb625c2019-08-01 09:46:51 -060011#include <env.h>
Joe Hershbergerbfacad72015-03-22 17:09:15 -050012#include <fdtdec.h>
Simon Glassf7ae49f2020-05-10 11:40:05 -060013#include <log.h>
Joe Hershbergerbfacad72015-03-22 17:09:15 -050014#include <malloc.h>
15#include <net.h>
Joe Hershbergere721b882015-05-20 14:27:27 -050016#include <dm/test.h>
Bin Meng6d9764c2015-10-07 21:45:43 -070017#include <dm/device-internal.h>
18#include <dm/uclass-internal.h>
Joe Hershberger7ece1c62015-03-22 17:09:20 -050019#include <asm/eth.h>
Joe Hershbergere721b882015-05-20 14:27:27 -050020#include <test/ut.h>
Joe Hershbergerbfacad72015-03-22 17:09:15 -050021
Bin Meng6d9764c2015-10-07 21:45:43 -070022#define DM_TEST_ETH_NUM 4
23
Joe Hershbergere721b882015-05-20 14:27:27 -050024static int dm_test_eth(struct unit_test_state *uts)
Joe Hershbergerbfacad72015-03-22 17:09:15 -050025{
Joe Hershberger049a95a2015-04-08 01:41:01 -050026 net_ping_ip = string_to_ip("1.1.2.2");
Joe Hershbergerbfacad72015-03-22 17:09:15 -050027
Simon Glass382bee52017-08-03 12:22:09 -060028 env_set("ethact", "eth@10002000");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -050029 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -060030 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershbergerbfacad72015-03-22 17:09:15 -050031
Simon Glass382bee52017-08-03 12:22:09 -060032 env_set("ethact", "eth@10003000");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -050033 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -060034 ut_asserteq_str("eth@10003000", env_get("ethact"));
Joe Hershbergerbfacad72015-03-22 17:09:15 -050035
Simon Glass382bee52017-08-03 12:22:09 -060036 env_set("ethact", "eth@10004000");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -050037 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -060038 ut_asserteq_str("eth@10004000", env_get("ethact"));
Joe Hershbergerbfacad72015-03-22 17:09:15 -050039
40 return 0;
41}
42DM_TEST(dm_test_eth, DM_TESTF_SCAN_FDT);
Joe Hershbergere58780d2015-03-22 17:09:16 -050043
Joe Hershbergere721b882015-05-20 14:27:27 -050044static int dm_test_eth_alias(struct unit_test_state *uts)
Joe Hershbergere58780d2015-03-22 17:09:16 -050045{
Joe Hershberger049a95a2015-04-08 01:41:01 -050046 net_ping_ip = string_to_ip("1.1.2.2");
Simon Glass382bee52017-08-03 12:22:09 -060047 env_set("ethact", "eth0");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -050048 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -060049 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershbergere58780d2015-03-22 17:09:16 -050050
Michael Wallebe1a6e92020-06-02 01:47:09 +020051 env_set("ethact", "eth6");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -050052 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -060053 ut_asserteq_str("eth@10004000", env_get("ethact"));
Joe Hershbergere58780d2015-03-22 17:09:16 -050054
55 /* Expected to fail since eth2 is not defined in the device tree */
Simon Glass382bee52017-08-03 12:22:09 -060056 env_set("ethact", "eth2");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -050057 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -060058 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershbergere58780d2015-03-22 17:09:16 -050059
Simon Glass382bee52017-08-03 12:22:09 -060060 env_set("ethact", "eth5");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -050061 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -060062 ut_asserteq_str("eth@10003000", env_get("ethact"));
Joe Hershbergere58780d2015-03-22 17:09:16 -050063
64 return 0;
65}
66DM_TEST(dm_test_eth_alias, DM_TESTF_SCAN_FDT);
Joe Hershberger6536b9b2015-03-22 17:09:17 -050067
Joe Hershbergere721b882015-05-20 14:27:27 -050068static int dm_test_eth_prime(struct unit_test_state *uts)
Joe Hershberger6536b9b2015-03-22 17:09:17 -050069{
Joe Hershberger049a95a2015-04-08 01:41:01 -050070 net_ping_ip = string_to_ip("1.1.2.2");
Joe Hershberger6536b9b2015-03-22 17:09:17 -050071
72 /* Expected to be "eth@10003000" because of ethprime variable */
Simon Glass382bee52017-08-03 12:22:09 -060073 env_set("ethact", NULL);
74 env_set("ethprime", "eth5");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -050075 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -060076 ut_asserteq_str("eth@10003000", env_get("ethact"));
Joe Hershberger6536b9b2015-03-22 17:09:17 -050077
78 /* Expected to be "eth@10002000" because it is first */
Simon Glass382bee52017-08-03 12:22:09 -060079 env_set("ethact", NULL);
80 env_set("ethprime", NULL);
Joe Hershbergerbc0571f2015-04-08 01:41:21 -050081 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -060082 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershberger6536b9b2015-03-22 17:09:17 -050083
84 return 0;
85}
86DM_TEST(dm_test_eth_prime, DM_TESTF_SCAN_FDT);
Joe Hershberger7d104ea2015-03-22 17:09:18 -050087
Bin Meng6d9764c2015-10-07 21:45:43 -070088/**
89 * This test case is trying to test the following scenario:
90 * - All ethernet devices are not probed
91 * - "ethaddr" for all ethernet devices are not set
92 * - "ethact" is set to a valid ethernet device name
93 *
94 * With Sandbox default test configuration, all ethernet devices are
95 * probed after power-up, so we have to manually create such scenario:
96 * - Remove all ethernet devices
97 * - Remove all "ethaddr" environment variables
98 * - Set "ethact" to the first ethernet device
99 *
100 * Do a ping test to see if anything goes wrong.
101 */
102static int dm_test_eth_act(struct unit_test_state *uts)
103{
104 struct udevice *dev[DM_TEST_ETH_NUM];
105 const char *ethname[DM_TEST_ETH_NUM] = {"eth@10002000", "eth@10003000",
106 "sbe5", "eth@10004000"};
107 const char *addrname[DM_TEST_ETH_NUM] = {"ethaddr", "eth5addr",
Michael Wallebe1a6e92020-06-02 01:47:09 +0200108 "eth3addr", "eth6addr"};
Bin Meng6d9764c2015-10-07 21:45:43 -0700109 char ethaddr[DM_TEST_ETH_NUM][18];
110 int i;
111
Tom Rinie2e6dae2017-09-26 14:08:30 -0400112 memset(ethaddr, '\0', sizeof(ethaddr));
Bin Meng6d9764c2015-10-07 21:45:43 -0700113 net_ping_ip = string_to_ip("1.1.2.2");
114
115 /* Prepare the test scenario */
116 for (i = 0; i < DM_TEST_ETH_NUM; i++) {
117 ut_assertok(uclass_find_device_by_name(UCLASS_ETH,
118 ethname[i], &dev[i]));
Stefan Roese706865a2017-03-20 12:51:48 +0100119 ut_assertok(device_remove(dev[i], DM_REMOVE_NORMAL));
Bin Meng6d9764c2015-10-07 21:45:43 -0700120
121 /* Invalidate MAC address */
Tom Rinie2e6dae2017-09-26 14:08:30 -0400122 strncpy(ethaddr[i], env_get(addrname[i]), 17);
Bin Meng6d9764c2015-10-07 21:45:43 -0700123 /* Must disable access protection for ethaddr before clearing */
Simon Glass382bee52017-08-03 12:22:09 -0600124 env_set(".flags", addrname[i]);
125 env_set(addrname[i], NULL);
Bin Meng6d9764c2015-10-07 21:45:43 -0700126 }
127
128 /* Set ethact to "eth@10002000" */
Simon Glass382bee52017-08-03 12:22:09 -0600129 env_set("ethact", ethname[0]);
Bin Meng6d9764c2015-10-07 21:45:43 -0700130
131 /* Segment fault might happen if something is wrong */
132 ut_asserteq(-ENODEV, net_loop(PING));
133
134 for (i = 0; i < DM_TEST_ETH_NUM; i++) {
135 /* Restore the env */
Simon Glass382bee52017-08-03 12:22:09 -0600136 env_set(".flags", addrname[i]);
137 env_set(addrname[i], ethaddr[i]);
Bin Meng6d9764c2015-10-07 21:45:43 -0700138
139 /* Probe the device again */
140 ut_assertok(device_probe(dev[i]));
141 }
Simon Glass382bee52017-08-03 12:22:09 -0600142 env_set(".flags", NULL);
143 env_set("ethact", NULL);
Bin Meng6d9764c2015-10-07 21:45:43 -0700144
145 return 0;
146}
147DM_TEST(dm_test_eth_act, DM_TESTF_SCAN_FDT);
148
Joe Hershberger09129be2015-05-20 14:27:33 -0500149/* The asserts include a return on fail; cleanup in the caller */
150static int _dm_test_eth_rotate1(struct unit_test_state *uts)
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500151{
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500152 /* Make sure that the default is to rotate to the next interface */
Simon Glass382bee52017-08-03 12:22:09 -0600153 env_set("ethact", "eth@10004000");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500154 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600155 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500156
157 /* If ethrotate is no, then we should fail on a bad MAC */
Simon Glass382bee52017-08-03 12:22:09 -0600158 env_set("ethact", "eth@10004000");
159 env_set("ethrotate", "no");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500160 ut_asserteq(-EINVAL, net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600161 ut_asserteq_str("eth@10004000", env_get("ethact"));
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500162
Joe Hershberger09129be2015-05-20 14:27:33 -0500163 return 0;
164}
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500165
Joe Hershberger09129be2015-05-20 14:27:33 -0500166static int _dm_test_eth_rotate2(struct unit_test_state *uts)
167{
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500168 /* Make sure we can skip invalid devices */
Simon Glass382bee52017-08-03 12:22:09 -0600169 env_set("ethact", "eth@10004000");
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500170 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600171 ut_asserteq_str("eth@10004000", env_get("ethact"));
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500172
Bin Meng71d79712015-08-27 22:25:53 -0700173 /* Make sure we can handle device name which is not eth# */
Simon Glass382bee52017-08-03 12:22:09 -0600174 env_set("ethact", "sbe5");
Bin Meng71d79712015-08-27 22:25:53 -0700175 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600176 ut_asserteq_str("sbe5", env_get("ethact"));
Bin Meng71d79712015-08-27 22:25:53 -0700177
Joe Hershberger09129be2015-05-20 14:27:33 -0500178 return 0;
179}
180
181static int dm_test_eth_rotate(struct unit_test_state *uts)
182{
183 char ethaddr[18];
184 int retval;
185
186 /* Set target IP to mock ping */
187 net_ping_ip = string_to_ip("1.1.2.2");
188
189 /* Invalidate eth1's MAC address */
Tom Rinie2e6dae2017-09-26 14:08:30 -0400190 memset(ethaddr, '\0', sizeof(ethaddr));
Michael Wallebe1a6e92020-06-02 01:47:09 +0200191 strncpy(ethaddr, env_get("eth6addr"), 17);
192 /* Must disable access protection for eth6addr before clearing */
193 env_set(".flags", "eth6addr");
194 env_set("eth6addr", NULL);
Joe Hershberger09129be2015-05-20 14:27:33 -0500195
196 retval = _dm_test_eth_rotate1(uts);
197
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500198 /* Restore the env */
Michael Wallebe1a6e92020-06-02 01:47:09 +0200199 env_set("eth6addr", ethaddr);
Simon Glass382bee52017-08-03 12:22:09 -0600200 env_set("ethrotate", NULL);
Joe Hershberger09129be2015-05-20 14:27:33 -0500201
202 if (!retval) {
203 /* Invalidate eth0's MAC address */
Tom Rinie2e6dae2017-09-26 14:08:30 -0400204 strncpy(ethaddr, env_get("ethaddr"), 17);
Joe Hershberger09129be2015-05-20 14:27:33 -0500205 /* Must disable access protection for ethaddr before clearing */
Simon Glass382bee52017-08-03 12:22:09 -0600206 env_set(".flags", "ethaddr");
207 env_set("ethaddr", NULL);
Joe Hershberger09129be2015-05-20 14:27:33 -0500208
209 retval = _dm_test_eth_rotate2(uts);
210
211 /* Restore the env */
Simon Glass382bee52017-08-03 12:22:09 -0600212 env_set("ethaddr", ethaddr);
Joe Hershberger09129be2015-05-20 14:27:33 -0500213 }
214 /* Restore the env */
Simon Glass382bee52017-08-03 12:22:09 -0600215 env_set(".flags", NULL);
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500216
Joe Hershberger09129be2015-05-20 14:27:33 -0500217 return retval;
Joe Hershberger7d104ea2015-03-22 17:09:18 -0500218}
219DM_TEST(dm_test_eth_rotate, DM_TESTF_SCAN_FDT);
Joe Hershberger7ece1c62015-03-22 17:09:20 -0500220
Joe Hershberger09129be2015-05-20 14:27:33 -0500221/* The asserts include a return on fail; cleanup in the caller */
222static int _dm_test_net_retry(struct unit_test_state *uts)
Joe Hershberger7ece1c62015-03-22 17:09:20 -0500223{
Joe Hershberger7ece1c62015-03-22 17:09:20 -0500224 /*
225 * eth1 is disabled and netretry is yes, so the ping should succeed and
226 * the active device should be eth0
227 */
228 sandbox_eth_disable_response(1, true);
Simon Glass382bee52017-08-03 12:22:09 -0600229 env_set("ethact", "eth@10004000");
230 env_set("netretry", "yes");
Joe Hershberger172a31b2015-04-21 13:57:20 -0500231 sandbox_eth_skip_timeout();
Joe Hershbergerbc0571f2015-04-08 01:41:21 -0500232 ut_assertok(net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600233 ut_asserteq_str("eth@10002000", env_get("ethact"));
Joe Hershberger7ece1c62015-03-22 17:09:20 -0500234
235 /*
236 * eth1 is disabled and netretry is no, so the ping should fail and the
237 * active device should be eth1
238 */
Simon Glass382bee52017-08-03 12:22:09 -0600239 env_set("ethact", "eth@10004000");
240 env_set("netretry", "no");
Joe Hershberger172a31b2015-04-21 13:57:20 -0500241 sandbox_eth_skip_timeout();
Thomas RIENOESSLa735e6e2018-11-21 15:56:07 +0100242 ut_asserteq(-ENONET, net_loop(PING));
Simon Glass00caae62017-08-03 12:22:12 -0600243 ut_asserteq_str("eth@10004000", env_get("ethact"));
Joe Hershberger7ece1c62015-03-22 17:09:20 -0500244
Joe Hershberger09129be2015-05-20 14:27:33 -0500245 return 0;
246}
247
248static int dm_test_net_retry(struct unit_test_state *uts)
249{
250 int retval;
251
252 net_ping_ip = string_to_ip("1.1.2.2");
253
254 retval = _dm_test_net_retry(uts);
255
Joe Hershberger7ece1c62015-03-22 17:09:20 -0500256 /* Restore the env */
Simon Glass382bee52017-08-03 12:22:09 -0600257 env_set("netretry", NULL);
Joe Hershberger7ece1c62015-03-22 17:09:20 -0500258 sandbox_eth_disable_response(1, false);
259
Joe Hershberger09129be2015-05-20 14:27:33 -0500260 return retval;
Joe Hershberger7ece1c62015-03-22 17:09:20 -0500261}
262DM_TEST(dm_test_net_retry, DM_TESTF_SCAN_FDT);
Joe Hershberger45988da2018-09-26 16:49:00 -0500263
264static int sb_check_arp_reply(struct udevice *dev, void *packet,
265 unsigned int len)
266{
267 struct eth_sandbox_priv *priv = dev_get_priv(dev);
268 struct ethernet_hdr *eth = packet;
269 struct arp_hdr *arp;
270 /* Used by all of the ut_assert macros */
271 struct unit_test_state *uts = priv->priv;
272
273 if (ntohs(eth->et_protlen) != PROT_ARP)
274 return 0;
275
276 arp = packet + ETHER_HDR_SIZE;
277
278 if (ntohs(arp->ar_op) != ARPOP_REPLY)
279 return 0;
280
281 /* This test would be worthless if we are not waiting */
282 ut_assert(arp_is_waiting());
283
284 /* Validate response */
Simon Glassf91f3662020-05-10 12:52:45 -0600285 ut_asserteq_mem(eth->et_src, net_ethaddr, ARP_HLEN);
286 ut_asserteq_mem(eth->et_dest, priv->fake_host_hwaddr, ARP_HLEN);
Joe Hershberger45988da2018-09-26 16:49:00 -0500287 ut_assert(eth->et_protlen == htons(PROT_ARP));
288
289 ut_assert(arp->ar_hrd == htons(ARP_ETHER));
290 ut_assert(arp->ar_pro == htons(PROT_IP));
291 ut_assert(arp->ar_hln == ARP_HLEN);
292 ut_assert(arp->ar_pln == ARP_PLEN);
Simon Glassf91f3662020-05-10 12:52:45 -0600293 ut_asserteq_mem(&arp->ar_sha, net_ethaddr, ARP_HLEN);
Joe Hershberger45988da2018-09-26 16:49:00 -0500294 ut_assert(net_read_ip(&arp->ar_spa).s_addr == net_ip.s_addr);
Simon Glassf91f3662020-05-10 12:52:45 -0600295 ut_asserteq_mem(&arp->ar_tha, priv->fake_host_hwaddr, ARP_HLEN);
Joe Hershberger45988da2018-09-26 16:49:00 -0500296 ut_assert(net_read_ip(&arp->ar_tpa).s_addr ==
297 string_to_ip("1.1.2.4").s_addr);
298
299 return 0;
300}
301
302static int sb_with_async_arp_handler(struct udevice *dev, void *packet,
303 unsigned int len)
304{
305 struct eth_sandbox_priv *priv = dev_get_priv(dev);
306 struct ethernet_hdr *eth = packet;
307 struct arp_hdr *arp = packet + ETHER_HDR_SIZE;
308 int ret;
309
310 /*
311 * If we are about to generate a reply to ARP, first inject a request
312 * from another host
313 */
314 if (ntohs(eth->et_protlen) == PROT_ARP &&
315 ntohs(arp->ar_op) == ARPOP_REQUEST) {
316 /* Make sure sandbox_eth_recv_arp_req() knows who is asking */
317 priv->fake_host_ipaddr = string_to_ip("1.1.2.4");
318
319 ret = sandbox_eth_recv_arp_req(dev);
320 if (ret)
321 return ret;
322 }
323
324 sandbox_eth_arp_req_to_reply(dev, packet, len);
325 sandbox_eth_ping_req_to_reply(dev, packet, len);
326
327 return sb_check_arp_reply(dev, packet, len);
328}
329
330static int dm_test_eth_async_arp_reply(struct unit_test_state *uts)
331{
332 net_ping_ip = string_to_ip("1.1.2.2");
333
334 sandbox_eth_set_tx_handler(0, sb_with_async_arp_handler);
335 /* Used by all of the ut_assert macros in the tx_handler */
336 sandbox_eth_set_priv(0, uts);
Joe Hershberger45988da2018-09-26 16:49:00 -0500337
338 env_set("ethact", "eth@10002000");
Joe Hershbergerac3f26c2018-09-26 16:49:02 -0500339 ut_assertok(net_loop(PING));
Joe Hershberger45988da2018-09-26 16:49:00 -0500340 ut_asserteq_str("eth@10002000", env_get("ethact"));
341
342 sandbox_eth_set_tx_handler(0, NULL);
343
344 return 0;
345}
346
347DM_TEST(dm_test_eth_async_arp_reply, DM_TESTF_SCAN_FDT);
Joe Hershberger72ff0042018-09-26 16:49:01 -0500348
349static int sb_check_ping_reply(struct udevice *dev, void *packet,
350 unsigned int len)
351{
352 struct eth_sandbox_priv *priv = dev_get_priv(dev);
353 struct ethernet_hdr *eth = packet;
354 struct ip_udp_hdr *ip;
355 struct icmp_hdr *icmp;
356 /* Used by all of the ut_assert macros */
357 struct unit_test_state *uts = priv->priv;
358
359 if (ntohs(eth->et_protlen) != PROT_IP)
360 return 0;
361
362 ip = packet + ETHER_HDR_SIZE;
363
364 if (ip->ip_p != IPPROTO_ICMP)
365 return 0;
366
367 icmp = (struct icmp_hdr *)&ip->udp_src;
368
369 if (icmp->type != ICMP_ECHO_REPLY)
370 return 0;
371
372 /* This test would be worthless if we are not waiting */
373 ut_assert(arp_is_waiting());
374
375 /* Validate response */
Simon Glassf91f3662020-05-10 12:52:45 -0600376 ut_asserteq_mem(eth->et_src, net_ethaddr, ARP_HLEN);
377 ut_asserteq_mem(eth->et_dest, priv->fake_host_hwaddr, ARP_HLEN);
Joe Hershberger72ff0042018-09-26 16:49:01 -0500378 ut_assert(eth->et_protlen == htons(PROT_IP));
379
380 ut_assert(net_read_ip(&ip->ip_src).s_addr == net_ip.s_addr);
381 ut_assert(net_read_ip(&ip->ip_dst).s_addr ==
382 string_to_ip("1.1.2.4").s_addr);
383
384 return 0;
385}
386
387static int sb_with_async_ping_handler(struct udevice *dev, void *packet,
388 unsigned int len)
389{
390 struct eth_sandbox_priv *priv = dev_get_priv(dev);
391 struct ethernet_hdr *eth = packet;
392 struct arp_hdr *arp = packet + ETHER_HDR_SIZE;
393 int ret;
394
395 /*
396 * If we are about to generate a reply to ARP, first inject a request
397 * from another host
398 */
399 if (ntohs(eth->et_protlen) == PROT_ARP &&
400 ntohs(arp->ar_op) == ARPOP_REQUEST) {
401 /* Make sure sandbox_eth_recv_arp_req() knows who is asking */
402 priv->fake_host_ipaddr = string_to_ip("1.1.2.4");
403
404 ret = sandbox_eth_recv_ping_req(dev);
405 if (ret)
406 return ret;
407 }
408
409 sandbox_eth_arp_req_to_reply(dev, packet, len);
410 sandbox_eth_ping_req_to_reply(dev, packet, len);
411
412 return sb_check_ping_reply(dev, packet, len);
413}
414
415static int dm_test_eth_async_ping_reply(struct unit_test_state *uts)
416{
417 net_ping_ip = string_to_ip("1.1.2.2");
418
419 sandbox_eth_set_tx_handler(0, sb_with_async_ping_handler);
420 /* Used by all of the ut_assert macros in the tx_handler */
421 sandbox_eth_set_priv(0, uts);
Joe Hershberger72ff0042018-09-26 16:49:01 -0500422
423 env_set("ethact", "eth@10002000");
Joe Hershbergerac3f26c2018-09-26 16:49:02 -0500424 ut_assertok(net_loop(PING));
Joe Hershberger72ff0042018-09-26 16:49:01 -0500425 ut_asserteq_str("eth@10002000", env_get("ethact"));
426
427 sandbox_eth_set_tx_handler(0, NULL);
428
429 return 0;
430}
431
432DM_TEST(dm_test_eth_async_ping_reply, DM_TESTF_SCAN_FDT);