zkkkk12 opened a new pull request, #17730: URL: https://github.com/apache/nuttx/pull/17730
Supports no Neighbor request for invalid routing addresses in cross-segment communication *Note: Please adhere to [Contributing Guidelines](https://github.com/apache/nuttx/blob/master/CONTRIBUTING.md).* ## Summary Supports no Neighbor request for invalid routing addresses in cross-segment communication ## Impact When processing IPv6 packet transmission, if the destination address is unspecified, the device buffer length is set to 0 and the device returns directly without sending any packets.This prevents the system from attempting to send data packets to invalid addresses, thus avoiding wasting network resources. ## Testing ``` #include <nuttx/config.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <net/if.h> #include <errno.h> #include <string.h> #include <unistd.h> #include <sys/ioctl.h> #include <stdio.h> #include <stdlib.h> #include <nuttx/net/net.h> #include <nuttx/net/netdev.h> #include <nuttx/net/icmpv6.h> #include <nuttx/net/neighbor.h> #include "Ipv6NeighborTest.h" #include "CunitTest.h" /* Test constants */ #define TEST_INTERFACE_NAME "test_eth0" /* IPv6 unspecified address (all zeros) */ static const net_ipv6addr_t g_unspecified_addr = {0, 0, 0, 0, 0, 0, 0, 0}; /* Helper function to create a network device structure for testing */ static struct net_driver_s *create_test_netdev(void) { struct net_driver_s *dev; /* Allocate memory for test netdev */ dev = (struct net_driver_s *)malloc(sizeof(struct net_driver_s)); if (dev == NULL) { return NULL; } /* Initialize basic fields */ memset(dev, 0, sizeof(struct net_driver_s)); /* Set device properties for IPv6 testing */ dev->d_lltype = NET_LL_ETHERNET; dev->d_ifname = TEST_INTERFACE_NAME; dev->d_ifup = true; /* Set IPv6 link-local address (fe80::1) */ dev->d_ipv6addr[0] = HTONS(0xfe80); dev->d_ipv6addr[1] = 0; dev->d_ipv6addr[2] = 0; dev->d_ipv6addr[3] = 0; dev->d_ipv6addr[4] = 0; dev->d_ipv6addr[5] = 0; dev->d_ipv6addr[6] = 0; dev->d_ipv6addr[7] = HTONS(0x0001); /* Set IPv6 netmask (prefix length 64) */ dev->d_ipv6netmask[0] = HTONS(0xffff); dev->d_ipv6netmask[1] = HTONS(0xffff); dev->d_ipv6netmask[2] = HTONS(0xffff); dev->d_ipv6netmask[3] = HTONS(0xffff); dev->d_ipv6netmask[4] = 0; dev->d_ipv6netmask[5] = 0; dev->d_ipv6netmask[6] = 0; dev->d_ipv6netmask[7] = 0; /* Set default router to unspecified address (this is what we want to test) */ memset(dev->d_ipv6draddr, 0, sizeof(net_ipv6addr_t)); /* Set MAC address */ dev->d_mac.ether.ether_addr_octet[0] = 0x00; dev->d_mac.ether.ether_addr_octet[1] = 0x11; dev->d_mac.ether.ether_addr_octet[2] = 0x22; dev->d_mac.ether.ether_addr_octet[3] = 0x33; dev->d_mac.ether.ether_addr_octet[4] = 0x44; dev->d_mac.ether.ether_addr_octet[5] = 0x55; /* Clear NOARP flag to allow neighbor discovery */ IFF_CLR_NOARP(dev->d_flags); return dev; } /* Helper function to cleanup test netdev */ static void cleanup_test_netdev(struct net_driver_s *dev) { if (dev != NULL) { free(dev); } } /* Helper function to create IPv6 packet in device buffer */ static void create_test_ipv6_packet(struct net_driver_s *dev, const net_ipv6addr_t dest_addr) { struct ipv6_hdr_s *ip; /* Allocate buffer for Ethernet + IPv6 header */ dev->d_buf = malloc(sizeof(struct eth_hdr_s) + sizeof(struct ipv6_hdr_s)); if (dev->d_buf == NULL) { return; } /* Set packet length */ dev->d_len = sizeof(struct eth_hdr_s) + sizeof(struct ipv6_hdr_s); /* Skip Ethernet header and get IPv6 header */ ip = (struct ipv6_hdr_s *)(dev->d_buf + sizeof(struct eth_hdr_s)); /* Set IPv6 header fields */ ip->vtc = 0x60; /* Version 6, Traffic class 0 */ ip->tcf = 0; /* Traffic class 0, Flow label 0 */ ip->flow = 0; /* Flow label 0 */ ip->len[0] = 0; /* Payload length (will be set later) */ ip->len[1] = 0; ip->proto = IP_PROTO_TCP; /* Next header */ ip->ttl = 64; /* Hop limit */ /* Set source address (link-local) */ ip->srcipaddr[0] = HTONS(0xfe80); ip->srcipaddr[1] = 0; ip->srcipaddr[2] = 0; ip->srcipaddr[3] = 0; ip->srcipaddr[4] = 0; ip->srcipaddr[5] = 0; ip->srcipaddr[6] = 0; ip->srcipaddr[7] = HTONS(0x0001); /* Set destination address */ memcpy(ip->destipaddr, dest_addr, sizeof(net_ipv6addr_t)); } /* Test icmpv6_neighbor function with unspecified address */ int do_icmpv6_neighbor_unspecified_addr_test(void) { struct net_driver_s *dev; int ret; /* Create test network device */ dev = create_test_netdev(); if (dev == NULL) { printf("Failed to create test netdev\n"); return TEST_FAIL; } /* Test icmpv6_neighbor with unspecified address - should return EHOSTUNREACH */ ret = icmpv6_neighbor(dev, g_unspecified_addr); if (ret != -EHOSTUNREACH) { printf("icmpv6_neighbor should return EHOSTUNREACH for unspecified address, got %d\n", ret); cleanup_test_netdev(dev); return TEST_FAIL; } cleanup_test_netdev(dev); return TEST_PASS; } /* Test neighbor_ethernet_out function with unspecified address */ int do_neighbor_ethernet_out_unspecified_addr_test(void) { struct net_driver_s *dev; uint16_t original_len; /* Create test network device */ dev = create_test_netdev(); if (dev == NULL) { printf("Failed to create test netdev\n"); return TEST_FAIL; } /* Create IPv6 packet with unspecified destination address */ create_test_ipv6_packet(dev, g_unspecified_addr); if (dev->d_buf == NULL) { printf("Failed to create test packet\n"); cleanup_test_netdev(dev); return TEST_FAIL; } original_len = dev->d_len; /* Call neighbor_ethernet_out - should detect unspecified address and set d_len to 0 */ neighbor_ethernet_out(dev); if (dev->d_len != 0) { printf("neighbor_ethernet_out should set d_len to 0 for unspecified address, got %d\n", dev->d_len); free(dev->d_buf); cleanup_test_netdev(dev); return TEST_FAIL; } /* Cleanup */ free(dev->d_buf); cleanup_test_netdev(dev); return TEST_PASS; } /**************************************************************************** * Name: main * * Description: * Main function to run IPv6 neighbor unspecified address tests * * Returned Value: * Zero on success, non-zero on failure * ****************************************************************************/ int main(int argc, char *argv[]) { int ret; int passed = 0; int failed = 0; printf("=== IPv6 Neighbor Unspecified Address Test ===\n\n"); /* Test 1: icmpv6_neighbor with unspecified address */ printf("Running do_icmpv6_neighbor_unspecified_addr_test...\n"); ret = do_icmpv6_neighbor_unspecified_addr_test(); if (ret == TEST_PASS) { printf("PASS: icmpv6_neighbor correctly handles unspecified address\n"); passed++; } else { printf("FAIL: icmpv6_neighbor test failed\n"); failed++; } printf("\n"); /* Test 2: neighbor_ethernet_out with unspecified address */ printf("Running do_neighbor_ethernet_out_unspecified_addr_test...\n"); ret = do_neighbor_ethernet_out_unspecified_addr_test(); if (ret == TEST_PASS) { printf("PASS: neighbor_ethernet_out correctly handles unspecified address\n"); passed++; } else { printf("FAIL: neighbor_ethernet_out test failed\n"); failed++; } printf("\n"); printf("=== Test Results ===\n"); printf("Total tests: %d\n", passed + failed); printf("Passed: %d\n", passed); printf("Failed: %d\n", failed); if (failed == 0) { printf("\nSUCCESS: All IPv6 neighbor unspecified address tests passed!\n"); printf("The fix ensures that:\n"); printf("1. icmpv6_neighbor() returns EHOSTUNREACH when address is unspecified\n"); printf("2. neighbor_ethernet_out() sets packet length to 0 when address is unspecified\n"); return 0; } else { printf("\nFAILURE: Some tests failed!\n"); return 1; } } ``` Terminal output logļ¼ ``` core1> === IPv6 Neighbor Unspecified Address Test === core1> Running do_icmpv6_neighbor_unspecified_addr_test... core1> PASS: icmpv6_neighbor correctly handles unspecified address core1> Running do_neighbor_ethernet_out_unspecified_addr_test... core1> PASS: neighbor_ethernet_out correctly handles unspecified address core1> === Test Results === core1> SUCCESS: All IPv6 neighbor unspecified address tests passed! ``` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
