|
|
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 |
|