tests: provide tests for gnrc_ipv6_ext_frag fragmentation
This commit is contained in:
parent
51ef1c997d
commit
e62bb9c414
@ -3,12 +3,17 @@ DEVELHELP := 1
|
||||
include ../Makefile.tests_common
|
||||
|
||||
BOARD_INSUFFICIENT_MEMORY := arduino-duemilanove arduino-leonardo \
|
||||
arduino-mega2560 arduino-nano arduino-uno chronos \
|
||||
arduino-mega2560 arduino-nano arduino-uno \
|
||||
blackpill bluepill hifive1 hifive1b \
|
||||
i-nucleo-lrwan1 mega-xplained msb-430 msb-430h \
|
||||
nucleo-f030r8 nucleo-f031k6 nucleo-f042k6 \
|
||||
nucleo-f070rb nucleo-f072rb nucleo-f302r8 \
|
||||
nucleo-f303k8 nucleo-f334r8 nucleo-l031k6 \
|
||||
nucleo-l053r8 stm32f0discovery stm32l0538-disco \
|
||||
telosb waspmote-pro wsn430-v1_3b wsn430-v1_4 z1
|
||||
nucleo-l053r8 saml10-xpro saml11-xpro \
|
||||
stm32f0discovery stm32l0538-disco telosb \
|
||||
waspmote-pro wsn430-v1_3b wsn430-v1_4 z1
|
||||
# chronos, hamilton, ruuvitag, and thingy52 boards don't support ethos
|
||||
BOARD_BLACKLIST := chronos hamilton ruuvitag thingy52
|
||||
|
||||
export TAP ?= tap0
|
||||
|
||||
@ -16,15 +21,22 @@ CFLAGS += -DOUTPUT=TEXT
|
||||
CFLAGS += -DTEST_SUITES="gnrc_ipv6_ext_frag"
|
||||
CFLAGS += -DGNRC_IPV6_EXT_FRAG_LIMITS_POOL_SIZE=3
|
||||
|
||||
# use Ethernet as link-layer protocol for native
|
||||
# The only current general option for non-native boards, ethos, performs poorly
|
||||
# with the rapidly sent, large packets sent by the Linux kernel.
|
||||
ifeq (native,$(BOARD))
|
||||
USEMODULE += netdev_tap
|
||||
TERMFLAGS ?= $(TAP)
|
||||
else
|
||||
USEMODULE += stdio_ethos
|
||||
|
||||
USEMODULE += auto_init_gnrc_netif
|
||||
ETHOS_BAUDRATE ?= 115200
|
||||
CFLAGS += -DETHOS_BAUDRATE=$(ETHOS_BAUDRATE)
|
||||
TERMDEPS += ethos
|
||||
TERMPROG ?= sudo $(RIOTTOOLS)/ethos/ethos
|
||||
TERMFLAGS ?= $(TAP) $(PORT) $(ETHOS_BAUDRATE)
|
||||
endif
|
||||
USEMODULE += auto_init_gnrc_netif
|
||||
# add dummy interface to test forwarding to smaller MTU
|
||||
USEMODULE += netdev_test
|
||||
GNRC_NETIF_NUMOF := 2
|
||||
# Specify the mandatory networking modules for IPv6
|
||||
USEMODULE += gnrc_ipv6_router_default
|
||||
USEMODULE += gnrc_icmpv6_error
|
||||
@ -42,8 +54,13 @@ USEMODULE += shell
|
||||
USEMODULE += shell_commands
|
||||
USEMODULE += ps
|
||||
|
||||
# native requires sudo for the `scapy` tests, but those are not executed for
|
||||
# non-native boards
|
||||
TEST_ON_CI_BLACKLIST += native
|
||||
# The test requires some setup and to be run as root
|
||||
# So it cannot currently be run
|
||||
TEST_ON_CI_BLACKLIST += all
|
||||
|
||||
.PHONY: ethos
|
||||
|
||||
ethos:
|
||||
$(Q)env -u CC -u CFLAGS make -C $(RIOTTOOLS)/ethos
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
||||
|
||||
@ -20,18 +20,31 @@
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "byteorder.h"
|
||||
#include "clist.h"
|
||||
#include "embUnit.h"
|
||||
#include "net/ipv6/addr.h"
|
||||
#include "net/ipv6/ext/frag.h"
|
||||
#include "net/protnum.h"
|
||||
#include "net/gnrc.h"
|
||||
#include "net/gnrc/ipv6/ext.h"
|
||||
#include "net/gnrc/ipv6/ext/frag.h"
|
||||
#include "net/gnrc/ipv6/hdr.h"
|
||||
#include "net/gnrc/ipv6/nib.h"
|
||||
#include "net/gnrc/netif/raw.h"
|
||||
#include "net/gnrc/udp.h"
|
||||
#include "net/netdev_test.h"
|
||||
#include "od.h"
|
||||
#include "random.h"
|
||||
#include "shell.h"
|
||||
#include "xtimer.h"
|
||||
|
||||
#define TEST_SAMPLE "This is a test. Failure might sometimes be an " \
|
||||
"option, but not today. "
|
||||
#define TEST_PORT (20908U)
|
||||
#define TEST_FRAG1 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
|
||||
0xab, 0xcf, 0xde, 0xb8, 0x18, 0x48, 0xe3, 0x70, \
|
||||
0x30, 0x1a, 0xba, 0x27, 0xa6, 0xa7, 0xce, 0xeb, \
|
||||
@ -63,10 +76,18 @@
|
||||
#define TEST_HL (64U)
|
||||
|
||||
extern int udp_cmd(int argc, char **argv);
|
||||
/* shell_test_cmd is used to test weird snip configurations,
|
||||
* the rest can just use udp_cmd */
|
||||
static int shell_test_cmd(int argc, char **argv);
|
||||
|
||||
static netdev_test_t mock_netdev;
|
||||
static gnrc_netif_t *eth_netif, *mock_netif;
|
||||
static ipv6_addr_t *local_addr;
|
||||
static char mock_netif_stack[THREAD_STACKSIZE_DEFAULT];
|
||||
static char line_buf[SHELL_DEFAULT_BUFSIZE];
|
||||
static const shell_command_t shell_commands[] = {
|
||||
{ "udp", "send data over UDP and listen on UDP ports", udp_cmd },
|
||||
{ "test", "sends data according to a specified numeric test", shell_test_cmd },
|
||||
{ NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
@ -443,9 +464,174 @@ static void run_unittests(void)
|
||||
TESTS_END();
|
||||
}
|
||||
|
||||
static gnrc_pktsnip_t *_build_udp_packet(const ipv6_addr_t *dst,
|
||||
unsigned payload_size,
|
||||
gnrc_pktsnip_t *payload)
|
||||
{
|
||||
udp_hdr_t *udp_hdr;
|
||||
ipv6_hdr_t *ipv6_hdr;
|
||||
gnrc_netif_hdr_t *netif_hdr;
|
||||
gnrc_pktsnip_t *hdr;
|
||||
|
||||
if (payload == NULL) {
|
||||
uint8_t *data;
|
||||
|
||||
payload = gnrc_pktbuf_add(NULL, NULL, payload_size, GNRC_NETTYPE_UNDEF);
|
||||
if (payload == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
data = payload->data;
|
||||
while (payload_size) {
|
||||
unsigned test_sample_len = sizeof(TEST_SAMPLE) - 1;
|
||||
|
||||
if (test_sample_len > payload_size) {
|
||||
test_sample_len = payload_size;
|
||||
}
|
||||
|
||||
memcpy(data, TEST_SAMPLE, test_sample_len);
|
||||
data += test_sample_len;
|
||||
payload_size -= test_sample_len;
|
||||
}
|
||||
}
|
||||
hdr = gnrc_udp_hdr_build(payload, TEST_PORT, TEST_PORT);
|
||||
if (hdr == NULL) {
|
||||
gnrc_pktbuf_release(payload);
|
||||
return NULL;
|
||||
}
|
||||
udp_hdr = hdr->data;
|
||||
udp_hdr->length = byteorder_htons(gnrc_pkt_len(hdr));
|
||||
payload = hdr;
|
||||
hdr = gnrc_ipv6_hdr_build(payload, local_addr, dst);
|
||||
if (hdr == NULL) {
|
||||
gnrc_pktbuf_release(payload);
|
||||
return NULL;
|
||||
}
|
||||
ipv6_hdr = hdr->data;
|
||||
ipv6_hdr->len = byteorder_htons(gnrc_pkt_len(payload));
|
||||
ipv6_hdr->nh = PROTNUM_UDP;
|
||||
ipv6_hdr->hl = GNRC_NETIF_DEFAULT_HL;
|
||||
gnrc_udp_calc_csum(payload, hdr);
|
||||
payload = hdr;
|
||||
hdr = gnrc_netif_hdr_build(NULL, 0, NULL, 0);
|
||||
if (hdr == NULL) {
|
||||
gnrc_pktbuf_release(payload);
|
||||
return NULL;
|
||||
}
|
||||
netif_hdr = hdr->data;
|
||||
netif_hdr->if_pid = eth_netif->pid;
|
||||
netif_hdr->flags |= GNRC_NETIF_HDR_FLAGS_MULTICAST;
|
||||
hdr->next = payload;
|
||||
return hdr;
|
||||
}
|
||||
|
||||
static void test_ipv6_ext_frag_send_pkt_single_frag(const ipv6_addr_t *dst)
|
||||
{
|
||||
gnrc_pktsnip_t *pkt;
|
||||
|
||||
TEST_ASSERT_NOT_NULL(local_addr);
|
||||
pkt = _build_udp_packet(dst, sizeof(TEST_SAMPLE) - 1, NULL);
|
||||
TEST_ASSERT_NOT_NULL(pkt);
|
||||
gnrc_ipv6_ext_frag_send_pkt(pkt, eth_netif->ipv6.mtu);
|
||||
}
|
||||
|
||||
static void test_ipv6_ext_frag_payload_snips_not_divisible_of_8(const ipv6_addr_t *dst)
|
||||
{
|
||||
gnrc_pktsnip_t *pkt, *payload = NULL;
|
||||
unsigned payload_size = 0;
|
||||
|
||||
TEST_ASSERT_NOT_NULL(local_addr);
|
||||
/* TEST_SAMPLE's string length is not a multiple of 8*/
|
||||
TEST_ASSERT((sizeof(TEST_SAMPLE) - 1) & 0x7);
|
||||
|
||||
while (payload_size <= eth_netif->ipv6.mtu) {
|
||||
pkt = gnrc_pktbuf_add(payload, TEST_SAMPLE, sizeof(TEST_SAMPLE) - 1,
|
||||
GNRC_NETTYPE_UNDEF);
|
||||
TEST_ASSERT_NOT_NULL(pkt);
|
||||
payload_size += pkt->size;
|
||||
payload = pkt;
|
||||
}
|
||||
pkt = _build_udp_packet(dst, 0, payload);
|
||||
TEST_ASSERT_NOT_NULL(pkt);
|
||||
gnrc_ipv6_ext_frag_send_pkt(pkt, eth_netif->ipv6.mtu);
|
||||
}
|
||||
|
||||
static int shell_test_cmd(int argc, char **argv)
|
||||
{
|
||||
static ipv6_addr_t dst;
|
||||
static void (* const _shell_tests[])(const ipv6_addr_t *) = {
|
||||
test_ipv6_ext_frag_send_pkt_single_frag,
|
||||
test_ipv6_ext_frag_payload_snips_not_divisible_of_8,
|
||||
};
|
||||
int test_num;
|
||||
|
||||
if ((argc < 3) || (ipv6_addr_from_str(&dst, argv[1]) == NULL)) {
|
||||
puts("usage: test <dst_addr> [<num>]");
|
||||
return 1;
|
||||
}
|
||||
test_num = atoi(argv[2]);
|
||||
if ((unsigned)test_num >= ARRAY_SIZE(_shell_tests)) {
|
||||
printf("<num> must be between 0 and %u\n",
|
||||
(unsigned)ARRAY_SIZE(_shell_tests) - 1);
|
||||
return 1;
|
||||
}
|
||||
printf("Running test %d\n", test_num);
|
||||
_shell_tests[test_num](&dst);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* TODO: test if forwarded packet is not fragmented */
|
||||
|
||||
static int mock_get_device_type(netdev_t *dev, void *value, size_t max_len)
|
||||
{
|
||||
(void)dev;
|
||||
assert(max_len == sizeof(uint16_t));
|
||||
*((uint16_t *)value) = NETDEV_TYPE_TEST;
|
||||
return sizeof(uint16_t);
|
||||
}
|
||||
|
||||
static int mock_get_max_packet_size(netdev_t *dev, void *value, size_t max_len)
|
||||
{
|
||||
(void)dev;
|
||||
assert(max_len == sizeof(uint16_t));
|
||||
assert(eth_netif != NULL);
|
||||
*((uint16_t *)value) = eth_netif->ipv6.mtu - 8;
|
||||
return sizeof(uint16_t);
|
||||
}
|
||||
|
||||
static int mock_send(netdev_t *dev, const iolist_t *iolist)
|
||||
{
|
||||
(void)dev;
|
||||
int res = 0;
|
||||
while(iolist != NULL) {
|
||||
od_hex_dump(iolist->iol_base, iolist->iol_len,
|
||||
OD_WIDTH_DEFAULT);
|
||||
res += iolist->iol_len;
|
||||
iolist = iolist->iol_next;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
eth_netif = gnrc_netif_iter(NULL);
|
||||
/* create mock netif to test forwarding too large fragments */
|
||||
netdev_test_setup(&mock_netdev, 0);
|
||||
netdev_test_set_get_cb(&mock_netdev, NETOPT_DEVICE_TYPE,
|
||||
mock_get_device_type);
|
||||
netdev_test_set_get_cb(&mock_netdev, NETOPT_MAX_PDU_SIZE,
|
||||
mock_get_max_packet_size);
|
||||
netdev_test_set_send_cb(&mock_netdev, mock_send);
|
||||
mock_netif = gnrc_netif_raw_create(mock_netif_stack,
|
||||
sizeof(mock_netif_stack),
|
||||
GNRC_NETIF_PRIO, "mock_netif",
|
||||
(netdev_t *)&mock_netdev);
|
||||
run_unittests();
|
||||
printf("Sending UDP test packets to port %u\n", TEST_PORT);
|
||||
for (unsigned i = 0; i < GNRC_NETIF_IPV6_ADDRS_NUMOF; i++) {
|
||||
if (ipv6_addr_is_link_local(ð_netif->ipv6.addrs[i])) {
|
||||
local_addr = ð_netif->ipv6.addrs[i];
|
||||
}
|
||||
}
|
||||
shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -14,10 +14,14 @@ import sys
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
from scapy.all import Ether, IPv6, IPv6ExtHdrFragment, sendp
|
||||
from scapy.all import Ether, ICMPv6PacketTooBig, IPv6, IPv6ExtHdrFragment, \
|
||||
UDP, raw, sendp, srp1
|
||||
from testrunner import run
|
||||
|
||||
|
||||
RECV_BUFSIZE = 2 * 1500
|
||||
TEST_SAMPLE = b"This is a test. Failure might sometimes be an option, but " \
|
||||
b"not today. "
|
||||
EXT_HDR_NH = {
|
||||
IPv6ExtHdrFragment: 44,
|
||||
}
|
||||
@ -54,6 +58,13 @@ def stop_udp_server(child):
|
||||
"Error: server was not running"])
|
||||
|
||||
|
||||
def udp_send(child, addr, port, length, num=1, delay=1000000):
|
||||
child.sendline("udp send {addr}%6 {port} {length} {num} {delay}"
|
||||
.format(**vars()))
|
||||
child.expect("Success: send {length} byte to \[[0-9a-f:]+\]:{port}"
|
||||
.format(**vars()))
|
||||
|
||||
|
||||
def check_and_search_output(cmd, pattern, res_group, *args, **kwargs):
|
||||
output = subprocess.check_output(cmd, *args, **kwargs).decode("utf-8")
|
||||
for line in output.splitlines():
|
||||
@ -145,6 +156,165 @@ def test_reass_offset_too_large(child, iface, hw_dst, ll_dst, ll_src):
|
||||
pktbuf_empty(child)
|
||||
|
||||
|
||||
def test_ipv6_ext_frag_shell_test_0(child, s, iface, ll_dst):
|
||||
child.sendline("test {} 0".format(ll_dst))
|
||||
data, _ = s.recvfrom(RECV_BUFSIZE)
|
||||
assert data == TEST_SAMPLE
|
||||
pktbuf_empty(child)
|
||||
|
||||
|
||||
def test_ipv6_ext_frag_shell_test_1(child, s, iface, ll_dst):
|
||||
child.sendline("test {} 1".format(ll_dst))
|
||||
data, _ = s.recvfrom(RECV_BUFSIZE)
|
||||
offset = 0
|
||||
while (offset < len(data)):
|
||||
assert data[offset:(offset + len(TEST_SAMPLE))] == TEST_SAMPLE
|
||||
offset += len(TEST_SAMPLE)
|
||||
pktbuf_empty(child)
|
||||
|
||||
|
||||
def test_ipv6_ext_frag_send_success(child, s, iface, ll_dst):
|
||||
length = get_host_mtu(iface)
|
||||
port = s.getsockname()[1]
|
||||
udp_send(child, ll_dst, port, length)
|
||||
data, _ = s.recvfrom(length)
|
||||
assert len(data) == length
|
||||
pktbuf_empty(child)
|
||||
|
||||
|
||||
def test_ipv6_ext_frag_send_last_fragment_filled(child, s, iface, ll_dst):
|
||||
# every fragment has an IPv6 header and a fragmentation header so subtract
|
||||
# them
|
||||
mtu = get_host_mtu(iface) - len(IPv6() / IPv6ExtHdrFragment())
|
||||
# first fragment has UDP header (so subtract it) and is rounded down to
|
||||
# the nearest multiple of 8
|
||||
length = (mtu - len(UDP())) & 0xfff8
|
||||
# second fragment fills the whole available MTU
|
||||
length += mtu
|
||||
port = s.getsockname()[1]
|
||||
udp_send(child, ll_dst, port, length)
|
||||
data, _ = s.recvfrom(length)
|
||||
assert len(data) == length
|
||||
pktbuf_empty(child)
|
||||
|
||||
|
||||
def test_ipv6_ext_frag_send_last_fragment_only_one_byte(child, s,
|
||||
iface, ll_dst):
|
||||
mtu = get_host_mtu(iface)
|
||||
# subtract IPv6 and UDP header as they are not part of the UDP payload
|
||||
length = (mtu - len(IPv6() / UDP()))
|
||||
length += 1
|
||||
port = s.getsockname()[1]
|
||||
udp_send(child, ll_dst, port, length)
|
||||
data, _ = s.recvfrom(length)
|
||||
assert len(data) == length
|
||||
pktbuf_empty(child)
|
||||
|
||||
|
||||
def test_ipv6_ext_frag_send_full_pktbuf(child, s, iface, ll_dst):
|
||||
length = pktbuf_size(child)
|
||||
# remove some slack for meta-data and header and 1 addition fragment header
|
||||
length -= (len(IPv6() / IPv6ExtHdrFragment() / UDP()) +
|
||||
(len(IPv6() / IPv6ExtHdrFragment())) + 96)
|
||||
port = s.getsockname()[1]
|
||||
# trigger neighbor discovery so it doesn't fill the packet buffer
|
||||
udp_send(child, ll_dst, port, 1)
|
||||
data, _ = s.recvfrom(1)
|
||||
last_nd = time.time()
|
||||
count = 0
|
||||
while True:
|
||||
if (time.time() - last_nd) > 5:
|
||||
# trigger neighbor discovery so it doesn't fill the packet buffer
|
||||
udp_send(child, ll_dst, port, 1)
|
||||
data, _ = s.recvfrom(1)
|
||||
last_nd = time.time()
|
||||
udp_send(child, ll_dst, port, length)
|
||||
count += 1
|
||||
try:
|
||||
data, _ = s.recvfrom(length)
|
||||
except socket.timeout:
|
||||
# 8 is the alignment unit of the packet buffer
|
||||
# and 20 the size of a packet snip, so take next multiple of 8 to
|
||||
# 28
|
||||
length -= 24
|
||||
else:
|
||||
break
|
||||
finally:
|
||||
pktbuf_empty(child)
|
||||
assert(count > 1)
|
||||
|
||||
|
||||
def _fwd_setup(child, ll_dst, g_src, g_dst):
|
||||
# check if interface is configured properly
|
||||
child.sendline("ifconfig 7")
|
||||
child.expect(r"MTU:(\d+)")
|
||||
mtu = int(child.match.group(1))
|
||||
# configure routes
|
||||
child.sendline("nib route add 7 {}/128 fe80::1".format(g_dst))
|
||||
child.sendline("nib route add 6 {}/128 {}".format(g_src, ll_dst))
|
||||
child.sendline("nib route")
|
||||
child.expect(r"{}/128 via fe80::1 dev #7".format(g_dst))
|
||||
child.expect(r"{}/128 via {} dev #6".format(g_src, ll_dst))
|
||||
child.sendline("nib neigh add 7 fe80::1")
|
||||
child.sendline("nib neigh")
|
||||
child.expect(r"fe80::1 dev #7 lladdr\s+-")
|
||||
# get TAP MAC address
|
||||
child.sendline("ifconfig 6")
|
||||
child.expect("HWaddr: ([0-9A-F:]+)")
|
||||
hwaddr = child.match.group(1)
|
||||
# consume MTU for later calls of `ifconfig 7`
|
||||
child.expect(r"MTU:(\d+)")
|
||||
return mtu, hwaddr
|
||||
|
||||
|
||||
def _fwd_teardown(child):
|
||||
# remove route
|
||||
child.sendline("nib neigh del 7 fe80::1")
|
||||
child.sendline("nib route del 7 affe::/64")
|
||||
|
||||
|
||||
def test_ipv6_ext_frag_fwd_success(child, s, iface, ll_dst):
|
||||
mtu, dst_mac = _fwd_setup(child, ll_dst, "beef::1", "affe::1")
|
||||
payload_fit = mtu - len(IPv6() / IPv6ExtHdrFragment() / UDP())
|
||||
pkt = Ether(dst=dst_mac) / IPv6(src="beef::1", dst="affe::1") / \
|
||||
IPv6ExtHdrFragment(m=True, id=0x477384a9) / \
|
||||
UDP(sport=1337, dport=1337) / ("x" * payload_fit)
|
||||
# fill missing fields
|
||||
pkt = Ether(raw(pkt))
|
||||
sendp(pkt, verbose=0, iface=iface)
|
||||
# check hexdump of mock device
|
||||
ipv6 = pkt[IPv6]
|
||||
ipv6.hlim -= 1 # the packet will have passed a hop
|
||||
# segment packet as GNRC does
|
||||
segments = [bytes(ipv6)[:40], bytes(ipv6.payload)]
|
||||
for seg in segments:
|
||||
addr = 0
|
||||
for i in range(0, len(seg), 16):
|
||||
bs = seg[i:i+16]
|
||||
exp_str = ("{:08X}" + (" {:02X}") * len(bs)).format(addr, *bs)
|
||||
child.expect_exact(exp_str)
|
||||
addr += 16
|
||||
_fwd_teardown(child)
|
||||
|
||||
|
||||
def test_ipv6_ext_frag_fwd_too_big(child, s, iface, ll_dst):
|
||||
mtu, dst_mac = _fwd_setup(child, ll_dst, "beef::1", "affe::1")
|
||||
assert(get_host_mtu(iface) > mtu)
|
||||
payload_fit = get_host_mtu(iface) - len(IPv6() / IPv6ExtHdrFragment() /
|
||||
UDP())
|
||||
pkt = srp1(Ether(dst=dst_mac) / IPv6(src="beef::1", dst="affe::1") /
|
||||
IPv6ExtHdrFragment(m=True, id=0x477384a9) /
|
||||
UDP(sport=1337, dport=1337) / ("x" * payload_fit),
|
||||
timeout=2, verbose=0, iface=iface)
|
||||
# packet should not be fragmented further but an ICMPv6 error should be
|
||||
# returned instead
|
||||
assert(pkt is not None)
|
||||
assert(ICMPv6PacketTooBig in pkt)
|
||||
assert(IPv6ExtHdrFragment in pkt)
|
||||
assert(pkt[IPv6ExtHdrFragment].id == 0x477384a9)
|
||||
_fwd_teardown(child)
|
||||
|
||||
|
||||
def testfunc(child):
|
||||
tap = get_bridge(os.environ["TAP"])
|
||||
|
||||
@ -152,12 +322,45 @@ def testfunc(child):
|
||||
print("." * int(child.match.group(1)), end="", flush=True)
|
||||
|
||||
lladdr_src = get_host_lladdr(tap)
|
||||
|
||||
def run_sock_test(func, s):
|
||||
if child.logfile == sys.stdout:
|
||||
func(child, s, tap, lladdr_src)
|
||||
else:
|
||||
try:
|
||||
func(child, s, tap, lladdr_src)
|
||||
print(".", end="", flush=True)
|
||||
except PermissionError:
|
||||
print("\n\x1b[1;33mSkipping {} because of missing "
|
||||
"privileges\x1b[0m".format(func.__name__))
|
||||
except Exception as e:
|
||||
print("FAILED")
|
||||
raise e
|
||||
|
||||
child.expect(r"Sending UDP test packets to port (\d+)")
|
||||
|
||||
port = int(child.match.group(1))
|
||||
with socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) as s:
|
||||
res = socket.getaddrinfo("{}%{}".format(lladdr_src, tap), port)
|
||||
s.bind(res[0][4])
|
||||
s.settimeout(.3)
|
||||
run_sock_test(test_ipv6_ext_frag_shell_test_0, s)
|
||||
run_sock_test(test_ipv6_ext_frag_shell_test_1, s)
|
||||
run_sock_test(test_ipv6_ext_frag_send_success, s)
|
||||
run_sock_test(test_ipv6_ext_frag_send_last_fragment_filled, s)
|
||||
run_sock_test(test_ipv6_ext_frag_send_last_fragment_only_one_byte, s)
|
||||
run_sock_test(test_ipv6_ext_frag_send_full_pktbuf, s)
|
||||
run_sock_test(test_ipv6_ext_frag_fwd_success, s)
|
||||
run_sock_test(test_ipv6_ext_frag_fwd_too_big, s)
|
||||
|
||||
if os.environ.get("BOARD", "") != "native":
|
||||
# ethos currently can't handle the larger, rapidly sent packets by the
|
||||
# IPv6 fragmentation of the Linux Kernel
|
||||
print("SUCCESS for unittests.")
|
||||
print("Skipping interaction tests due to ethos bug.")
|
||||
print("SUCCESS")
|
||||
print("Skipping datagram reception tests due to ethos bug.")
|
||||
return
|
||||
|
||||
# datagram reception tests
|
||||
res = 1
|
||||
count = 0
|
||||
while res:
|
||||
@ -197,4 +400,9 @@ def testfunc(child):
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(run(testfunc, timeout=1, echo=False))
|
||||
if os.geteuid() != 0:
|
||||
print("\x1b[1;31mThis test requires root privileges.\n"
|
||||
"It's constructing and sending Ethernet frames.\x1b[0m\n",
|
||||
file=sys.stderr)
|
||||
sys.exit(1)
|
||||
sys.exit(run(testfunc, timeout=2, echo=False))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user