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

gnrc_netif: check all required options on initialization #10532

Merged
merged 4 commits into from
Feb 26, 2019
Merged
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
1 change: 1 addition & 0 deletions drivers/include/net/netdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ extern "C" {

enum {
NETDEV_TYPE_UNKNOWN,
NETDEV_TYPE_TEST,
NETDEV_TYPE_RAW,
NETDEV_TYPE_ETHERNET,
NETDEV_TYPE_IEEE802154,
Expand Down
107 changes: 107 additions & 0 deletions sys/net/gnrc/netif/gnrc_netif.c
Original file line number Diff line number Diff line change
Expand Up @@ -1161,6 +1161,110 @@ static void _configure_netdev(netdev_t *dev)
#endif
}

#ifdef DEVELHELP
/* checks if a device supports all required options and functions */
static void _test_options(gnrc_netif_t *netif)
{
uint8_t dummy_addr[GNRC_NETIF_L2ADDR_MAXLEN] = { 0 };
ndp_opt_t dummy_opt = { .len = 1U };
uint64_t tmp64 = 0ULL;

(void)dummy_addr;
(void)dummy_opt;
(void)tmp64;
#if (GNRC_NETIF_L2ADDR_MAXLEN > 0)
/* check if address was set in _update_l2addr_from_dev()
* (NETOPT_DEVICE_TYPE already tested in _configure_netdev()) and
* if MTU and max. fragment size was set properly by
* gnrc_netif_ipv6_init_mtu()
* all checked types below have link-layer addresses so we don't need to
* check `GNRC_NETIF_FLAGS_HAS_L2ADDR` */
switch (netif->device_type) {
#ifdef TEST_SUITES
case NETDEV_TYPE_TEST:
/* make no assumptions about test devices */
break;
#endif
case NETDEV_TYPE_BLE:
case NETDEV_TYPE_ETHERNET:
case NETDEV_TYPE_ESP_NOW:
assert(netif->flags & GNRC_NETIF_FLAGS_HAS_L2ADDR);
assert(ETHERNET_ADDR_LEN == netif->l2addr_len);
#ifdef MODULE_GNRC_IPV6
switch (netif->device_type) {
case NETDEV_TYPE_BLE:
assert(netif->ipv6.mtu == IPV6_MIN_MTU);
break;
case NETDEV_TYPE_ETHERNET:
assert(netif->ipv6.mtu == ETHERNET_DATA_LEN);
break;
case NETDEV_TYPE_ESP_NOW:
assert(netif->ipv6.mtu <= ETHERNET_DATA_LEN);
}
#endif /* MODULE GNRC_IPV6 */
break;
case NETDEV_TYPE_IEEE802154:
case NETDEV_TYPE_NRFMIN: {
gnrc_nettype_t tmp;

/* in case assert() evaluates to NOP */
(void)tmp;
assert(netif->flags & GNRC_NETIF_FLAGS_HAS_L2ADDR);
assert((IEEE802154_SHORT_ADDRESS_LEN == netif->l2addr_len) ||
(IEEE802154_LONG_ADDRESS_LEN == netif->l2addr_len));
assert(-ENOTSUP != netif->dev->driver->get(netif->dev, NETOPT_PROTO,
&tmp, sizeof(tmp)));
#ifdef MODULE_GNRC_IPV6
#ifdef MODULE_GNRC_SIXLOWPAN
assert(netif->ipv6.mtu == IPV6_MIN_MTU);
assert(netif->sixlo.max_frag_size > 0);
#else /* MODULE_GNRC_SIXLOWPAN */
assert(netif->ipv6.mtu < UINT16_MAX);
#endif /* MODULE_GNRC_SIXLOWPAN */
#endif /* MODULE_GNRC_IPV6 */
#ifdef MODULE_GNRC_SIXLOWPAN_ND
assert((netif->device_type != NETDEV_TYPE_IEEE802154) ||
(-ENOTSUP != netif->dev->driver->get(netif->dev,
NETOPT_ADDRESS_LONG,
&dummy_addr,
sizeof(dummy_addr))));
#endif /* MODULE_GNRC_SIXLOWPAN_ND */
break;
}
case NETDEV_TYPE_CC110X:
assert(netif->flags & GNRC_NETIF_FLAGS_HAS_L2ADDR);
assert(1U == netif->l2addr_len);
#ifdef MODULE_GNRC_IPV6
assert(netif->ipv6.mtu < UINT16_MAX);
#endif /* MODULE_GNRC_IPV6 */
break;
case NETDEV_TYPE_SLIP:
assert(!(netif->flags & GNRC_NETIF_FLAGS_HAS_L2ADDR));
assert(0U == netif->l2addr_len);
/* don't check MTU here for now since I'm not sure the current
* one is correct ^^" "*/
break;
default:
/* device type not supported yet, please amend case above when
* porting new device type */
assert(false);
}
/* These functions only apply to network devices having link-layers */
if (netif->flags & GNRC_NETIF_FLAGS_HAS_L2ADDR) {
#ifdef MODULE_GNRC_IPV6
assert(-ENOTSUP != gnrc_netif_ipv6_get_iid(netif, (eui64_t *)&tmp64));
assert(-ENOTSUP != gnrc_netif_ndp_addr_len_from_l2ao(netif,
&dummy_opt));
#endif /* MODULE_GNRC_IPV6 */
#if GNRC_IPV6_NIB_CONF_6LN
assert(-ENOTSUP != gnrc_netif_ipv6_iid_to_addr(netif, (eui64_t *)&tmp64,
dummy_addr));
#endif /* GNRC_IPV6_NIB_CONF_6LN */
}
#endif /* (GNRC_NETIF_L2ADDR_MAXLEN > 0) */
}
#endif /* DEVELHELP */

static void *_gnrc_netif_thread(void *args)
{
gnrc_netapi_opt_t *opt;
Expand Down Expand Up @@ -1194,6 +1298,9 @@ static void *_gnrc_netif_thread(void *args)
}
_configure_netdev(dev);
_init_from_device(netif);
#ifdef DEVELHELP
_test_options(netif);
#endif
netif->cur_hl = GNRC_NETIF_DEFAULT_HL;
#ifdef MODULE_GNRC_IPV6_NIB
gnrc_ipv6_nib_init_iface(netif);
Expand Down
4 changes: 3 additions & 1 deletion sys/net/gnrc/netif/gnrc_netif_device_type.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,11 @@ int gnrc_netif_ndp_addr_len_from_l2ao(gnrc_netif_t *netif,
(void)opt;
return sizeof(uint8_t);
#endif /* MODULE_CC110X */
#if defined(MODULE_NETDEV_ETH) || defined(MODULE_ESP_NOW)
#if defined(MODULE_NETDEV_ETH) || defined(MODULE_ESP_NOW) || \
defined(MODULE_NORDIC_SOFTDEVICE_BLE)
case NETDEV_TYPE_ETHERNET:
case NETDEV_TYPE_ESP_NOW:
case NETDEV_TYPE_BLE:
/* see https://tools.ietf.org/html/rfc2464#section-6*/
if (opt->len == 1U) {
return ETHERNET_ADDR_LEN;
Expand Down
10 changes: 10 additions & 0 deletions tests/gnrc_ipv6_nib_6ln/mockup_netif.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ int _get_address_long(netdev_t *dev, void *value, size_t max_len)
return sizeof(addr);
}

int _get_proto(netdev_t *dev, void *value, size_t max_len)
{
(void)dev;
assert(max_len == sizeof(gnrc_nettype_t));
*((gnrc_nettype_t *)value) = GNRC_NETTYPE_SIXLOWPAN;
return sizeof(gnrc_nettype_t);
}

void _tests_init(void)
{
msg_init_queue(_main_msg_queue, _MSG_QUEUE_SIZE);
Expand All @@ -89,6 +97,8 @@ void _tests_init(void)
_get_src_len);
netdev_test_set_get_cb(&_mock_netdev, NETOPT_ADDRESS_LONG,
_get_address_long);
netdev_test_set_get_cb(&_mock_netdev, NETOPT_PROTO,
_get_proto);
_mock_netif = gnrc_netif_ieee802154_create(
_mock_netif_stack, THREAD_STACKSIZE_DEFAULT, GNRC_NETIF_PRIO,
"mockup_wpan", &_mock_netdev.netdev.netdev
Expand Down
4 changes: 3 additions & 1 deletion tests/gnrc_ndp/Makefile
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
include ../Makefile.tests_common

BOARD_INSUFFICIENT_MEMORY := arduino-duemilanove arduino-mega2560 arduino-uno \
chronos nucleo-f031k6 nucleo-f042k6 nucleo-l031k6 \
chronos nucleo-f030r8 nucleo-f031k6 nucleo-f042k6 \
nucleo-l031k6 nucleo-l053r8 stm32f0discovery \
telosb waspmote-pro wsn430-v1_3b wsn430-v1_4

USEMODULE += gnrc_ipv6_nib_router
USEMODULE += gnrc_ndp
USEMODULE += gnrc_netif
USEMODULE += embunit
USEMODULE += netdev_ieee802154
USEMODULE += netdev_test

CFLAGS += -DGNRC_NETTYPE_NDP=GNRC_NETTYPE_TEST
Expand Down
88 changes: 45 additions & 43 deletions tests/gnrc_ndp/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,9 @@ static void test_nbr_sol_send(const ipv6_addr_t *src)
gnrc_pktsnip_t *pkt;
ndp_nbr_sol_t *nbr_sol;

while (msg_try_receive(&msg) == 1) {
/* empty message queue */
}
TEST_ASSERT_NOT_NULL(test_netif);
gnrc_ndp_nbr_sol_send(&test_tgt, test_netif, src, &test_dst, NULL);
msg_receive(&msg);
Expand Down Expand Up @@ -947,45 +950,6 @@ static gnrc_pktsnip_t *_test_netif_recv(gnrc_netif_t *netif)
return NULL;
}

static int _test_netif_get(gnrc_netif_t *netif, gnrc_netapi_opt_t *opt)
{
(void)netif;
switch (opt->opt) {
case NETOPT_ADDRESS_LONG:
if (opt->data_len < sizeof(test_src_l2)) {
return -EOVERFLOW;
}
memcpy(opt->data, test_src_l2, sizeof(test_src_l2));
return sizeof(test_src_l2);
case NETOPT_SRC_LEN: {
uint16_t *val = opt->data;
if (opt->data_len != sizeof(uint16_t)) {
return -EOVERFLOW;
}
*val = sizeof(test_src_l2);
return sizeof(uint16_t);
}
case NETOPT_IPV6_IID:
if (opt->data_len < sizeof(uint64_t)) {
return -EOVERFLOW;
}
memcpy(opt->data, &test_src.u64[1], sizeof(uint64_t));
return sizeof(uint64_t);
case NETOPT_IS_WIRED:
return 1;
case NETOPT_MAX_PDU_SIZE: {
uint16_t *val = opt->data;
if (opt->data_len != sizeof(uint16_t)) {
return -EOVERFLOW;
}
*val = 100U;
return sizeof(uint16_t);
}
default:
return -ENOTSUP;
}
}

static int _test_netif_set(gnrc_netif_t *netif, const gnrc_netapi_opt_t *opt)
{
(void)netif;
Expand All @@ -996,11 +960,43 @@ static int _test_netif_set(gnrc_netif_t *netif, const gnrc_netapi_opt_t *opt)
static const gnrc_netif_ops_t _test_netif_ops = {
.send = _test_netif_send,
.recv = _test_netif_recv,
.get = _test_netif_get,
.get = gnrc_netif_get_from_netdev,
.set = _test_netif_set,
};

int _netdev_test_device_type_get(netdev_t *dev, void *value, size_t max_len)
static int _netdev_test_address_long(netdev_t *dev, void *value, size_t max_len)
{
(void)dev;
assert(max_len >= sizeof(test_src_l2));
memcpy(value, test_src_l2, sizeof(test_src_l2));
return sizeof(test_src_l2);
}

static int _netdev_test_proto(netdev_t *dev, void *value, size_t max_len)
{
(void)dev;
assert(max_len == sizeof(gnrc_nettype_t));
*((gnrc_nettype_t *)value) = GNRC_NETTYPE_UNDEF;
return sizeof(gnrc_nettype_t);
}

static int _netdev_test_src_len(netdev_t *dev, void *value, size_t max_len)
{
(void)dev;
assert(max_len == sizeof(uint16_t));
*((uint16_t *)value) = sizeof(test_src_l2);
return sizeof(uint16_t);
}

static int _netdev_test_max_pdu_size(netdev_t *dev, void *value, size_t max_len)
{
(void)dev;
assert(max_len == sizeof(uint16_t));
*((uint16_t *)value) = 100U;
return sizeof(uint16_t);
}

static int _netdev_test_device_type(netdev_t *dev, void *value, size_t max_len)
{
(void)dev;
assert(max_len == sizeof(uint16_t));
Expand All @@ -1015,10 +1011,16 @@ static void init_pkt_handler(void)
sched_active_pid);
gnrc_netreg_register(GNRC_NETTYPE_NDP, &netreg_entry);
netdev_test_setup(&dev, NULL);
netdev_test_set_get_cb(&dev, NETOPT_DEVICE_TYPE, _netdev_test_device_type_get);
netdev_test_set_get_cb(&dev, NETOPT_ADDRESS_LONG,
_netdev_test_address_long);
netdev_test_set_get_cb(&dev, NETOPT_PROTO, _netdev_test_proto);
netdev_test_set_get_cb(&dev, NETOPT_SRC_LEN, _netdev_test_src_len);
netdev_test_set_get_cb(&dev, NETOPT_MAX_PDU_SIZE,
_netdev_test_max_pdu_size);
netdev_test_set_get_cb(&dev, NETOPT_DEVICE_TYPE, _netdev_test_device_type);
test_netif = gnrc_netif_create(test_netif_stack, sizeof(test_netif_stack),
GNRC_NETIF_PRIO, "test-netif",
&dev.netdev, &_test_netif_ops);
&dev.netdev.netdev, &_test_netif_ops);
TEST_ASSERT_MESSAGE(test_netif != NULL,
"Unable to start test interface");
memcpy(&test_netif->ipv6.addrs[0], &test_src,
Expand Down
12 changes: 11 additions & 1 deletion tests/gnrc_netif/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,19 @@ static int _get_netdev_device_type(netdev_t *netdev, void *value, size_t max_len
*((uint16_t *)value) = NETDEV_TYPE_IEEE802154;
}
else {
*((uint16_t *)value) = NETDEV_TYPE_UNKNOWN;
*((uint16_t *)value) = NETDEV_TYPE_TEST;
}
return sizeof(uint16_t);
}

static int _get_netdev_proto(netdev_t *dev, void *value, size_t max_len)
{
assert(dev == ieee802154_dev);
assert(max_len == sizeof(gnrc_nettype_t));
*((gnrc_nettype_t *)value) = GNRC_NETTYPE_UNDEF;
return sizeof(gnrc_nettype_t);
}

static int _get_netdev_max_packet_size(netdev_t *netdev, void *value, size_t max_len)
{
assert(max_len == sizeof(uint16_t));
Expand Down Expand Up @@ -166,6 +174,8 @@ void _tests_init(void)
netdev_test_set_isr_cb((netdev_test_t *)ieee802154_dev, _netdev_isr);
netdev_test_set_get_cb((netdev_test_t *)ieee802154_dev, NETOPT_DEVICE_TYPE,
_get_netdev_device_type);
netdev_test_set_get_cb((netdev_test_t *)ieee802154_dev, NETOPT_PROTO,
_get_netdev_proto);
netdev_test_set_get_cb((netdev_test_t *)ieee802154_dev,
NETOPT_MAX_PDU_SIZE, _get_netdev_max_packet_size);
for (intptr_t i = SPECIAL_DEVS; i < GNRC_NETIF_NUMOF; i++) {
Expand Down
2 changes: 1 addition & 1 deletion tests/gnrc_netif/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ static void test_creation(void)
TEST_ASSERT_NOT_NULL(netifs[i]->ops);
TEST_ASSERT_NOT_NULL(netifs[i]->dev);
TEST_ASSERT_EQUAL_INT(GNRC_NETIF_DEFAULT_HL, netifs[i]->cur_hl);
TEST_ASSERT_EQUAL_INT(NETDEV_TYPE_UNKNOWN, netifs[i]->device_type);
TEST_ASSERT_EQUAL_INT(NETDEV_TYPE_TEST, netifs[i]->device_type);
TEST_ASSERT(netifs[i]->pid > KERNEL_PID_UNDEF);
TEST_ASSERT(thread_has_msg_queue(sched_threads[netifs[i]->pid]));
TEST_ASSERT_EQUAL_INT(i + SPECIAL_DEVS + 1, gnrc_netif_numof());
Expand Down
11 changes: 11 additions & 0 deletions tests/gnrc_sixlowpan/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ static int _get_netdev_device_type(netdev_t *netdev, void *value, size_t max_len
return sizeof(uint16_t);
}

static int _get_netdev_proto(netdev_t *netdev, void *value, size_t max_len)
{
assert(max_len == sizeof(gnrc_nettype_t));
(void)netdev;

*((gnrc_nettype_t *)value) = GNRC_NETTYPE_SIXLOWPAN;
return sizeof(gnrc_nettype_t);
}

static int _get_netdev_max_packet_size(netdev_t *netdev, void *value,
size_t max_len)
{
Expand Down Expand Up @@ -91,6 +100,8 @@ static void _init_interface(void)
netdev_test_setup(&_ieee802154_dev, NULL);
netdev_test_set_get_cb(&_ieee802154_dev, NETOPT_DEVICE_TYPE,
_get_netdev_device_type);
netdev_test_set_get_cb(&_ieee802154_dev, NETOPT_PROTO,
_get_netdev_proto);
netdev_test_set_get_cb(&_ieee802154_dev, NETOPT_MAX_PDU_SIZE,
_get_netdev_max_packet_size);
netdev_test_set_get_cb(&_ieee802154_dev, NETOPT_SRC_LEN,
Expand Down