net: filter: add vlan tag access
authorEric Dumazet <edumazet@google.com>
Sat, 27 Oct 2012 02:26:17 +0000 (02:26 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 31 Oct 2012 18:00:15 +0000 (14:00 -0400)
BPF filters lack ability to access skb->vlan_tci

This patch adds two new ancillary accessors :

SKF_AD_VLAN_TAG         (44) mapped to vlan_tx_tag_get(skb)

SKF_AD_VLAN_TAG_PRESENT (48) mapped to vlan_tx_tag_present(skb)

This allows libpcap/tcpdump to use a kernel filter instead of
having to fallback to accept all packets, then filter them in
user space.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Suggested-by: Ani Sinha <ani@aristanetworks.com>
Suggested-by: Daniel Borkmann <danborkmann@iogearbox.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/filter.h
include/uapi/linux/filter.h
net/core/filter.c

index 24d251f3bab0711c26231d67352df1ca140e608a..c9f0005c35e22d6b0e1df0a2b8f5f327ee1daa78 100644 (file)
@@ -123,6 +123,8 @@ enum {
        BPF_S_ANC_CPU,
        BPF_S_ANC_ALU_XOR_X,
        BPF_S_ANC_SECCOMP_LD_W,
+       BPF_S_ANC_VLAN_TAG,
+       BPF_S_ANC_VLAN_TAG_PRESENT,
 };
 
 #endif /* __LINUX_FILTER_H__ */
index 3d7922433abad7b6e3cf7985897e9536eda49037..9cfde6941099635ee567d28e240f8cbc02386f51 100644 (file)
@@ -127,7 +127,9 @@ struct sock_fprog { /* Required for SO_ATTACH_FILTER. */
 #define SKF_AD_RXHASH  32
 #define SKF_AD_CPU     36
 #define SKF_AD_ALU_XOR_X       40
-#define SKF_AD_MAX     44
+#define SKF_AD_VLAN_TAG        44
+#define SKF_AD_VLAN_TAG_PRESENT 48
+#define SKF_AD_MAX     52
 #define SKF_NET_OFF   (-0x100000)
 #define SKF_LL_OFF    (-0x200000)
 
index 3d92ebb7fbcf71471d4b3d90e5309f459c47bea0..5a114d41bf1130fa9424f5b9c2125f4ae5e515b0 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/reciprocal_div.h>
 #include <linux/ratelimit.h>
 #include <linux/seccomp.h>
+#include <linux/if_vlan.h>
 
 /* No hurry in this branch
  *
@@ -341,6 +342,12 @@ load_b:
                case BPF_S_ANC_CPU:
                        A = raw_smp_processor_id();
                        continue;
+               case BPF_S_ANC_VLAN_TAG:
+                       A = vlan_tx_tag_get(skb);
+                       continue;
+               case BPF_S_ANC_VLAN_TAG_PRESENT:
+                       A = !!vlan_tx_tag_present(skb);
+                       continue;
                case BPF_S_ANC_NLATTR: {
                        struct nlattr *nla;
 
@@ -600,6 +607,8 @@ int sk_chk_filter(struct sock_filter *filter, unsigned int flen)
                        ANCILLARY(RXHASH);
                        ANCILLARY(CPU);
                        ANCILLARY(ALU_XOR_X);
+                       ANCILLARY(VLAN_TAG);
+                       ANCILLARY(VLAN_TAG_PRESENT);
                        }
                }
                ftest->code = code;