Skip to content

Commit

Permalink
Merge pull request #7462 from miri64/gnrc_netif2/feat/raw
Browse files Browse the repository at this point in the history
gnrc_netif2: provide raw adaption layer (for e.g. SLIP)
  • Loading branch information
miri64 authored Nov 15, 2017
2 parents 30f9cac + 852cb5a commit e756d2a
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 18 deletions.
19 changes: 5 additions & 14 deletions sys/auto_init/netif/auto_init_slipdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@

#include "log.h"
#include "board.h"
#include "net/gnrc/netdev.h"
#include "net/gnrc/netdev/raw.h"
#include "net/gnrc/netif2/raw.h"
#include "net/gnrc.h"

#include "slipdev.h"
Expand All @@ -36,11 +35,10 @@
*/
#define SLIPDEV_STACKSIZE (THREAD_STACKSIZE_DEFAULT)
#ifndef SLIPDEV_PRIO
#define SLIPDEV_PRIO (GNRC_NETDEV_MAC_PRIO)
#define SLIPDEV_PRIO (GNRC_NETIF2_PRIO)
#endif

static slipdev_t slipdevs[SLIPDEV_NUM];
static gnrc_netdev_t gnrc_adpt[SLIPDEV_NUM];
static char _slipdev_stacks[SLIPDEV_NUM][SLIPDEV_STACKSIZE];

void auto_init_slipdev(void)
Expand All @@ -51,16 +49,9 @@ void auto_init_slipdev(void)
LOG_DEBUG("[auto_init_netif] initializing slip #%u\n", i);

slipdev_setup(&slipdevs[i], p);
kernel_pid_t res = gnrc_netdev_raw_init(&gnrc_adpt[i],
(netdev_t *)&slipdevs[i]);

if (res < 0) {
LOG_ERROR("[auto_init_netif] error initializing slipdev #%u\n", i);
}
else {
gnrc_netdev_init(_slipdev_stacks[i], SLIPDEV_STACKSIZE,
SLIPDEV_PRIO, "slipdev", &gnrc_adpt[i]);
}
gnrc_netif2_raw_create(_slipdev_stacks[i], SLIPDEV_STACKSIZE,
SLIPDEV_PRIO, "slipdev",
(netdev_t *)&slipdevs[i]);
}
}
#else
Expand Down
50 changes: 50 additions & 0 deletions sys/include/net/gnrc/netif2/raw.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright (C) 2017 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 net_gnrc_netif2
* @{
*
* @file
* @brief Raw (i.e. raw IP packets without link-layer information) adaptation
* for @ref net_gnrc_netif2
*
* @author Martine Lenders <[email protected]>
*/
#ifndef NET_GNRC_NETIF2_RAW_H
#define NET_GNRC_NETIF2_RAW_H

#include "net/gnrc/netif2.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief Creates a raw network interface
*
* @param[in] stack The stack for the network interface's thread.
* @param[in] stacksize Size of @p stack.
* @param[in] priority Priority for the network interface's thread.
* @param[in] name Name for the network interface. May be NULL.
* @param[in] dev Device for the interface.
*
* @see @ref gnrc_netif2_create()
*
* @return The network interface on success.
* @return NULL, on error.
*/
gnrc_netif2_t *gnrc_netif2_raw_create(char *stack, int stacksize, char priority,
char *name, netdev_t *dev);

#ifdef __cplusplus
}
#endif

#endif /* NET_GNRC_NETIF2_RAW_H */
/** @} */
12 changes: 9 additions & 3 deletions sys/net/gnrc/netif2/gnrc_netif2.c
Original file line number Diff line number Diff line change
Expand Up @@ -1100,11 +1100,17 @@ static void _init_from_device(gnrc_netif2_t *netif)
break;
#endif
default:
res = dev->driver->get(dev, NETOPT_MAX_PACKET_SIZE, &tmp, sizeof(tmp));
assert(res == sizeof(tmp));
#ifdef MODULE_GNRC_IPV6
netif->ipv6.mtu = tmp;
res = dev->driver->get(dev, NETOPT_MAX_PACKET_SIZE, &tmp, sizeof(tmp));
if (res < 0) {
/* assume maximum possible transition unit */
netif->ipv6.mtu = UINT16_MAX;
}
else {
netif->ipv6.mtu = tmp;
}
#endif
break;
}
_update_l2addr_from_dev(netif);
}
Expand Down
116 changes: 116 additions & 0 deletions sys/net/gnrc/netif2/gnrc_netif2_raw.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
* Copyright (C) 2017 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 <[email protected]>
*/

