Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tests: add tests for netdev flooding race-condition #11256

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions tests/netdev_flood_flooder/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
BOARD ?= samr21-xpro

include ../Makefile.tests_common

# currently only the following network devices are supported by this test
# - at86rf2xx
# so only whitelist boards that have these devices on-board
BOARD_WHITELIST = fox iotlab-m3 iotlab-a8-m3 mulle samr21-xpro samr30-xpro

DISABLE_MODULE += auto_init

USEMODULE += netdev_default
USEMODULE += xtimer

include $(RIOTBASE)/Makefile.include
43 changes: 43 additions & 0 deletions tests/netdev_flood_flooder/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Testing rapidly sending packets while the receiving node tries to reply

## Usage

This test is supposed to be used in tandem with [netdev_flood_replier].

**Before** you start the replier first flash this application to another board
that supports the same link-layer technology as the device under test on the
replier:

```sh
make flash
```

You can test if everything went right by connecting via terminal to the node

```sh
make term
```

If after a reset the following message is shown and no error messages follow,
the device started flooding successfully

```
Starting to flood now; start an instance of tests/netdev_flood_replier
(on a device with matching link-layer ;-)) to see results.
```

## Support for more devices
Currently the following devices are supported with this test:

- `at86rf2xx`

To extend the coverage of this test, just add the setup and sending behavior for
your device in the functions it is documented

```C
/**
* @note Please amend for more device support
*/
```

[netdev_flood_replier]: ../netdev_flood_replier/
212 changes: 212 additions & 0 deletions tests/netdev_flood_flooder/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
/*
* Copyright (C) 2019 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

/**
* @{
*
* @file
* @author Martine Lenders <m.lenders@fu-berlin.de>
*/

#include <stddef.h>
#include <stdint.h>
#include <stdio.h>

#ifdef MODULE_AT86RF2XX
#include "at86rf2xx.h"
#include "at86rf2xx_params.h"
#endif /* MODULE_AT86RF2XX */

#include "net/netdev.h"
#include "xtimer.h"

#include "netdev_flood.h"

#if defined(MODULE_AT86RF2XX)
#define NETDEV_ADDR_LEN (2U)
#define NETDEV_FLOOD_HDR_SEQ_OFFSET (2U)
/* IEEE 802.15.4 header */
#define NETDEV_FLOOD_HDR { 0x71, 0x98, /* FCF */ \
0xa1, /* Sequence number 161 */ \
0x23, 0x00, /* PAN ID 0x23 */ \
0x0e, 0x50, /* 0x500e (start of NETDEV_FLOOD_TARGET) */ \
0x0e, 0x12, /* 0x120e (start of NETDEV_FLOOD_SOURCE) */ }
#else
Comment on lines +30 to +39
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this at86rf2xx specific?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because this test is trying to point out a problem in the at86rf2xx implementation. For other drivers other data might be needed. See also https://github.com/RIOT-OS/RIOT/pull/11256/files#diff-f29476e871b447f52f062cd754786b75R53-R54

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the 802.15.4 header should be the same for all 802.15.4 devices - what configuration would that be?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 802.15.4 header, yes. I don't remember if this data was specific to the error case though.

/**
* @brief The address length for the devices
*
* @note Please define for your device (try to find a common one)
*/
#define NETDEV_ADDR_LEN (8U)

/**
* @brief The header for the packets that flood the target
*
* @note Please define for your device
*/
#define NETDEV_FLOOD_HDR { 0 }
#error "Board not supported by this test; please provide setup for the " \
"board's network device"
#endif

/**
* @brief The address of the flooding source (in-memory version)
*/
static const uint8_t _flood_source[] = NETDEV_FLOOD_SOURCE;

/**
* @brief The header for the packets that flood the target (in-memory version)
*/
static uint8_t _flood_hdr[] = NETDEV_FLOOD_HDR;

/**
* @brief The payload for the packets that flood the target (in-memory version)
*/
static uint8_t _flood_payload[] = NETDEV_FLOOD_PAYLOAD;

/**
* @brief Payload iolist entry for _flood_payload
*/
static iolist_t _flood_payload_ioe = {
.iol_next = NULL,
.iol_base = _flood_payload,
.iol_len = sizeof(_flood_payload),
};

/**
* @brief The packet to flood the target with
*/
static iolist_t _flood_pkt = {
.iol_next = &_flood_payload_ioe,
.iol_base = _flood_hdr,
.iol_len = sizeof(_flood_hdr),
};

/**
* @brief Setups and initializes the flooding device
*
* @note Please amend for more device support
*/
static void _setup(void);

/**
* @brief Get's the flooding device as a netdev_t pointer
*
* @note Please amend for more device support
*
* @return The flooding device as a netdev_t pointer
*/
static inline netdev_t *_get_netdev(void);

/**
* @brief Updates _flood_pkt according to the needs of the link-layer of the
* device (e.g. increment sequence number)
*
* @param[in] dev The device
*
* @note Please amend for more device support
*/
static void _update_packet(netdev_t *dev);

/**
* @brief Activates RX complete for the device
*
* @param[in] dev The device
*/
static void _config_netdev(netdev_t *dev);

/**
* @brief Configures the address to NETDEV_FLOOD_SOURCE of length
* NETDEV_ADDR_LEN for @p dev
*
* @param[in] dev The device
*
* @return 0 on success
* @return -1 on error
*/
static inline int _config_address(netdev_t *dev);

