Blame SOURCES/0001-Introduce-bpf_filter1-function.patch

2cd29a
From d4306feb76ee9a6d9ecee63b152404bd0db0f97c Mon Sep 17 00:00:00 2001
2cd29a
From: Michal Sekletar <msekleta@redhat.com>
2cd29a
Date: Tue, 5 Aug 2014 16:46:19 +0200
2cd29a
Subject: [PATCH] Introduce bpf_filter1 function
2cd29a
2cd29a
Function takes additional argument which is a pointer to bpf_aux_data
2cd29a
structure. This newly introduced struct holds auxiliary data provided by caller
2cd29a
to specify additional data needed to implement some BPF extensions while
2cd29a
executing filter in userspace.
2cd29a
2cd29a
bpf_filter1 currently implements support for two BPF extesions, namely
2cd29a
vlan_tci and vlan_pr.
2cd29a
2cd29a
(cherry picked from 02e420f820750e970c93068c01ea10d4c16f2b9a)
2cd29a
2cd29a
Conflicts:
2cd29a
        bpf/net/bpf_filter.c
2cd29a
---
2cd29a
 bpf/net/bpf_filter.c | 77 +++++++++++++++++++++++++++++++++++++++++++---------
2cd29a
 pcap/bpf.h           | 10 +++++++
2cd29a
 2 files changed, 74 insertions(+), 13 deletions(-)
2cd29a
2cd29a
diff --git a/bpf/net/bpf_filter.c b/bpf/net/bpf_filter.c
2cd29a
index 0c4fb00..3409a9b 100644
2cd29a
--- a/bpf/net/bpf_filter.c
2cd29a
+++ b/bpf/net/bpf_filter.c
2cd29a
@@ -200,6 +200,17 @@ m_xhalf(m, k, err)
2cd29a
 }
2cd29a
 #endif
2cd29a
 
2cd29a
+#ifdef __linux__
2cd29a
+#include <linux/if_packet.h>
2cd29a
+#include <linux/filter.h>
2cd29a
+#endif
2cd29a
+
2cd29a
+enum {
2cd29a
+        BPF_S_ANC_NONE,
2cd29a
+        BPF_S_ANC_VLAN_TAG,
2cd29a
+        BPF_S_ANC_VLAN_TAG_PRESENT,
2cd29a
+};
2cd29a
+
2cd29a
 /*
2cd29a
  * Execute the filter program starting at pc on the packet p
2cd29a
  * wirelen is the length of the original packet
2cd29a
@@ -208,11 +219,12 @@ m_xhalf(m, k, err)
2cd29a
  * in all other cases, p is a pointer to a buffer and buflen is its size.
2cd29a
  */
2cd29a
 u_int
2cd29a
-bpf_filter(pc, p, wirelen, buflen)
2cd29a
+bpf_filter1(pc, p, wirelen, buflen, aux_data)
2cd29a
 	register const struct bpf_insn *pc;
2cd29a
 	register const u_char *p;
2cd29a
 	u_int wirelen;
2cd29a
 	register u_int buflen;
