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