Skip to content
Snippets Groups Projects
Unverified Commit b24a8fbf authored by Cenk Gündoğan's avatar Cenk Gündoğan Committed by GitHub
Browse files

Merge pull request #10524 from miri64/gnrc_netif/enh/centralize-dev-type-functions

 gnrc_netif: centralize device-type-specific functions
parents 61452669 55b97570
No related branches found
No related tags found
No related merge requests found
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#endif #endif
#include "net/ndp.h" #include "net/ndp.h"
#include "net/netdev.h" #include "net/netdev.h"
#include "net/netopt.h"
#include "rmutex.h" #include "rmutex.h"
#ifdef __cplusplus #ifdef __cplusplus
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#define NET_GNRC_NETIF_INTERNAL_H #define NET_GNRC_NETIF_INTERNAL_H
#include "net/gnrc/netif.h" #include "net/gnrc/netif.h"
#include "net/netopt.h"
#ifdef MODULE_GNRC_IPV6_NIB #ifdef MODULE_GNRC_IPV6_NIB
#include "net/gnrc/ipv6/nib/conf.h" #include "net/gnrc/ipv6/nib/conf.h"
...@@ -403,7 +404,37 @@ static inline bool gnrc_netif_is_6lbr(const gnrc_netif_t *netif) ...@@ -403,7 +404,37 @@ static inline bool gnrc_netif_is_6lbr(const gnrc_netif_t *netif)
#define gnrc_netif_is_6lbr(netif) (false) #define gnrc_netif_is_6lbr(netif) (false)
#endif #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) #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. * @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) ...@@ -484,11 +515,44 @@ static inline int gnrc_netif_ipv6_get_iid(gnrc_netif_t *netif, eui64_t *iid)
(void)iid; (void)iid;
return -ENOTSUP; 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) */ #else /* defined(MODULE_GNRC_IPV6) || defined(DOXYGEN) */
#define gnrc_netif_ipv6_iid_from_addr(netif, addr, addr_len, iid) (-ENOTSUP) #define gnrc_netif_ipv6_init_mtu(netif) (void)netif
#define gnrc_netif_ipv6_iid_to_addr(netif, iid, addr) (-ENOTSUP) #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) #define gnrc_netif_ipv6_get_iid(netif, iid) (-ENOTSUP)
#endif /* defined(MODULE_GNRC_IPV6) || defined(DOXYGEN) */ #endif /* defined(MODULE_GNRC_IPV6) || defined(DOXYGEN) */
/** @} */
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -1109,27 +1109,8 @@ static void _update_l2addr_from_dev(gnrc_netif_t *netif) ...@@ -1109,27 +1109,8 @@ static void _update_l2addr_from_dev(gnrc_netif_t *netif)
{ {
netdev_t *dev = netif->dev; netdev_t *dev = netif->dev;
int res; 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, res = dev->driver->get(dev, opt, netif->l2addr,
sizeof(netif->l2addr)); sizeof(netif->l2addr));
if (res != -ENOTSUP) { if (res != -ENOTSUP) {
...@@ -1155,60 +1136,7 @@ static void _init_from_device(gnrc_netif_t *netif) ...@@ -1155,60 +1136,7 @@ static void _init_from_device(gnrc_netif_t *netif)
(void)res; (void)res;
assert(res == sizeof(tmp)); assert(res == sizeof(tmp));
netif->device_type = (uint8_t)tmp; netif->device_type = (uint8_t)tmp;
switch (netif->device_type) { gnrc_netif_ipv6_init_mtu(netif);
#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;
}
_update_l2addr_from_dev(netif); _update_l2addr_from_dev(netif);
} }
......
...@@ -17,11 +17,111 @@ ...@@ -17,11 +17,111 @@
#include <errno.h> #include <errno.h>
#include "log.h" #include "log.h"
#ifdef MODULE_GNRC_IPV6
#include "net/ipv6.h"
#endif
#include "net/gnrc/netif.h" #include "net/gnrc/netif.h"
#include "net/eui48.h" #include "net/eui48.h"
#include "net/ethernet.h"
#include "net/ieee802154.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 #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) #if defined(MODULE_CC110X) || defined(MODULE_NRFMIN)
static void _create_iid_from_short(const uint8_t *addr, size_t addr_len, static void _create_iid_from_short(const uint8_t *addr, size_t addr_len,
eui64_t *iid) eui64_t *iid)
...@@ -148,6 +248,56 @@ int gnrc_netif_ipv6_iid_to_addr(const gnrc_netif_t *netif, const 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; 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 */ #endif /* MODULE_GNRC_IPV6 */
/** @} */ /** @} */
...@@ -30,18 +30,6 @@ ...@@ -30,18 +30,6 @@
static char addr_str[IPV6_ADDR_MAX_STR_LEN]; 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, void _snd_ns(const ipv6_addr_t *tgt, gnrc_netif_t *netif,
const ipv6_addr_t *src, const ipv6_addr_t *dst) 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, ...@@ -104,10 +92,10 @@ void _handle_sl2ao(gnrc_netif_t *netif, const ipv6_hdr_t *ipv6,
{ {
assert(netif != NULL); assert(netif != NULL);
_nib_onl_entry_t *nce = _nib_onl_get(&ipv6->src, netif->pid); _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); l2addr_len = gnrc_netif_ndp_addr_len_from_l2ao(netif, sl2ao);
if (l2addr_len == 0U) { if (l2addr_len < 0) {
DEBUG("nib: Unexpected SL2AO length. Ignoring SL2AO\n"); DEBUG("nib: Unexpected SL2AO length. Ignoring SL2AO\n");
return; return;
} }
...@@ -174,43 +162,6 @@ void _handle_sl2ao(gnrc_netif_t *netif, const ipv6_hdr_t *ipv6, ...@@ -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 #if GNRC_IPV6_NIB_CONF_ARSM
/** /**
* @brief Calculates exponential back-off for retransmission timer for * @brief Calculates exponential back-off for retransmission timer for
...@@ -379,13 +330,13 @@ void _probe_nbr(_nib_onl_entry_t *nbr, bool reset) ...@@ -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, void _handle_adv_l2(gnrc_netif_t *netif, _nib_onl_entry_t *nce,
const icmpv6_hdr_t *icmpv6, const ndp_opt_t *tl2ao) const icmpv6_hdr_t *icmpv6, const ndp_opt_t *tl2ao)
{ {
unsigned l2addr_len = 0; int l2addr_len = 0;
assert(nce != NULL); assert(nce != NULL);
assert(netif != NULL); assert(netif != NULL);
if (tl2ao != NULL) { if (tl2ao != NULL) {
l2addr_len = _get_l2addr_len(netif, tl2ao); l2addr_len = gnrc_netif_ndp_addr_len_from_l2ao(netif, tl2ao);
if (l2addr_len == 0U) { if (l2addr_len < 0) {
DEBUG("nib: Unexpected TL2AO length. Ignoring TL2AO\n"); DEBUG("nib: Unexpected TL2AO length. Ignoring TL2AO\n");
return; return;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment