Skip to content

Commit

Permalink
Merge pull request #10524 from miri64/gnrc_netif/enh/centralize-dev-t…
Browse files Browse the repository at this point in the history
…ype-functions

 gnrc_netif: centralize device-type-specific functions
  • Loading branch information
cgundogan authored Jan 16, 2019
2 parents 6145266 + 55b9757 commit b24a8fb
Show file tree
Hide file tree
Showing 5 changed files with 225 additions and 131 deletions.
1 change: 1 addition & 0 deletions sys/include/net/gnrc/netif.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#endif
#include "net/ndp.h"
#include "net/netdev.h"
#include "net/netopt.h"
#include "rmutex.h"

#ifdef __cplusplus
Expand Down
68 changes: 66 additions & 2 deletions sys/include/net/gnrc/netif/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#define NET_GNRC_NETIF_INTERNAL_H

#include "net/gnrc/netif.h"
#include "net/netopt.h"

#ifdef MODULE_GNRC_IPV6_NIB
#include "net/gnrc/ipv6/nib/conf.h"
Expand Down Expand Up @@ -403,7 +404,37 @@ static inline bool gnrc_netif_is_6lbr(const gnrc_netif_t *netif)
#define gnrc_netif_is_6lbr(netif) (false)
#endif

/**
* @name Device type based function
*
* These functions' behavior is based around the gnrc_netif_t::device_type of
* an interface.
*
* @attention Special care needs to be taken for those functions when porting
* a new network device type or link-layer protocol: They might
* need adaptions for your port
* @{
*/
/**
* @brief Get the default link-layer address option for the given
* gnrc_netif_t::device_type of a network interface
*
* @param[in] netif The network interface to get the default link-layer
* address option for.
*
* @return Either @ref NETOPT_ADDRESS or @ref NETOPT_ADDRESS_LONG.
*/
netopt_t gnrc_netif_get_l2addr_opt(const gnrc_netif_t *netif);

#if defined(MODULE_GNRC_IPV6) || defined(DOXYGEN)
/**
* @brief Initialize IPv6 MTU and other packet length related members of
* @ref gnrc_netif_t based on gnrc_netif_t::device_type
*
* @param[in,out] netif The network interface to initialize the MTU for.
*/
void gnrc_netif_ipv6_init_mtu(gnrc_netif_t *netif);

/**
* @brief Converts a given hardware address to an IPv6 IID.
*
Expand Down Expand Up @@ -484,11 +515,44 @@ static inline int gnrc_netif_ipv6_get_iid(gnrc_netif_t *netif, eui64_t *iid)
(void)iid;
return -ENOTSUP;
}

/**
* @brief Derives the length of the link-layer address in an NDP link-layer
* address option from that option's length field and the given device
* type.
*
* @note If an RFC exists that specifies how IPv6 operates over a link-layer,
* this function usually implements the section "Unicast Address
* Mapping".
*
* @see [RFC 4861, section 4.6.1](https://tools.ietf.org/html/rfc4861#section-4.6.1)
*
* @pre `netif->flags & GNRC_NETIF_FLAGS_HAS_L2ADDR`
*
* @attention When `NDEBUG` is not defined, the node fails with an assertion
* instead of returning `-ENOTSUP`
*
* @param[in] netif The network interface @p opt was received on within an NDP
* message.
* @param[in] opt An NDP source/target link-layer address option.
*
* @return Length of the link-layer address in @p opt on success
* @return `-ENOTSUP`, when implementation does not know how to derive the
* length of the link-layer address from @p opt's length field based
* on gnrc_netif_t::device_type of @p netif.
* @return `-EINVAL` if `opt->len` was an invalid value for the given
* gnrc_netif_t::device_type of @p netif.
*/
int gnrc_netif_ndp_addr_len_from_l2ao(gnrc_netif_t *netif,
const ndp_opt_t *opt);
#else /* defined(MODULE_GNRC_IPV6) || defined(DOXYGEN) */
#define gnrc_netif_ipv6_iid_from_addr(netif, addr, addr_len, iid) (-ENOTSUP)
#define gnrc_netif_ipv6_iid_to_addr(netif, iid, addr) (-ENOTSUP)
#define gnrc_netif_ipv6_init_mtu(netif) (void)netif
#define gnrc_netif_ipv6_iid_from_addr(netif, addr, addr_len, iid) (-ENOTSUP)
#define gnrc_netif_ipv6_iid_to_addr(netif, iid, addr) (-ENOTSUP)
#define gnrc_netif_ndp_addr_len_from_l2ao(netif, opt) (-ENOTSUP)
#define gnrc_netif_ipv6_get_iid(netif, iid) (-ENOTSUP)
#endif /* defined(MODULE_GNRC_IPV6) || defined(DOXYGEN) */
/** @} */