2cd29a
+        register const struct bpf_aux_data *aux_data;
2cd29a
 {
2cd29a
 	register u_int32 A, X;
2cd29a
 	register int k;
2cd29a
@@ -288,22 +300,50 @@ bpf_filter(pc, p, wirelen, buflen)
2cd29a
 			continue;
2cd29a
 
2cd29a
 		case BPF_LD|BPF_B|BPF_ABS:
2cd29a
-			k = pc->k;
2cd29a
-			if (k >= buflen) {
2cd29a
+			{
2cd29a
+#if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT)
2cd29a
+				int code = BPF_S_ANC_NONE;
2cd29a
+#define ANCILLARY(CODE) case SKF_AD_OFF + SKF_AD_##CODE:		\
2cd29a
+				code = BPF_S_ANC_##CODE;		\
2cd29a
+                                        if (!aux_data)                  \
2cd29a
+                                                return 0;               \
2cd29a
+                                        break;
2cd29a
+
2cd29a
+				switch (pc->k) {
2cd29a
+					ANCILLARY(VLAN_TAG);
2cd29a
+					ANCILLARY(VLAN_TAG_PRESENT);
2cd29a
+				default :
2cd29a
+#endif
2cd29a
+					k = pc->k;
2cd29a
+					if (k >= buflen) {
2cd29a
 #if defined(KERNEL) || defined(_KERNEL)
2cd29a
-				if (m == NULL)
2cd29a
-					return 0;
2cd29a
-				n = m;
2cd29a
-				MINDEX(len, n, k);
2cd29a
-				A = mtod(n, u_char *)[k];
2cd29a
-				continue;
2cd29a
+						if (m == NULL)
2cd29a
+							return 0;
2cd29a
+						n = m;
2cd29a
+						MINDEX(len, n, k);
2cd29a
+						A = mtod(n, u_char *)[k];
2cd29a
+						continue;
2cd29a
 #else
2cd29a
-				return 0;
2cd29a
+						return 0;
2cd29a
+#endif
2cd29a
+					}
2cd29a
+					A = p[k];
2cd29a
+#if defined(SKF_AD_VLAN_TAG) && defined(SKF_AD_VLAN_TAG_PRESENT)
2cd29a
+				}
2cd29a
+				switch (code) {
2cd29a
+				case BPF_S_ANC_VLAN_TAG:
2cd29a
+					if (aux_data)
2cd29a
+						A = aux_data->vlan_tag;
2cd29a
+					break;
2cd29a
+
2cd29a
+				case BPF_S_ANC_VLAN_TAG_PRESENT:
2cd29a
+					if (aux_data)
2cd29a
+						A = aux_data->vlan_tag_present;
2cd29a
+					break;
2cd29a
+				}
2cd29a
 #endif
2cd29a
+				continue;
2cd29a
 			}
2cd29a
-			A = p[k];
2cd29a
-			continue;
2cd29a
-
2cd29a
 		case BPF_LD|BPF_W|BPF_LEN:
2cd29a
 			A = wirelen;
2cd29a
 			continue;
2cd29a
@@ -532,6 +572,17 @@ bpf_filter(pc, p, wirelen, buflen)
2cd29a
 	}
2cd29a
 }
2cd29a
 
2cd29a
+u_int
2cd29a
+bpf_filter(pc, p, wirelen, buflen)
2cd29a
+	register const struct bpf_insn *pc;
2cd29a
+	register const u_char *p;
2cd29a
+	u_int wirelen;
2cd29a
+	register u_int buflen;
2cd29a
+{
2cd29a
+	return bpf_filter1(pc, p, wirelen, buflen, NULL);
2cd29a
+}
2cd29a
+
2cd29a
+
2cd29a
 /*
2cd29a
  * Return true if the 'fcode' is a valid filter program.
2cd29a
  * The constraints are that each jump be forward and to a valid
2cd29a
diff --git a/pcap/bpf.h b/pcap/bpf.h
2cd29a
index 8286ed5..495f326 100644
2cd29a
--- a/pcap/bpf.h
2cd29a
+++ b/pcap/bpf.h
2cd29a
@@ -70,6 +70,9 @@
2cd29a
  *
2cd29a
  * This also provides our own multiple-include protection.
2cd29a
  */
2cd29a
+
2cd29a
+#include <stdint.h>
2cd29a
+
2cd29a
 #if !defined(_NET_BPF_H_) && !defined(_BPF_H_) && !defined(_H_BPF) && !defined(lib_pcap_bpf_h)
2cd29a
 #define lib_pcap_bpf_h
2cd29a
 
2cd29a
@@ -1317,6 +1320,11 @@ struct bpf_insn {
2cd29a
 	bpf_u_int32 k;
2cd29a
 };
2cd29a
 
2cd29a
+struct bpf_aux_data {
2cd29a
+        uint16_t vlan_tag_present;
2cd29a
+        uint16_t vlan_tag;
2cd29a
+};
2cd29a
+
2cd29a
 /*
2cd29a
  * Macros for insn array initializers.
2cd29a
  */
2cd29a
@@ -1326,9 +1334,11 @@ struct bpf_insn {
2cd29a
 #if __STDC__ || defined(__cplusplus)
2cd29a
 extern int bpf_validate(const struct bpf_insn *, int);
2cd29a
 extern u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int);
2cd29a
+extern u_int bpf_filter1(const struct bpf_insn *, const u_char *, u_int, u_int, const struct bpf_aux_data *);        
2cd29a
 #else
2cd29a
 extern int bpf_validate();
2cd29a
 extern u_int bpf_filter();
2cd29a
+extern u_int bpf_filter();
2cd29a
 #endif
2cd29a
 
2cd29a
 /*
2cd29a
-- 
2cd29a
2.4.3
2cd29a