ip6: add some unit test cases for ip6 forwarding

This commit is contained in:
Xu Si Yu
2025-02-21 15:53:46 +08:00
parent adcd330ee1
commit ebabd6d79c
6 changed files with 251 additions and 1 deletions
+1
View File
@@ -29,6 +29,7 @@ set(LWIP_TESTFILES
${LWIP_TESTDIR}/etharp/test_etharp.c
${LWIP_TESTDIR}/ip4/test_ip4.c
${LWIP_TESTDIR}/ip6/test_ip6.c
${LWIP_TESTDIR}/ip6/test_ip6_route.c
${LWIP_TESTDIR}/mdns/test_mdns.c
${LWIP_TESTDIR}/mqtt/test_mqtt.c
${LWIP_TESTDIR}/tcp/tcp_helper.c
+1
View File
@@ -45,6 +45,7 @@ TESTFILES=$(TESTDIR)/lwip_unittests.c \
$(TESTDIR)/etharp/test_etharp.c \
$(TESTDIR)/ip4/test_ip4.c \
$(TESTDIR)/ip6/test_ip6.c \
$(TESTDIR)/ip6/test_ip6_route.c \
$(TESTDIR)/mdns/test_mdns.c \
$(TESTDIR)/mqtt/test_mqtt.c \
$(TESTDIR)/tcp/tcp_helper.c \
+237
View File
@@ -0,0 +1,237 @@
#include "test_ip6_route.h"
#include "lwip/ethip6.h"
#include "lwip/ip6.h"
#include "lwip/icmp6.h"
#include "lwip/inet_chksum.h"
#include "lwip/stats.h"
#include "lwip/prot/ethernet.h"
#include "lwip/prot/ip.h"
#include "lwip/prot/ip6.h"
#include "netif/ethernet.h"
#if LWIP_IPV6 /* allow to build the unit tests without IPv6 support */
#define IP6_PAYLOAD_LEN 0
static struct netif ap;
static struct netif sta;
static int ap_cnt = 0;
static int sta_cnt = 0;
static u8_t ap_output_p_type_internal = (PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS | PBUF_TYPE_ALLOC_SRC_MASK_STD_HEAP);
static u8_t sta_output_p_type_internal = (PBUF_TYPE_FLAG_STRUCT_DATA_CONTIGUOUS | PBUF_TYPE_ALLOC_SRC_MASK_STD_HEAP);
unsigned char packet_buffer[sizeof(struct ip6_hdr) + IP6_PAYLOAD_LEN];
/* Setups/teardown functions */
static void
ip6route_setup(void)
{
lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
}
static void
ip6route_teardown(void)
{
lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
}
/* test helper functions */
static void debug_print_packet(struct pbuf *p)
{
LWIP_UNUSED_ARG(p);
ip6_debug_print(p);
}
static void
send_to_netif(struct netif *input_netif, struct pbuf *p)
{
err_t err;
if (p != NULL) {
err = ip6_input(p, input_netif);
EXPECT(err == ERR_OK);
}
}
static err_t
ap_output(struct netif *netif, struct pbuf *p, const ip6_addr_t *ipaddr)
{
fail_unless(p->type_internal == ap_output_p_type_internal);
ap_cnt++;
debug_print_packet(p);
LWIP_UNUSED_ARG(netif);
LWIP_UNUSED_ARG(p);
LWIP_UNUSED_ARG(ipaddr);
return ERR_OK;
}
static err_t
sta_output(struct netif *netif, struct pbuf *p, const ip6_addr_t *ipaddr)
{
fail_unless(p->type_internal == sta_output_p_type_internal);
sta_cnt++;
debug_print_packet(p);
LWIP_UNUSED_ARG(netif);
LWIP_UNUSED_ARG(p);
LWIP_UNUSED_ARG(ipaddr);
return ERR_OK;
}
static err_t
sta_tx_func(struct netif *netif, struct pbuf *p)
{
LWIP_UNUSED_ARG(netif);
LWIP_UNUSED_ARG(p);
return ERR_OK;
}
static err_t
ap_tx_func(struct netif *netif, struct pbuf *p)
{
LWIP_UNUSED_ARG(netif);
LWIP_UNUSED_ARG(p);
return ERR_OK;
}
static err_t
testif_init_sta(struct netif *netif)
{
netif->name[0] = 's';
netif->name[1] = 't';
netif->output_ip6 = sta_output;
netif->linkoutput = sta_tx_func;
netif->mtu = 1500;
netif->hwaddr_len = 6;
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP | NETIF_FLAG_MLD6 | NETIF_FLAG_LINK_UP;
netif->hwaddr[0] = 0x02;
netif->hwaddr[1] = 0x03;
netif->hwaddr[2] = 0x04;
netif->hwaddr[3] = 0x05;
netif->hwaddr[4] = 0x06;
netif->hwaddr[5] = 0x08;
return ERR_OK;
}
static err_t
testif_init_ap(struct netif *netif)
{
netif->name[0] = 'a';
netif->name[1] = 'p';
netif->output_ip6 = ap_output;
netif->linkoutput = ap_tx_func;
netif->mtu = 1500;
netif->hwaddr_len = 6;
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP | NETIF_FLAG_MLD6 | NETIF_FLAG_LINK_UP;
netif->hwaddr[0] = 0x02;
netif->hwaddr[1] = 0x03;
netif->hwaddr[2] = 0x04;
netif->hwaddr[3] = 0x05;
netif->hwaddr[4] = 0x06;
netif->hwaddr[5] = 0x07;
return ERR_OK;
}
static struct pbuf *
test_ip6_create_test_packet(const ip6_addr_t *src_ip6, const ip6_addr_t *dst_ip6, pbuf_layer layer, pbuf_type type)
{
struct pbuf *p = NULL;
u16_t pbuf_len = (u16_t)(sizeof(struct ip6_hdr) + IP6_PAYLOAD_LEN);
struct ip6_hdr *ip6hdr = NULL;
if (type == PBUF_RAM) {
p = pbuf_alloc(layer, pbuf_len, PBUF_RAM);
} else if (type == PBUF_REF) {
p = pbuf_alloc(layer, pbuf_len, PBUF_REF);
p->payload = packet_buffer;
}
EXPECT_RETNULL(p != NULL);
ip6hdr = (struct ip6_hdr *)p->payload;
IP6H_VTCFL_SET(ip6hdr, 6, 0, 0);
IP6H_PLEN_SET(ip6hdr, 0);
IP6H_NEXTH_SET(ip6hdr, IP6_NEXTH_NONE);
IP6H_HOPLIM_SET(ip6hdr, 64);
ip6_addr_copy_to_packed(ip6hdr->src, *src_ip6);
ip6_addr_copy_to_packed(ip6hdr->dest, *dst_ip6);
return p;
}
/* Test functions */
static void test_ip6_route_netif_with_params(pbuf_layer layer, pbuf_type type)
{
ip6_addr_t addr_link_sta, addr_link_ap, sta_addr, ap_addr;
struct pbuf *p = NULL;
s8_t chosen_idx = -1;
/* setup station */
netif_add(&sta, NULL, NULL, NULL, NULL, testif_init_sta, ethernet_input);
ip6addr_aton("fdde:ad00:beef:cafe::1", &sta_addr);
netif_add_ip6_address(&sta, &sta_addr, &chosen_idx);
fail_unless(chosen_idx != -1);
sta.ip6_addr_state[chosen_idx] = IP6_ADDR_VALID;
netif_set_up(&sta);
/* setup access point */
netif_add(&ap, NULL, NULL, NULL, NULL, testif_init_ap, ethernet_input);
ip6addr_aton("fdde:ad00:beef:abcd::1", &ap_addr);
chosen_idx = -1;
netif_add_ip6_address(&ap, &ap_addr, &chosen_idx);
fail_unless(chosen_idx != -1);
ap.ip6_addr_state[chosen_idx] = IP6_ADDR_VALID;
netif_set_up(&ap);
/* add addr */
ip6addr_aton("fdde:ad00:beef:cafe::2", &addr_link_sta);
ip6addr_aton("fdde:ad00:beef:abcd::2", &addr_link_ap);
/* create packet and send it to the STA */
p = test_ip6_create_test_packet(&addr_link_sta, &addr_link_ap, layer, type);
send_to_netif(&sta, p);
fail_unless(ap_cnt == 1);
fail_unless(sta_cnt == 0);
/* create packet and send it to the AP */
p = test_ip6_create_test_packet(&addr_link_ap, &addr_link_sta, layer, type);
send_to_netif(&ap, p);
fail_unless(ap_cnt == 1);
fail_unless(sta_cnt == 1);
/* cleanup */
ap_cnt = 0;
sta_cnt = 0;
netif_set_down(&ap);
netif_remove(&ap);
netif_set_down(&sta);
netif_remove(&sta);
}
START_TEST(test_ip6_route_netif_forward_PBUF_RAM)
{
test_ip6_route_netif_with_params(PBUF_RAW, PBUF_RAM);
}
END_TEST
START_TEST(test_ip6_route_netif_forward_PBUF_REF)
{
test_ip6_route_netif_with_params(PBUF_RAW, PBUF_REF);
}
END_TEST
/** Create the suite including all tests for this module */
Suite *
ip6route_suite(void)
{
testfunc tests[] = {
TESTFUNC(test_ip6_route_netif_forward_PBUF_RAM),
TESTFUNC(test_ip6_route_netif_forward_PBUF_REF),
};
return create_suite("IP6_ROUTE", tests, sizeof(tests)/sizeof(testfunc), ip6route_setup, ip6route_teardown);
}
#endif /* LWIP_IPV6 */
+8
View File
@@ -0,0 +1,8 @@
#ifndef LWIP_HDR_TEST_IP6_ROUTE_H
#define LWIP_HDR_TEST_IP6_ROUTE_H
#include "../lwip_check.h"
Suite* ip6route_suite(void);
#endif
+3 -1
View File
@@ -2,6 +2,7 @@
#include "ip4/test_ip4.h"
#include "ip6/test_ip6.h"
#include "ip6/test_ip6_route.h"
#include "udp/test_udp.h"
#include "tcp/test_tcp.h"
#include "tcp/test_tcp_oos.h"
@@ -116,7 +117,8 @@ int main(void)
#endif /* PPP_SUPPORT && PPPOS_SUPPORT */
#endif /* ESP_TEST_DEBUG */
ip4napt_suite,
ip4route_suite
ip4route_suite,
ip6route_suite
};
size_t num = sizeof(suites)/sizeof(void*);
LWIP_ASSERT("No suites defined", num > 0);
+1
View File
@@ -36,6 +36,7 @@
#define LWIP_IPV6 1
#define LWIP_ND6 1
#define LWIP_IPV6_FORWARD 1
#define LWIP_CHECKSUM_ON_COPY 1
#define TCP_CHECKSUM_ON_COPY_SANITY_CHECK 1