#ifdef __cplusplus
}
Expand Down
76 changes: 2 additions & 74 deletions sys/net/gnrc/netif/gnrc_netif.c
Original file line number Diff line number Diff line change
Expand Up @@ -1109,27 +1109,8 @@ static void _update_l2addr_from_dev(gnrc_netif_t *netif)
{
netdev_t *dev = netif->dev;
int res;
netopt_t opt = NETOPT_ADDRESS;
netopt_t opt = gnrc_netif_get_l2addr_opt(netif);

switch (netif->device_type) {
#if defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_XBEE) \
|| defined(MODULE_NORDIC_SOFTDEVICE_BLE)
case NETDEV_TYPE_BLE:
case NETDEV_TYPE_IEEE802154: {
uint16_t tmp;

res = dev->driver->get(dev, NETOPT_SRC_LEN, &tmp, sizeof(tmp));
assert(res == sizeof(tmp));
netif->l2addr_len = (uint8_t)tmp;
if (tmp == IEEE802154_LONG_ADDRESS_LEN) {
opt = NETOPT_ADDRESS_LONG;
}
}
break;
#endif
default:
break;
}
res = dev->driver->get(dev, opt, netif->l2addr,
sizeof(netif->l2addr));
if (res != -ENOTSUP) {
Expand All @@ -1155,60 +1136,7 @@ static void _init_from_device(gnrc_netif_t *netif)
(void)res;
assert(res == sizeof(tmp));
netif->device_type = (uint8_t)tmp;
switch (netif->device_type) {
#if defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_NRFMIN) || \
defined(MODULE_XBEE) || defined(MODULE_ESP_NOW) || \
defined(MODULE_GNRC_SIXLOENC)
case NETDEV_TYPE_IEEE802154:
case NETDEV_TYPE_NRFMIN:
#ifdef MODULE_GNRC_SIXLOWPAN_IPHC
netif->flags |= GNRC_NETIF_FLAGS_6LO_HC;
#endif
/* intentionally falls through */
case NETDEV_TYPE_ESP_NOW:
#ifdef MODULE_GNRC_IPV6
res = dev->driver->get(dev, NETOPT_MAX_PACKET_SIZE, &tmp, sizeof(tmp));
assert(res == sizeof(tmp));
#ifdef MODULE_GNRC_SIXLOWPAN
netif->ipv6.mtu = IPV6_MIN_MTU;
netif->sixlo.max_frag_size = tmp;
#else
netif->ipv6.mtu = tmp;
#endif
#endif
break;
#endif /* MODULE_NETDEV_IEEE802154 */
#ifdef MODULE_NETDEV_ETH
case NETDEV_TYPE_ETHERNET:
#ifdef MODULE_GNRC_IPV6
netif->ipv6.mtu = ETHERNET_DATA_LEN;
#endif
#if defined(MODULE_GNRC_SIXLOWPAN_IPHC) && defined(MODULE_GNRC_SIXLOENC)
netif->flags |= GNRC_NETIF_FLAGS_6LO_HC;
#endif
break;
#endif
#ifdef MODULE_NORDIC_SOFTDEVICE_BLE
case NETDEV_TYPE_BLE:
netif->ipv6.mtu = IPV6_MIN_MTU;
#ifdef MODULE_GNRC_SIXLOWPAN_IPHC
netif->flags |= GNRC_NETIF_FLAGS_6LO_HC;
#endif
break;
#endif
default:
#ifdef MODULE_GNRC_IPV6
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;
}
gnrc_netif_ipv6_init_mtu(netif);
_update_l2addr_from_dev(netif);
}

Expand Down
150 changes: 150 additions & 0 deletions sys/net/gnrc/netif/gnrc_netif_device_type.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,111 @@
#include <errno.h>

#include "log.h"
#ifdef MODULE_GNRC_IPV6
#include "net/ipv6.h"
#endif
#include "net/gnrc/netif.h"
#include "net/eui48.h"
#include "net/ethernet.h"
#include "net/ieee802154.h"

netopt_t gnrc_netif_get_l2addr_opt(const gnrc_netif_t *netif)
{
netopt_t res = NETOPT_ADDRESS;

switch (netif->device_type) {
#if defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_XBEE) || \
defined(MODULE_NORDIC_SOFTDEVICE_BLE)
case NETDEV_TYPE_IEEE802154:
case NETDEV_TYPE_BLE: {
netdev_t *dev = netif->dev;
int r;
uint16_t tmp;

r = dev->driver->get(dev, NETOPT_SRC_LEN, &tmp, sizeof(tmp));
assert(r == sizeof(tmp));
assert(r <= ((int)UINT8_MAX));
(void)r;
if (tmp == IEEE802154_LONG_ADDRESS_LEN) {
res = NETOPT_ADDRESS_LONG;
}
}
break;
#endif
default:
break;
}
return res;
}

#ifdef MODULE_GNRC_IPV6
void gnrc_netif_ipv6_init_mtu(gnrc_netif_t *netif)
{
#ifdef MODULE_GNRC_IPV6
netdev_t *dev = netif->dev;
int res;
uint16_t tmp;

switch (netif->device_type) {
#if defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_NRFMIN) || \
defined(MODULE_XBEE) || defined(MODULE_ESP_NOW) || \
defined(MODULE_GNRC_SIXLOENC)
case NETDEV_TYPE_IEEE802154:
case NETDEV_TYPE_NRFMIN:
#ifdef MODULE_GNRC_SIXLOWPAN_IPHC
netif->flags |= GNRC_NETIF_FLAGS_6LO_HC;
#endif
/* intentionally falls through */
case NETDEV_TYPE_ESP_NOW:
res = dev->driver->get(dev, NETOPT_MAX_PACKET_SIZE,
&tmp, sizeof(tmp));
assert(res == sizeof(tmp));
#ifdef MODULE_GNRC_SIXLOWPAN
netif->ipv6.mtu = IPV6_MIN_MTU;
netif->sixlo.max_frag_size = tmp;
#else
netif->ipv6.mtu = tmp;
#endif
break;
#endif /* defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_NRFMIN) || \
* defined(MODULE_XBEE) || defined(MODULE_ESP_NOW) */
#ifdef MODULE_NETDEV_ETH
case NETDEV_TYPE_ETHERNET:
#ifdef MODULE_GNRC_IPV6
netif->ipv6.mtu = ETHERNET_DATA_LEN;
#endif
#if defined(MODULE_GNRC_SIXLOWPAN_IPHC) && defined(MODULE_GNRC_SIXLOENC)
netif->flags |= GNRC_NETIF_FLAGS_6LO_HC;
#endif
break;
#endif
#ifdef MODULE_NORDIC_SOFTDEVICE_BLE
case NETDEV_TYPE_BLE:
netif->ipv6.mtu = IPV6_MIN_MTU;
#ifdef MODULE_GNRC_SIXLOWPAN_IPHC
netif->flags |= GNRC_NETIF_FLAGS_6LO_HC;
#endif
break;
#endif
default:
#ifdef DEVELHELP
LOG_DEBUG("gnrc_netif: getting MTU from device for interface %i\n",
netif->pid);
#endif
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;
}
break;
}
#endif
}