int main(void)
{
netdev_t *dev;

_setup();
xtimer_init();
dev = _get_netdev();
if (dev == NULL) {
puts("Board not supported by this test; please provide setup for the "
"board's network device");
return 1;
}
dev->driver->init(dev);
_config_netdev(dev);
if (_config_address(dev) < 0) {
puts("Unable to configure address");
return 1;
}
puts("Starting to flood now; start an instance of tests/netdev_flood_replier\n"
"(on a device with matching link-layer ;-)) to see results.");
while (1) {
/* wait for NETDEV_FLOOD_INTERVAL microseconds to send next packet */
xtimer_usleep(NETDEV_FLOOD_INTERVAL);
if (dev->driver->send(dev, &_flood_pkt) < 0) {
puts("Error on send");
}
_update_packet(dev);
}
return 0;
}

#ifdef MODULE_AT86RF2XX
static at86rf2xx_t at86rf2xx_dev;
#endif /* MODULE_AT86RF2XX */

static void _setup(void)
{
#ifdef MODULE_AT86RF2XX
at86rf2xx_setup(&at86rf2xx_dev, &at86rf2xx_params[0]);
#endif /* MODULE_AT86RF2XX */
}

static inline netdev_t *_get_netdev(void)
{
#ifdef MODULE_AT86RF2XX
return (netdev_t *)&at86rf2xx_dev;
#else /* MODULE_AT86RF2XX */
return NULL;
#endif /* MODULE_AT86RF2XX */
}

static void _update_packet(netdev_t *dev)
{
#if defined(MODULE_AT86RF2XX)
(void)dev;
_flood_hdr[NETDEV_FLOOD_HDR_SEQ_OFFSET]++;
#endif
}

static void _config_netdev(netdev_t *dev)
{
static const netopt_enable_t enable = NETOPT_ENABLE;
int res = dev->driver->set(dev, NETOPT_RX_END_IRQ, &enable, sizeof(enable));

if (res < 0) {
puts("enable NETOPT_RX_END_IRQ failed");
}
}

static inline int _config_address(netdev_t *dev)
{
if (dev->driver->set(dev, NETOPT_ADDRESS,
_flood_source, NETDEV_ADDR_LEN) < 0) {
return -1;
}
return 0;
}

/** @} */
59 changes: 59 additions & 0 deletions tests/netdev_flood_flooder/netdev_flood.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright (C) 2019 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

/**
* @ingroup tests
* @{
*
* @file
* @brief Common definitions for the netdev flood tests
*
* @author Martine Lenders <m.lenders@fu-berlin.de>
*/
#ifndef NETDEV_FLOOD_H
#define NETDEV_FLOOD_H

#include "timex.h"

#ifdef __cplusplus
extern "C" {
#endif


#define NETDEV_FLOOD_PKT_SIZE (48U) /**< size of NETDEV_FLOOD_PAYLOAD + l2 hdr */

/**
* @brief The payload for the packets that flood the target
*/
#define NETDEV_FLOOD_PAYLOAD { 0x53, 0x6f, 0x20, 0x73, 0x6f, 0x72, 0x72, 0x79, \
0x20, 0x66, 0x6f, 0x72, 0x20, 0x66, 0x6c, 0x6f, \
0x6f, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x79, 0x6f, \
0x75, 0x72, 0x20, 0x6e, 0x65, 0x74, 0x77, 0x6f, \
0x72, 0x6b, 0x21, 0x20, 0x3e, 0x2e, 0x3c }

/**
* @brief The address of the flooding source
*/
#define NETDEV_FLOOD_SOURCE { 0x12, 0x0e, 0x2e, 0x0a, 0xf0, 0xc4, 0xb1, 0xe7 }

/**
* @brief The address of the flooding target
*/
#define NETDEV_FLOOD_TARGET { 0x50, 0x0e, 0x61, 0xf2, 0xde, 0x44, 0x8f, 0xb4 }

/**
* @brief Flood interval in micro seconds
*/
#define NETDEV_FLOOD_INTERVAL (5 * US_PER_MS)

#ifdef __cplusplus
}
#endif

#endif /* NETDEV_FLOOD_H */
/** @} */
19 changes: 19 additions & 0 deletions tests/netdev_flood_replier/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
BOARD ?= samr21-xpro

include ../Makefile.tests_common

# currently only the following network devices are supported by this test
# - at86rf2xx
# so only whitelist boards that have these devices on-board
BOARD_WHITELIST = fox iotlab-m3 iotlab-a8-m3 mulle samr21-xpro samr30-xpro

DISABLE_MODULE += auto_init

USEMODULE += event
USEMODULE += event_timeout
USEMODULE += netdev_default
USEMODULE += od

INCLUDES += -I$(RIOTBASE)/tests/netdev_flood_flooder/

include $(RIOTBASE)/Makefile.include
34 changes: 34 additions & 0 deletions tests/netdev_flood_replier/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Testing rapidly received packets while sending replies

## Usage

This test is supposed to be used in tandem with [netdev_flood_flooder].

It is supposed to test a bug in network devices where an incoming packet is
overwitten by a sent packet before it is read by the upper layer.

Start the flooder first (see README there) and then flash this application and
run the test

```sh
make flash
make test
```

If there is no output for a while, the test was successful.

## Support for more devices
Currently the following devices are supported with this test:

- `at86rf2xx`

To extend the coverage of this test, just add the setup, sending, and reception
behavior for your device in the functions it is documented

```C
/**
* @note Please amend for more device support
*/
```

[netdev_flood_flooder]: ../netdev_flood_flooder/
Loading