Prepare v2023.10
[platform/kernel/u-boot.git] / test / dm / eth.c
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)
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
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
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
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
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
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
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
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  */
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 */
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 */
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
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
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 */
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
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
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
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
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
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
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
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
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
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