#if defined(MODULE_CC110X) || defined(MODULE_NRFMIN)
static void _create_iid_from_short(const uint8_t *addr, size_t addr_len,
eui64_t *iid)
Expand Down Expand Up @@ -148,6 +248,56 @@ int gnrc_netif_ipv6_iid_to_addr(const gnrc_netif_t *netif, const eui64_t *iid,
}
return -ENOTSUP;
}

int gnrc_netif_ndp_addr_len_from_l2ao(gnrc_netif_t *netif,
const ndp_opt_t *opt)
{
assert(netif->flags & GNRC_NETIF_FLAGS_HAS_L2ADDR);
switch (netif->device_type) {
#ifdef MODULE_CC110X
case NETDEV_TYPE_CC110X:
(void)opt;
return sizeof(uint8_t);
#endif /* MODULE_CC110X */
#if defined(MODULE_NETDEV_ETH) || defined(MODULE_ESP_NOW)
case NETDEV_TYPE_ETHERNET:
case NETDEV_TYPE_ESP_NOW:
/* see https://tools.ietf.org/html/rfc2464#section-6*/
if (opt->len == 1U) {
return ETHERNET_ADDR_LEN;
}
else {
return -EINVAL;
}
#endif /* defined(MODULE_NETDEV_ETH) || defined(MODULE_ESP_NOW) */
#ifdef MODULE_NRFMIN
case NETDEV_TYPE_NRFMIN:
(void)opt;
return sizeof(uint16_t);
#endif /* MODULE_NRFMIN */
#if defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_XBEE)
case NETDEV_TYPE_IEEE802154:
/* see https://tools.ietf.org/html/rfc4944#section-8 */
switch (opt->len) {
case 1U:
return IEEE802154_SHORT_ADDRESS_LEN;
case 2U:
return IEEE802154_LONG_ADDRESS_LEN;
default:
return -EINVAL;
}
#endif /* defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_XBEE) */
default:
(void)opt;
#ifdef DEVELHELP
LOG_ERROR("gnrc_netif: can't get address length from NDP link-layer "
"address option on interface %u\n", netif->pid);
#endif
assert(false);
break;
}
return -ENOTSUP;
}
#endif /* MODULE_GNRC_IPV6 */

/** @} */
Loading

0 comments on commit b24a8fb

Please sign in to comment.