From f923adb03811ed1a208d562237721c188ff0b94a Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 14 Jun 2016 09:29:23 +0300 Subject: [PATCH] net: tests: Add unit tests for net_nbuf_copy() The tests will make sure net_nbuf_copy() works as expected. Change-Id: I48dc3b794c70ec4d6436feb76508952c88bbf09b Signed-off-by: Jukka Rissanen --- tests/net/nbuf/prj_x86.conf | 10 +-- tests/net/nbuf/src/main.c | 124 +++++++++++++++++++++++++++++++++++- 2 files changed, 128 insertions(+), 6 deletions(-) diff --git a/tests/net/nbuf/prj_x86.conf b/tests/net/nbuf/prj_x86.conf index f40f6d2f1ab..5e5ea1d1873 100644 --- a/tests/net/nbuf/prj_x86.conf +++ b/tests/net/nbuf/prj_x86.conf @@ -2,11 +2,13 @@ CONFIG_NETWORKING=y CONFIG_NET_IPV6=y CONFIG_NET_YAIP=y CONFIG_NET_BUF=y -CONFIG_NET_BUF_DEBUG=y +#CONFIG_NET_BUF_DEBUG=y CONFIG_MAIN_STACK_SIZE=2048 -CONFIG_NET_NBUF_RX_COUNT=2 -CONFIG_NET_NBUF_TX_COUNT=2 -CONFIG_NET_NBUF_DATA_COUNT=5 +CONFIG_NET_NBUF_RX_COUNT=4 +CONFIG_NET_NBUF_TX_COUNT=4 +CONFIG_NET_NBUF_DATA_COUNT=15 +CONFIG_NET_NBUF_DATA_SIZE=100 CONFIG_NET_LOG=y CONFIG_SYS_LOG_SHOW_COLOR=y CONFIG_NETWORK_IP_STACK_DEBUG_NET_BUF=y +CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/tests/net/nbuf/src/main.c b/tests/net/nbuf/src/main.c index fd432771487..ffc0379aac7 100644 --- a/tests/net/nbuf/src/main.c +++ b/tests/net/nbuf/src/main.c @@ -36,14 +36,20 @@ struct ipv6_hdr { uint8_t hop_limit; struct in6_addr src; struct in6_addr dst; -} __attribute__((__packed__)); +} __packed; struct udp_hdr { uint16_t src_port; uint16_t dst_port; uint16_t len; uint16_t chksum; -} __attribute__((__packed__)); +} __packed; + +struct icmp_hdr { + uint8_t type; + uint8_t code; + uint16_t chksum; +} __packed; static const char example_data[] = "0123456789abcdefghijklmnopqrstuvxyz!#ยค%&/()=?" @@ -156,6 +162,116 @@ static int test_ipv6_multi_frags(void) return 0; } +static char buf_orig[200]; +static char buf_copy[200]; + +static void linearize(struct net_buf *buf, char *buffer, int len) +{ + char *ptr = buffer; + + buf = buf->frags; + + while (buf && len > 0) { + + memcpy(ptr, buf->data, buf->len); + ptr += buf->len; + len -= buf->len; + + buf = buf->frags; + } +} + +static int test_fragment_copy(void) +{ + struct net_buf *buf, *frag, *new_buf, *new_frag; + struct ipv6_hdr *ipv6; + struct udp_hdr *udp; + size_t orig_len; + int pos; + + buf = net_nbuf_get_reserve_rx(0); + frag = net_nbuf_get_reserve_data(LL_RESERVE); + + /* Place the IP + UDP header in the first fragment */ + if (net_buf_tailroom(frag)) { + ipv6 = (struct ipv6_hdr *)(frag->data); + udp = (struct udp_hdr *)((void *)ipv6 + sizeof(*ipv6)); + if (net_buf_tailroom(frag) < sizeof(*ipv6)) { + printk("Not enough space for IPv6 header, " + "needed %d bytes, has %d bytes\n", + sizeof(ipv6), net_buf_tailroom(frag)); + return -EINVAL; + } + net_buf_add(frag, sizeof(*ipv6)); + + if (net_buf_tailroom(frag) < sizeof(*udp)) { + printk("Not enough space for UDP header, " + "needed %d bytes, has %d bytes\n", + sizeof(udp), net_buf_tailroom(frag)); + return -EINVAL; + } + + net_buf_add(frag, sizeof(*udp)); + + memcpy(net_buf_add(frag, 15), example_data, 15); + + net_nbuf_appdata(buf) = (void *)udp + sizeof(*udp) + 15; + net_nbuf_appdatalen(buf) = 0; + } + + net_buf_frag_add(buf, frag); + + orig_len = net_buf_frags_len(buf); + + printk("Total copy data len %d\n", orig_len); + + linearize(buf, buf_orig, sizeof(orig_len)); + + /* Then copy a fragment list to a new fragment list */ + new_frag = net_nbuf_copy_all(buf->frags, sizeof(struct ipv6_hdr) + + sizeof(struct icmp_hdr)); + if (!new_frag) { + printk("Cannot copy fragment list.\n"); + return -EINVAL; + } + + new_buf = net_nbuf_get_reserve_tx(0); + net_buf_frag_add(new_buf, new_frag); + + printk("Total new data len %d\n", net_buf_frags_len(new_buf)); + + if (net_buf_frags_len(buf) != 0) { + printk("Fragment list missing data, %d bytes not copied\n", + net_buf_frags_len(buf)); + return -EINVAL; + } + + if (net_buf_frags_len(new_buf) != (orig_len + sizeof(struct ipv6_hdr) + + sizeof(struct icmp_hdr))) { + printk("Fragment list missing data, new buf len %d " + "should be %d\n", net_buf_frags_len(new_buf), + orig_len + sizeof(struct ipv6_hdr) + + sizeof(struct icmp_hdr)); + return -EINVAL; + } + + linearize(new_buf, buf_copy, sizeof(buf_copy)); + + if (!memcmp(buf_orig, buf_copy, sizeof(buf_orig))) { + printk("Buffer copy failed, buffers are same!\n"); + return -EINVAL; + } + + pos = memcmp(buf_orig, buf_copy + sizeof(struct ipv6_hdr) + + sizeof(struct icmp_hdr), sizeof(buf_orig)); + if (pos) { + printk("Buffer copy failed at pos %d\n", pos); + return -EINVAL; + } + + return 0; +} + #ifdef CONFIG_MICROKERNEL void mainloop(void) #else @@ -166,5 +282,9 @@ void main(void) return; } + if (test_fragment_copy() < 0) { + return; + } + printk("nbuf tests passed\n"); }