#include "net/gnrc/pktbuf.h"
#include "net/gnrc/netif2/raw.h"

#define ENABLE_DEBUG (0)
#include "debug.h"

#define IP_VERSION_MASK (0xf0U)
#define IP_VERSION4 (0x40U)
#define IP_VERSION6 (0x60U)


static int _send(gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt);
static gnrc_pktsnip_t *_recv(gnrc_netif2_t *netif);

static const gnrc_netif2_ops_t raw_ops = {
.send = _send,
.recv = _recv,
.get = gnrc_netif2_get_from_netdev,
.set = gnrc_netif2_set_from_netdev,
};

gnrc_netif2_t *gnrc_netif2_raw_create(char *stack, int stacksize,
char priority, char *name,
netdev_t *dev)
{
return gnrc_netif2_create(stack, stacksize, priority, name, dev,
&raw_ops);
}

static inline uint8_t _get_version(uint8_t *data)
{
return (data[0] & IP_VERSION_MASK);
}

static gnrc_pktsnip_t *_recv(gnrc_netif2_t *netif)
{
netdev_t *dev = netif->dev;
int bytes_expected = dev->driver->recv(dev, NULL, 0, NULL);
gnrc_pktsnip_t *pkt = NULL;

if (bytes_expected > 0) {
int nread;

pkt = gnrc_pktbuf_add(NULL, NULL, bytes_expected, GNRC_NETTYPE_UNDEF);

if (!pkt) {
DEBUG("gnrc_netif_raw: cannot allocate pktsnip.\n");
/* drop packet */
dev->driver->recv(dev, NULL, bytes_expected, NULL);
return pkt;
}
nread = dev->driver->recv(dev, pkt->data, bytes_expected, NULL);
if (nread <= 1) { /* we need at least 1 byte to identify IP version */
DEBUG("gnrc_netif_raw: read error.\n");
gnrc_pktbuf_release(pkt);
return NULL;
}
if (nread < bytes_expected) {
/* we've got less then the expected packet size,
* so free the unused space.*/
DEBUG("gnrc_netif_raw: reallocating.\n");
gnrc_pktbuf_realloc_data(pkt, nread);
}
switch (_get_version(pkt->data)) {
#ifdef MODULE_GNRC_IPV6
case IP_VERSION6:
pkt->type = GNRC_NETTYPE_IPV6;
break;
#endif
default:
/* leave UNDEF */
break;
}
}
return pkt;
}

static int _send(gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt)
{
gnrc_pktsnip_t *vector;
int res = -ENOBUFS;
size_t n;

if (pkt->type == GNRC_NETTYPE_NETIF) {
/* we don't need the netif snip: remove it */
pkt = gnrc_pktbuf_remove_snip(pkt, pkt);
}
vector = gnrc_pktbuf_get_iovec(pkt, &n);
if (vector != NULL) {
struct iovec *v = (struct iovec *)vector->data;
netdev_t *dev = netif->dev;

#ifdef MODULE_NETSTATS_L2
dev->stats.tx_unicast_count++;
#endif
res = dev->driver->send(dev, v, n);
}
return res;
}

/** @} */
1 change: 0 additions & 1 deletion tests/slip/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ BOARD_BLACKLIST += mips-malta
USEMODULE += auto_init_gnrc_netif
USEMODULE += gnrc
USEMODULE += gnrc_pktdump
USEMODULE += gnrc_netdev
USEMODULE += gnrc_txtsnd
USEMODULE += slipdev
USEMODULE += shell
Expand Down

0 comments on commit e756d2a

Please sign in to comment.