From 985d98073fa21d9ada591031d6e7ee36310c29e8 Mon Sep 17 00:00:00 2001
From: Martine Lenders <m.lenders@fu-berlin.de>
Date: Wed, 6 Sep 2017 17:18:22 +0200
Subject: [PATCH] gnrc_netif_ieee802154: drop duplicate broadcast packets
 (optionally)

---
 Makefile.dep                                  |  4 ++
 makefiles/pseudomodules.inc.mk                |  1 +
 sys/include/net/gnrc/netif.h                  | 11 ++++
 sys/include/net/gnrc/netif/dedup.h            | 52 +++++++++++++++++++
 .../netif/ieee802154/gnrc_netif_ieee802154.c  | 26 ++++++++++
 5 files changed, 94 insertions(+)
 create mode 100644 sys/include/net/gnrc/netif/dedup.h

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 <m.lenders@fu-berlin.de>
+ */
+#ifndef NET_GNRC_NETIF_DEDUP_H
+#define NET_GNRC_NETIF_DEDUP_H
+
+#include <stdint.h>
+
+#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;
-- 
GitLab