diff --git a/cpu/native/netdev_tap/netdev_tap.c b/cpu/native/netdev_tap/netdev_tap.c
index fe18b9a8cd6df22deb94189fca107acc918726c8..884b6efc9217a409b44b517b54956dd51914eef7 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 b0c6d0da81cef77992a3b86498d07d5e940b1f27..e2518fea6b73f45415cacb6ca4a57f86ccdaef11 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 07119b6cbbc55510f1c7dd12be7d292754725bab..cb532e16b037d0436d26269aa6835bab7f70a093 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));