From 31dfe382a398f40d7afa322eb24d38ecc3d2351a Mon Sep 17 00:00:00 2001
From: Hauke Petersen <hauke.petersen@fu-berlin.de>
Date: Tue, 16 May 2017 16:29:28 +0200
Subject: [PATCH] net/gnrc/eth: enable filtering of L2 addresses

---
 cpu/native/netdev_tap/netdev_tap.c            |  3 ++-
 drivers/netdev_eth/netdev_eth.c               | 23 ++++++++++++++++++-
 .../gnrc/link_layer/netdev/gnrc_netdev_eth.c  |  7 ++++++
 3 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/cpu/native/netdev_tap/netdev_tap.c b/cpu/native/netdev_tap/netdev_tap.c
index fe18b9a8cd..884b6efc92 100644
--- a/cpu/native/netdev_tap/netdev_tap.c
+++ b/cpu/native/netdev_tap/netdev_tap.c
@@ -144,7 +144,8 @@ static int _set(netdev_t *dev, netopt_t opt, void *value, size_t value_len)
             _set_promiscous(dev, ((bool *)value)[0]);
             break;
         default:
-            return -ENOTSUP;
+            res = netdev_eth_set(dev, opt, value, value_len);
+            break;
     }
 
     return res;
diff --git a/drivers/netdev_eth/netdev_eth.c b/drivers/netdev_eth/netdev_eth.c
index b0c6d0da81..e2518fea6b 100644
--- a/drivers/netdev_eth/netdev_eth.c
+++ b/drivers/netdev_eth/netdev_eth.c
@@ -87,6 +87,15 @@ int netdev_eth_get(netdev_t *dev, netopt_t opt, void *value, size_t max_len)
                 res = sizeof(uintptr_t);
                 break;
             }
+#endif
+#ifdef MODULE_L2FILTER
+        case NETOPT_L2FILTER:
+            {
+                assert(max_len >= sizeof(l2filter_t **));
+                *((l2filter_t **)value) = dev->filter;
+                res = sizeof(l2filter_t **);
+                break;
+            }
 #endif
         default:
             {
@@ -100,15 +109,27 @@ int netdev_eth_get(netdev_t *dev, netopt_t opt, void *value, size_t max_len)
 
 int netdev_eth_set(netdev_t *dev, netopt_t opt, void *value, size_t value_len)
 {
+#ifndef MODULE_L2FILTER
     (void)dev;
+#endif
     (void)value;
     (void)value_len;
 
     int res = 0;
 
     switch (opt) {
+
+#ifdef MODULE_L2FILTER
+        case NETOPT_L2FILTER:
+            res = l2filter_add(dev->filter, value, value_len);
+            break;
+        case NETOPT_L2FILTER_RM:
+            res = l2filter_rm(dev->filter, value, value_len);
+            break;
+#endif
         default:
-            return -ENOTSUP;
+            res = -ENOTSUP;
+            break;
     }
 
     return res;
diff --git a/sys/net/gnrc/link_layer/netdev/gnrc_netdev_eth.c b/sys/net/gnrc/link_layer/netdev/gnrc_netdev_eth.c
index 07119b6cbb..cb532e16b0 100644
--- a/sys/net/gnrc/link_layer/netdev/gnrc_netdev_eth.c
+++ b/sys/net/gnrc/link_layer/netdev/gnrc_netdev_eth.c
@@ -72,6 +72,13 @@ static gnrc_pktsnip_t *_recv(gnrc_netdev_t *gnrc_netdev)
 
         ethernet_hdr_t *hdr = (ethernet_hdr_t *)eth_hdr->data;
 
+#ifdef MODULE_L2FILTER
+        if (!l2filter_pass(dev->filter, hdr->src, ETHERNET_ADDR_LEN)) {
+            DEBUG("gnrc_netdev_eth: incoming packet filtered by l2filter\n");
+            goto safe_out;
+        }
+#endif
+
         /* set payload type from ethertype */
         pkt->type = gnrc_nettype_from_ethertype(byteorder_ntohs(hdr->type));
 
-- 
GitLab