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) 28static 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} 78DM_TEST(dm_test_string_to_ip6, 0); 79 80static 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} 107DM_TEST(dm_test_csum_ipv6_magic, 0); 108 109static 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} 132DM_TEST(dm_test_ip6_addr_in_subnet, 0); 133 134static 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} 152DM_TEST(dm_test_ip6_make_snma, 0); 153 154static 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} 170DM_TEST(dm_test_ip6_make_lladdr, UT_TESTF_SCAN_FDT); 171#endif 172 173static 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} 191DM_TEST(dm_test_eth, UT_TESTF_SCAN_FDT); 192 193static 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} 215DM_TEST(dm_test_eth_alias, UT_TESTF_SCAN_FDT); 216 217static 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} 235DM_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 */ 251static 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 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(-ENODEV, net_loop(PING)); 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} 300DM_TEST(dm_test_eth_act, UT_TESTF_SCAN_FDT); 301 302/* Ensure that all addresses are loaded properly */ 303static 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} 333DM_TEST(dm_test_ethaddr, UT_TESTF_SCAN_FDT); 334 335/* The asserts include a return on fail; cleanup in the caller */ 336static int _dm_test_eth_rotate1(struct unit_test_state *uts) 337{ 338 /* Make sure that the default is to rotate to the next interface */ 339 env_set("ethact", "eth@10004000"); 340 ut_assertok(net_loop(PING)); 341 ut_asserteq_str("eth@10002000", env_get("ethact")); 342 343 /* If ethrotate is no, then we should fail on a bad MAC */ 344 env_set("ethact", "eth@10004000"); 345 env_set("ethrotate", "no"); 346 ut_asserteq(-EINVAL, net_loop(PING)); 347 ut_asserteq_str("eth@10004000", env_get("ethact")); 348 349 return 0; 350} 351 352static int _dm_test_eth_rotate2(struct unit_test_state *uts) 353{ 354 /* Make sure we can skip invalid devices */ 355 env_set("ethact", "eth@10004000"); 356 ut_assertok(net_loop(PING)); 357 ut_asserteq_str("eth@10004000", env_get("ethact")); 358 359 /* Make sure we can handle device name which is not eth# */ 360 env_set("ethact", "sbe5"); 361 ut_assertok(net_loop(PING)); 362 ut_asserteq_str("sbe5", env_get("ethact")); 363 364 return 0; 365} 366 367static int dm_test_eth_rotate(struct unit_test_state *uts) 368{ 369 char ethaddr[18]; 370 int retval; 371 372 /* Set target IP to mock ping */ 373 net_ping_ip = string_to_ip("1.1.2.2"); 374 375 /* Invalidate eth1's MAC address */ 376 memset(ethaddr, '\0', sizeof(ethaddr)); 377 strncpy(ethaddr, env_get("eth6addr"), 17); 378 /* Must disable access protection for eth6addr before clearing */ 379 env_set(".flags", "eth6addr"); 380 env_set("eth6addr", NULL); 381 382 retval = _dm_test_eth_rotate1(uts); 383 384 /* Restore the env */ 385 env_set("eth6addr", ethaddr); 386 env_set("ethrotate", NULL); 387 388 if (!retval) { 389 /* Invalidate eth0's MAC address */ 390 strncpy(ethaddr, env_get("ethaddr"), 17); 391 /* Must disable access protection for ethaddr before clearing */ 392 env_set(".flags", "ethaddr"); 393 env_set("ethaddr", NULL); 394 395 retval = _dm_test_eth_rotate2(uts); 396 397 /* Restore the env */ 398 env_set("ethaddr", ethaddr); 399 } 400 /* Restore the env */ 401 env_set(".flags", NULL); 402 403 return retval; 404} 405DM_TEST(dm_test_eth_rotate, UT_TESTF_SCAN_FDT); 406 407/* The asserts include a return on fail; cleanup in the caller */ 408static int _dm_test_net_retry(struct unit_test_state *uts) 409{ 410 /* 411 * eth1 is disabled and netretry is yes, so the ping should succeed and 412 * the active device should be eth0 413 */ 414 sandbox_eth_disable_response(1, true); 415 env_set("ethact", "lan1"); 416 env_set("netretry", "yes"); 417 sandbox_eth_skip_timeout(); 418 ut_assertok(net_loop(PING)); 419 ut_asserteq_str("eth@10002000", env_get("ethact")); 420 421 /* 422 * eth1 is disabled and netretry is no, so the ping should fail and the 423 * active device should be eth1 424 */ 425 env_set("ethact", "lan1"); 426 env_set("netretry", "no"); 427 sandbox_eth_skip_timeout(); 428 ut_asserteq(-ENONET, net_loop(PING)); 429 ut_asserteq_str("lan1", env_get("ethact")); 430 431 return 0; 432} 433 434static int dm_test_net_retry(struct unit_test_state *uts) 435{ 436 int retval; 437 438 net_ping_ip = string_to_ip("1.1.2.2"); 439 440 retval = _dm_test_net_retry(uts); 441 442 /* Restore the env */ 443 env_set("netretry", NULL); 444 sandbox_eth_disable_response(1, false); 445 446 return retval; 447} 448DM_TEST(dm_test_net_retry, UT_TESTF_SCAN_FDT); 449 450static int sb_check_arp_reply(struct udevice *dev, void *packet, 451 unsigned int len) 452{ 453 struct eth_sandbox_priv *priv = dev_get_priv(dev); 454 struct ethernet_hdr *eth = packet; 455 struct arp_hdr *arp; 456 /* Used by all of the ut_assert macros */ 457 struct unit_test_state *uts = priv->priv; 458 459 if (ntohs(eth->et_protlen) != PROT_ARP) 460 return 0; 461 462 arp = packet + ETHER_HDR_SIZE; 463 464 if (ntohs(arp->ar_op) != ARPOP_REPLY) 465 return 0; 466 467 /* This test would be worthless if we are not waiting */ 468 ut_assert(arp_is_waiting()); 469 470 /* Validate response */ 471 ut_asserteq_mem(eth->et_src, net_ethaddr, ARP_HLEN); 472 ut_asserteq_mem(eth->et_dest, priv->fake_host_hwaddr, ARP_HLEN); 473 ut_assert(eth->et_protlen == htons(PROT_ARP)); 474 475 ut_assert(arp->ar_hrd == htons(ARP_ETHER)); 476 ut_assert(arp->ar_pro == htons(PROT_IP)); 477 ut_assert(arp->ar_hln == ARP_HLEN); 478 ut_assert(arp->ar_pln == ARP_PLEN); 479 ut_asserteq_mem(&arp->ar_sha, net_ethaddr, ARP_HLEN); 480 ut_assert(net_read_ip(&arp->ar_spa).s_addr == net_ip.s_addr); 481 ut_asserteq_mem(&arp->ar_tha, priv->fake_host_hwaddr, ARP_HLEN); 482 ut_assert(net_read_ip(&arp->ar_tpa).s_addr == 483 string_to_ip("1.1.2.4").s_addr); 484 485 return 0; 486} 487 488static int sb_with_async_arp_handler(struct udevice *dev, void *packet, 489 unsigned int len) 490{ 491 struct eth_sandbox_priv *priv = dev_get_priv(dev); 492 struct ethernet_hdr *eth = packet; 493 struct arp_hdr *arp = packet + ETHER_HDR_SIZE; 494 int ret; 495 496 /* 497 * If we are about to generate a reply to ARP, first inject a request 498 * from another host 499 */ 500 if (ntohs(eth->et_protlen) == PROT_ARP && 501 ntohs(arp->ar_op) == ARPOP_REQUEST) { 502 /* Make sure sandbox_eth_recv_arp_req() knows who is asking */ 503 priv->fake_host_ipaddr = string_to_ip("1.1.2.4"); 504 505 ret = sandbox_eth_recv_arp_req(dev); 506 if (ret) 507 return ret; 508 } 509 510 sandbox_eth_arp_req_to_reply(dev, packet, len); 511 sandbox_eth_ping_req_to_reply(dev, packet, len); 512 513 return sb_check_arp_reply(dev, packet, len); 514} 515 516static int dm_test_eth_async_arp_reply(struct unit_test_state *uts) 517{ 518 net_ping_ip = string_to_ip("1.1.2.2"); 519 520 sandbox_eth_set_tx_handler(0, sb_with_async_arp_handler); 521 /* Used by all of the ut_assert macros in the tx_handler */ 522 sandbox_eth_set_priv(0, uts); 523 524 env_set("ethact", "eth@10002000"); 525 ut_assertok(net_loop(PING)); 526 ut_asserteq_str("eth@10002000", env_get("ethact")); 527 528 sandbox_eth_set_tx_handler(0, NULL); 529 530 return 0; 531} 532 533DM_TEST(dm_test_eth_async_arp_reply, UT_TESTF_SCAN_FDT); 534 535static int sb_check_ping_reply(struct udevice *dev, void *packet, 536 unsigned int len) 537{ 538 struct eth_sandbox_priv *priv = dev_get_priv(dev); 539 struct ethernet_hdr *eth = packet; 540 struct ip_udp_hdr *ip; 541 struct icmp_hdr *icmp; 542 /* Used by all of the ut_assert macros */ 543 struct unit_test_state *uts = priv->priv; 544 545 if (ntohs(eth->et_protlen) != PROT_IP) 546 return 0; 547 548 ip = packet + ETHER_HDR_SIZE; 549 550 if (ip->ip_p != IPPROTO_ICMP) 551 return 0; 552 553 icmp = (struct icmp_hdr *)&ip->udp_src; 554 555 if (icmp->type != ICMP_ECHO_REPLY) 556 return 0; 557 558 /* This test would be worthless if we are not waiting */ 559 ut_assert(arp_is_waiting()); 560 561 /* Validate response */ 562 ut_asserteq_mem(eth->et_src, net_ethaddr, ARP_HLEN); 563 ut_asserteq_mem(eth->et_dest, priv->fake_host_hwaddr, ARP_HLEN); 564 ut_assert(eth->et_protlen == htons(PROT_IP)); 565 566 ut_assert(net_read_ip(&ip->ip_src).s_addr == net_ip.s_addr); 567 ut_assert(net_read_ip(&ip->ip_dst).s_addr == 568 string_to_ip("1.1.2.4").s_addr); 569 570 return 0; 571} 572 573static int sb_with_async_ping_handler(struct udevice *dev, void *packet, 574 unsigned int len) 575{ 576 struct eth_sandbox_priv *priv = dev_get_priv(dev); 577 struct ethernet_hdr *eth = packet; 578 struct arp_hdr *arp = packet + ETHER_HDR_SIZE; 579 int ret; 580 581 /* 582 * If we are about to generate a reply to ARP, first inject a request 583 * from another host 584 */ 585 if (ntohs(eth->et_protlen) == PROT_ARP && 586 ntohs(arp->ar_op) == ARPOP_REQUEST) { 587 /* Make sure sandbox_eth_recv_arp_req() knows who is asking */ 588 priv->fake_host_ipaddr = string_to_ip("1.1.2.4"); 589 590 ret = sandbox_eth_recv_ping_req(dev); 591 if (ret) 592 return ret; 593 } 594 595 sandbox_eth_arp_req_to_reply(dev, packet, len); 596 sandbox_eth_ping_req_to_reply(dev, packet, len); 597 598 return sb_check_ping_reply(dev, packet, len); 599} 600 601static int dm_test_eth_async_ping_reply(struct unit_test_state *uts) 602{ 603 net_ping_ip = string_to_ip("1.1.2.2"); 604 605 sandbox_eth_set_tx_handler(0, sb_with_async_ping_handler); 606 /* Used by all of the ut_assert macros in the tx_handler */ 607 sandbox_eth_set_priv(0, uts); 608 609 env_set("ethact", "eth@10002000"); 610 ut_assertok(net_loop(PING)); 611 ut_asserteq_str("eth@10002000", env_get("ethact")); 612 613 sandbox_eth_set_tx_handler(0, NULL); 614 615 return 0; 616} 617 618DM_TEST(dm_test_eth_async_ping_reply, UT_TESTF_SCAN_FDT); 619 620#if IS_ENABLED(CONFIG_IPV6_ROUTER_DISCOVERY) 621 622static u8 ip6_ra_buf[] = {0x60, 0xf, 0xc5, 0x4a, 0x0, 0x38, 0x3a, 0xff, 0xfe, 623 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x85, 0xe6, 624 0x29, 0x77, 0xcb, 0xc8, 0x53, 0xff, 0x2, 0x0, 0x0, 625 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 626 0x1, 0x86, 0x0, 0xdc, 0x90, 0x40, 0x80, 0x15, 0x18, 627 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x4, 628 0x40, 0xc0, 0x0, 0x0, 0x37, 0xdc, 0x0, 0x0, 0x37, 629 0x78, 0x0, 0x0, 0x0, 0x0, 0x20, 0x1, 0xca, 0xfe, 0xca, 630 0xfe, 0xca, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 631 0x0, 0x1, 0x1, 0x0, 0x15, 0x5d, 0xe2, 0x8a, 0x2}; 632 633static int dm_test_validate_ra(struct unit_test_state *uts) 634{ 635 struct ip6_hdr *ip6 = (struct ip6_hdr *)ip6_ra_buf; 636 struct icmp6hdr *icmp = (struct icmp6hdr *)(ip6 + 1); 637 __be16 temp = 0; 638 639 ut_assert(validate_ra(ip6) == true); 640 641 temp = ip6->payload_len; 642 ip6->payload_len = 15; 643 ut_assert(validate_ra(ip6) == false); 644 ip6->payload_len = temp; 645 646 temp = ip6->saddr.s6_addr16[0]; 647 ip6->saddr.s6_addr16[0] = 0x2001; 648 ut_assert(validate_ra(ip6) == false); 649 ip6->saddr.s6_addr16[0] = temp; 650 651 temp = ip6->hop_limit; 652 ip6->hop_limit = 15; 653 ut_assert(validate_ra(ip6) == false); 654 ip6->hop_limit = temp; 655 656 temp = icmp->icmp6_code; 657 icmp->icmp6_code = 15; 658 ut_assert(validate_ra(ip6) == false); 659 icmp->icmp6_code = temp; 660 661 return 0; 662} 663 664DM_TEST(dm_test_validate_ra, 0); 665 666static int dm_test_process_ra(struct unit_test_state *uts) 667{ 668 int len = sizeof(ip6_ra_buf); 669 struct ip6_hdr *ip6 = (struct ip6_hdr *)ip6_ra_buf; 670 struct icmp6hdr *icmp = (struct icmp6hdr *)(ip6 + 1); 671 struct ra_msg *msg = (struct ra_msg *)icmp; 672 unsigned char *option = msg->opt; 673 struct icmp6_ra_prefix_info *prefix = 674 (struct icmp6_ra_prefix_info *)option; 675 __be16 temp = 0; 676 unsigned char option_len = option[1]; 677 678 ut_assert(process_ra(ip6, len) == 0); 679 680 temp = icmp->icmp6_rt_lifetime; 681 icmp->icmp6_rt_lifetime = 0; 682 ut_assert(process_ra(ip6, len) != 0); 683 icmp->icmp6_rt_lifetime = temp; 684 685 ut_assert(process_ra(ip6, 0) != 0); 686 687 option[1] = 0; 688 ut_assert(process_ra(ip6, len) != 0); 689 option[1] = option_len; 690 691 prefix->on_link = false; 692 ut_assert(process_ra(ip6, len) != 0); 693 prefix->on_link = true; 694 695 temp = prefix->prefix.s6_addr16[0]; 696 prefix->prefix.s6_addr16[0] = 0x80fe; 697 ut_assert(process_ra(ip6, len) != 0); 698 prefix->prefix.s6_addr16[0] = temp; 699 700 return 0; 701} 702 703DM_TEST(dm_test_process_ra, 0); 704 705#endif 706