Merge pull request #10524 from miri64/gnrc_netif/enh/centralize-dev-type-functions
gnrc_netif: centralize device-type-specific functions
This commit is contained in:
commit
b24a8fbf3a
@ -46,6 +46,7 @@
|
||||
#endif
|
||||
#include "net/ndp.h"
|
||||
#include "net/netdev.h"
|
||||
#include "net/netopt.h"
|
||||
#include "rmutex.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -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"
|
||||
@ -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.
|
||||
*
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
@ -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 */
|
||||
|
||||
/** @} */
|
||||
|
||||
@ -30,18 +30,6 @@
|
||||
|
||||
static char addr_str[IPV6_ADDR_MAX_STR_LEN];
|
||||
|
||||
/**
|
||||
* @brief Determines supposed link-layer address from interface and option
|
||||
* length
|
||||
*
|
||||
* @param[in] netif A network interface.
|
||||
* @param[in] opt A SL2AO or TL2AO.
|
||||
*
|
||||
* @return The length of the L2 address carried in @p opt.
|
||||
*/
|
||||
static inline unsigned _get_l2addr_len(gnrc_netif_t *netif,
|
||||
const ndp_opt_t *opt);
|
||||
|
||||
void _snd_ns(const ipv6_addr_t *tgt, gnrc_netif_t *netif,
|
||||
const ipv6_addr_t *src, const ipv6_addr_t *dst)
|
||||
{
|
||||
@ -104,10 +92,10 @@ void _handle_sl2ao(gnrc_netif_t *netif, const ipv6_hdr_t *ipv6,
|
||||
{
|
||||
assert(netif != NULL);
|
||||
_nib_onl_entry_t *nce = _nib_onl_get(&ipv6->src, netif->pid);
|
||||
unsigned l2addr_len;
|
||||
int l2addr_len;
|
||||
|
||||
l2addr_len = _get_l2addr_len(netif, sl2ao);
|
||||
if (l2addr_len == 0U) {
|
||||
l2addr_len = gnrc_netif_ndp_addr_len_from_l2ao(netif, sl2ao);
|
||||
if (l2addr_len < 0) {
|
||||
DEBUG("nib: Unexpected SL2AO length. Ignoring SL2AO\n");
|
||||
return;
|
||||
}
|
||||
@ -174,43 +162,6 @@ void _handle_sl2ao(gnrc_netif_t *netif, const ipv6_hdr_t *ipv6,
|
||||
}
|
||||
}
|
||||
|
||||
static inline unsigned _get_l2addr_len(gnrc_netif_t *netif,
|
||||
const ndp_opt_t *opt)
|
||||
{
|
||||
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:
|
||||
(void)opt;
|
||||
return ETHERNET_ADDR_LEN;
|
||||
#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:
|
||||
switch (opt->len) {
|
||||
case 1U:
|
||||
return IEEE802154_SHORT_ADDRESS_LEN;
|
||||
case 2U:
|
||||
return IEEE802154_LONG_ADDRESS_LEN;
|
||||
default:
|
||||
return 0U;
|
||||
}
|
||||
#endif /* defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_XBEE) */
|
||||
default:
|
||||
(void)opt;
|
||||
return 0U;
|
||||
}
|
||||
}
|
||||
|
||||
#if GNRC_IPV6_NIB_CONF_ARSM
|
||||
/**
|
||||
* @brief Calculates exponential back-off for retransmission timer for
|
||||
@ -379,13 +330,13 @@ void _probe_nbr(_nib_onl_entry_t *nbr, bool reset)
|
||||
void _handle_adv_l2(gnrc_netif_t *netif, _nib_onl_entry_t *nce,
|
||||
const icmpv6_hdr_t *icmpv6, const ndp_opt_t *tl2ao)
|
||||
{
|
||||
unsigned l2addr_len = 0;
|
||||
int l2addr_len = 0;
|
||||
|
||||
assert(nce != NULL);
|
||||
assert(netif != NULL);
|
||||
if (tl2ao != NULL) {
|
||||
l2addr_len = _get_l2addr_len(netif, tl2ao);
|
||||
if (l2addr_len == 0U) {
|
||||
l2addr_len = gnrc_netif_ndp_addr_len_from_l2ao(netif, tl2ao);
|
||||
if (l2addr_len < 0) {
|
||||
DEBUG("nib: Unexpected TL2AO length. Ignoring TL2AO\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user