diff --git a/Makefile.dep b/Makefile.dep index 5b5664a27b..fac5838696 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -543,6 +543,10 @@ ifneq (,$(filter gnrc_pktbuf_%, $(USEMODULE))) USEMODULE += gnrc_pktbuf # make MODULE_GNRC_PKTBUF macro available for all implementations endif +ifneq (,$(filter gnrc_netif_%,$(USEMODULE))) + USEMODULE += gnrc_netif +endif + ifneq (,$(filter netstats_%, $(USEMODULE))) USEMODULE += netstats endif diff --git a/makefiles/pseudomodules.inc.mk b/makefiles/pseudomodules.inc.mk index 7f05cc9ff5..6132f5b16d 100644 --- a/makefiles/pseudomodules.inc.mk +++ b/makefiles/pseudomodules.inc.mk @@ -25,6 +25,7 @@ PSEUDOMODULES += gnrc_neterr PSEUDOMODULES += gnrc_netapi_callbacks PSEUDOMODULES += gnrc_netapi_mbox PSEUDOMODULES += gnrc_pktbuf_cmd +PSEUDOMODULES += gnrc_netif_dedup PSEUDOMODULES += gnrc_sixloenc PSEUDOMODULES += gnrc_sixlowpan_border_router_default PSEUDOMODULES += gnrc_sixlowpan_default diff --git a/sys/include/net/gnrc/netif.h b/sys/include/net/gnrc/netif.h index a69948d683..c4554deace 100644 --- a/sys/include/net/gnrc/netif.h +++ b/sys/include/net/gnrc/netif.h @@ -37,6 +37,9 @@ #ifdef MODULE_GNRC_SIXLOWPAN #include "net/gnrc/netif/6lo.h" #endif +#if defined(MODULE_GNRC_NETIF_DEDUP) && (GNRC_NETIF_L2ADDR_MAXLEN > 0) +#include "net/gnrc/netif/dedup.h" +#endif #include "net/gnrc/netif/flags.h" #ifdef MODULE_GNRC_IPV6 #include "net/gnrc/netif/ipv6.h" @@ -98,6 +101,14 @@ typedef struct { * @note Only available if @ref GNRC_NETIF_L2ADDR_MAXLEN > 0 */ uint8_t l2addr_len; +#if defined(MODULE_GNRC_NETIF_DEDUP) || DOXYGEN + /** + * @brief Last received packet information + * + * @note Only available with @ref net_gnrc_netif_dedup. + */ + gnrc_netif_dedup_t last_pkt; +#endif #endif #if defined(MODULE_GNRC_SIXLOWPAN) || DOXYGEN gnrc_netif_6lo_t sixlo; /**< 6Lo component */ diff --git a/sys/include/net/gnrc/netif/dedup.h b/sys/include/net/gnrc/netif/dedup.h new file mode 100644 index 0000000000..829ba22d6d --- /dev/null +++ b/sys/include/net/gnrc/netif/dedup.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2019 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. + */ + +/** + * @defgroup net_gnrc_netif_dedup Link-layer Broadcast deduplication + * @ingroup net_gnrc_netif + * @brief Deduplicates broadcast link-layer packets best-effort style + * + * To activate, use `USEMODULE += gnrc_netif_dedup` in your applications + * Makefile. Also make sure the link-layer you use supports the module. + * Currently supported are + * + * - IEEE 802.15.4 + * + * @{ + * + * @file + * @brief + * + * @author Martine Lenders + */ +#ifndef NET_GNRC_NETIF_DEDUP_H +#define NET_GNRC_NETIF_DEDUP_H + +#include + +#include "net/gnrc/netif/conf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Structure to store information on the last broadcast packet received + */ +typedef struct { + uint8_t src[GNRC_NETIF_L2ADDR_MAXLEN]; /**< link-layer source address */ + uint16_t seq; /**< link-layer sequence number */ + uint8_t src_len; /**< length of gnrc_netif_dedup_t:src */ +} gnrc_netif_dedup_t; + +#ifdef __cplusplus +} +#endif + +#endif /* NET_GNRC_NETIF_DEDUP_H */ +/** @} */ diff --git a/sys/net/gnrc/netif/ieee802154/gnrc_netif_ieee802154.c b/sys/net/gnrc/netif/ieee802154/gnrc_netif_ieee802154.c index fc2bbddeb5..44bccbe17d 100644 --- a/sys/net/gnrc/netif/ieee802154/gnrc_netif_ieee802154.c +++ b/sys/net/gnrc/netif/ieee802154/gnrc_netif_ieee802154.c @@ -73,6 +73,20 @@ static gnrc_pktsnip_t *_make_netif_hdr(uint8_t *mhr) return snip; } +#if MODULE_GNRC_NETIF_DEDUP +static inline bool _already_received(gnrc_netif_t *netif, + gnrc_netif_hdr_t *netif_hdr, + uint8_t *mhr) +{ + const uint8_t seq = ieee802154_get_seq(mhr); + + return (netif->last_pkt.seq == seq) && + (netif->last_pkt.src_len == netif_hdr->src_l2addr_len) && + (memcmp(netif->last_pkt.src, gnrc_netif_hdr_get_src_addr(netif_hdr), + netif_hdr->src_l2addr_len) == 0); +} +#endif /* MODULE_GNRC_NETIF_DEDUP */ + static gnrc_pktsnip_t *_recv(gnrc_netif_t *netif) { netdev_t *dev = netif->dev; @@ -155,6 +169,18 @@ static gnrc_pktsnip_t *_recv(gnrc_netif_t *netif) return NULL; } #endif +#ifdef MODULE_GNRC_NETIF_DEDUP + if (_already_received(netif, hdr, ieee802154_hdr->data)) { + gnrc_pktbuf_release(pkt); + gnrc_pktbuf_release(netif_hdr); + DEBUG("_recv_ieee802154: packet dropped by deduplication\n"); + return NULL; + } + memcpy(netif->last_pkt.src, gnrc_netif_hdr_get_src_addr(hdr), + hdr->src_l2addr_len); + netif->last_pkt.src_len = hdr->src_l2addr_len; + netif->last_pkt.seq = ieee802154_get_seq(ieee802154_hdr->data); +#endif /* MODULE_GNRC_NETIF_DEDUP */ hdr->lqi = rx_info.lqi; hdr->rssi = rx_info.rssi;