netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 0/8] Add complementary BPF conditional jump instructions
@ 2012-12-31 13:59 Daniel Borkmann
  2012-12-31 13:59 ` [PATCH net-next 1/8] net: bpf: add lt,le jump operations to bpf machine Daniel Borkmann
                   ` (8 more replies)
  0 siblings, 9 replies; 14+ messages in thread
From: Daniel Borkmann @ 2012-12-31 13:59 UTC (permalink / raw)
  To: davem; +Cc: netdev

This set adds adds jump operations for lt (<), le (<=), ne (!=) that
compare A with K resp. X in order to facilitate filter programming
with conditional jumps, as also available in McCanne et. al's BPF+
paper (``BPF+: Exploiting Global Data-flow Optimization in a Generalized
Packet Filter Architecture'').

Also, follow-up BPF JIT implementations for x86, Sparc and PowerPC
are added in this set.

Daniel Borkmann (8):
  net: bpf: add lt,le jump operations to bpf machine
  x86: bpf_jit_comp: add JMP instructions for BPF JIT
  sparc: bpf_jit_comp: add JMP instructions for BPF JIT
  PPC: bpf_jit_comp: add JMP instructions for BPF JIT
  net: bpf: add neq jump operations to bpf machine
  x86: bpf_jit_comp: add JMP_NEQ instructions for BPF JIT
  sparc: bpf_jit_comp: add JMP_NEQ instructions for BPF JIT
  PPC: bpf_jit_comp: add JMP_NEQ instructions for BPF JIT

 arch/powerpc/net/bpf_jit.h      |  1 +
 arch/powerpc/net/bpf_jit_comp.c | 16 ++++++++++++++++
 arch/sparc/net/bpf_jit_comp.c   | 12 ++++++++++++
 arch/x86/net/bpf_jit_comp.c     | 12 ++++++++++++
 include/linux/filter.h          |  6 ++++++
 include/uapi/linux/filter.h     |  4 ++++
 net/core/filter.c               | 42 +++++++++++++++++++++++++++++++++++++++++
 7 files changed, 93 insertions(+)

-- 
1.7.11.7

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH net-next 1/8] net: bpf: add lt,le jump operations to bpf machine
  2012-12-31 13:59 [PATCH net-next 0/8] Add complementary BPF conditional jump instructions Daniel Borkmann
@ 2012-12-31 13:59 ` Daniel Borkmann
  2012-12-31 13:59 ` [PATCH net-next 2/8] x86: bpf_jit_comp: add JMP instructions for BPF JIT Daniel Borkmann
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Daniel Borkmann @ 2012-12-31 13:59 UTC (permalink / raw)
  To: davem; +Cc: netdev

This patch adds jump operations for lt (<) and le (<=) that
compare A with K resp. X in order to facilitate filter
programming with conditional jumps, since currently only
gt (>) and ge (>=) are present in the BPF machine. For
user-space filter programming / compilers, it might be good
to also have those complementary operations. They don't need
to be as ancillary, since they fit into the instruction
encoding directly. Follow-up BPF JIT patches are welcomed.

Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
 include/linux/filter.h      |  4 ++++
 include/uapi/linux/filter.h |  3 +++
 net/core/filter.c           | 28 ++++++++++++++++++++++++++++
 3 files changed, 35 insertions(+)

diff --git a/include/linux/filter.h b/include/linux/filter.h
index c45eabc..36630bc 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -109,6 +109,10 @@ enum {
 	BPF_S_JMP_JGE_X,
 	BPF_S_JMP_JGT_K,
 	BPF_S_JMP_JGT_X,
+	BPF_S_JMP_JLE_K,
+	BPF_S_JMP_JLE_X,
+	BPF_S_JMP_JLT_K,
+	BPF_S_JMP_JLT_X,
 	BPF_S_JMP_JSET_K,
 	BPF_S_JMP_JSET_X,
 	/* Ancillary data */
diff --git a/include/uapi/linux/filter.h b/include/uapi/linux/filter.h
index 9cfde69..3ebcc2e 100644
--- a/include/uapi/linux/filter.h
+++ b/include/uapi/linux/filter.h
@@ -78,6 +78,9 @@ struct sock_fprog {	/* Required for SO_ATTACH_FILTER. */
 #define         BPF_JGT         0x20
 #define         BPF_JGE         0x30
 #define         BPF_JSET        0x40
+#define         BPF_JLT         0x50
+#define         BPF_JLE         0x60
+
 #define BPF_SRC(code)   ((code) & 0x08)
 #define         BPF_K           0x00
 #define         BPF_X           0x08
diff --git a/net/core/filter.c b/net/core/filter.c
index 2ead2a9..2122eba 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -219,6 +219,12 @@ unsigned int sk_run_filter(const struct sk_buff *skb,
 		case BPF_S_JMP_JGE_K:
 			fentry += (A >= K) ? fentry->jt : fentry->jf;
 			continue;
+		case BPF_S_JMP_JLT_K:
+			fentry += (A < K) ? fentry->jt : fentry->jf;
+			continue;
+		case BPF_S_JMP_JLE_K:
+			fentry += (A <= K) ? fentry->jt : fentry->jf;
+			continue;
 		case BPF_S_JMP_JEQ_K:
 			fentry += (A == K) ? fentry->jt : fentry->jf;
 			continue;
@@ -231,6 +237,12 @@ unsigned int sk_run_filter(const struct sk_buff *skb,
 		case BPF_S_JMP_JGE_X:
 			fentry += (A >= X) ? fentry->jt : fentry->jf;
 			continue;
+		case BPF_S_JMP_JLT_X:
+			fentry += (A < X) ? fentry->jt : fentry->jf;
+			continue;
+		case BPF_S_JMP_JLE_X:
+			fentry += (A <= X) ? fentry->jt : fentry->jf;
+			continue;
 		case BPF_S_JMP_JEQ_X:
 			fentry += (A == X) ? fentry->jt : fentry->jf;
 			continue;
@@ -446,6 +458,10 @@ static int check_load_and_stores(struct sock_filter *filter, int flen)
 		case BPF_S_JMP_JGE_X:
 		case BPF_S_JMP_JGT_K:
 		case BPF_S_JMP_JGT_X:
+		case BPF_S_JMP_JLE_K:
+		case BPF_S_JMP_JLE_X:
+		case BPF_S_JMP_JLT_K:
+		case BPF_S_JMP_JLT_X:
 		case BPF_S_JMP_JSET_X:
 		case BPF_S_JMP_JSET_K:
 			/* a jump must set masks on targets */
@@ -528,6 +544,10 @@ int sk_chk_filter(struct sock_filter *filter, unsigned int flen)
 		[BPF_JMP|BPF_JGE|BPF_X]  = BPF_S_JMP_JGE_X,
 		[BPF_JMP|BPF_JGT|BPF_K]  = BPF_S_JMP_JGT_K,
 		[BPF_JMP|BPF_JGT|BPF_X]  = BPF_S_JMP_JGT_X,
+		[BPF_JMP|BPF_JLE|BPF_K]  = BPF_S_JMP_JLE_K,
+		[BPF_JMP|BPF_JLE|BPF_X]  = BPF_S_JMP_JLE_X,
+		[BPF_JMP|BPF_JLT|BPF_K]  = BPF_S_JMP_JLT_K,
+		[BPF_JMP|BPF_JLT|BPF_X]  = BPF_S_JMP_JLT_X,
 		[BPF_JMP|BPF_JSET|BPF_K] = BPF_S_JMP_JSET_K,
 		[BPF_JMP|BPF_JSET|BPF_X] = BPF_S_JMP_JSET_X,
 	};
@@ -583,6 +603,10 @@ int sk_chk_filter(struct sock_filter *filter, unsigned int flen)
 		case BPF_S_JMP_JGE_X:
 		case BPF_S_JMP_JGT_K:
 		case BPF_S_JMP_JGT_X:
+		case BPF_S_JMP_JLE_K:
+		case BPF_S_JMP_JLE_X:
+		case BPF_S_JMP_JLT_K:
+		case BPF_S_JMP_JLT_X:
 		case BPF_S_JMP_JSET_X:
 		case BPF_S_JMP_JSET_K:
 			/* for conditionals both must be safe */
@@ -832,6 +856,10 @@ static void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to)
 		[BPF_S_JMP_JGE_X]	= BPF_JMP|BPF_JGE|BPF_X,
 		[BPF_S_JMP_JGT_K]	= BPF_JMP|BPF_JGT|BPF_K,
 		[BPF_S_JMP_JGT_X]	= BPF_JMP|BPF_JGT|BPF_X,
+		[BPF_S_JMP_JLE_K]	= BPF_JMP|BPF_JLE|BPF_K,
+		[BPF_S_JMP_JLE_X]	= BPF_JMP|BPF_JLE|BPF_X,
+		[BPF_S_JMP_JLT_K]	= BPF_JMP|BPF_JLT|BPF_K,
+		[BPF_S_JMP_JLT_X]	= BPF_JMP|BPF_JLT|BPF_X,
 		[BPF_S_JMP_JSET_K]	= BPF_JMP|BPF_JSET|BPF_K,
 		[BPF_S_JMP_JSET_X]	= BPF_JMP|BPF_JSET|BPF_X,
 	};
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 2/8] x86: bpf_jit_comp: add JMP instructions for BPF JIT
  2012-12-31 13:59 [PATCH net-next 0/8] Add complementary BPF conditional jump instructions Daniel Borkmann
  2012-12-31 13:59 ` [PATCH net-next 1/8] net: bpf: add lt,le jump operations to bpf machine Daniel Borkmann
@ 2012-12-31 13:59 ` Daniel Borkmann
  2012-12-31 13:59 ` [PATCH net-next 3/8] sparc: " Daniel Borkmann
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Daniel Borkmann @ 2012-12-31 13:59 UTC (permalink / raw)
  To: davem; +Cc: netdev, Eric Dumazet

This patch is a follow-up for patch "net: bpf: add lt,le jump
operations to bpf machine" that implements BPF x86 JIT parts
for BPF JMP_LT/JMP_LE operations.

Cc: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
 arch/x86/net/bpf_jit_comp.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index d11a470..6d6a4ce 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -584,10 +584,14 @@ common_load_ind:		seen |= SEEN_DATAREF | SEEN_XREG;
 				break;
 			COND_SEL(BPF_S_JMP_JGT_K, X86_JA, X86_JBE);
 			COND_SEL(BPF_S_JMP_JGE_K, X86_JAE, X86_JB);
+			COND_SEL(BPF_S_JMP_JLT_K, X86_JB, X86_JAE);
+			COND_SEL(BPF_S_JMP_JLE_K, X86_JBE, X86_JA);
 			COND_SEL(BPF_S_JMP_JEQ_K, X86_JE, X86_JNE);
 			COND_SEL(BPF_S_JMP_JSET_K,X86_JNE, X86_JE);
 			COND_SEL(BPF_S_JMP_JGT_X, X86_JA, X86_JBE);
 			COND_SEL(BPF_S_JMP_JGE_X, X86_JAE, X86_JB);
+			COND_SEL(BPF_S_JMP_JLT_X, X86_JB, X86_JAE);
+			COND_SEL(BPF_S_JMP_JLE_X, X86_JBE, X86_JA);
 			COND_SEL(BPF_S_JMP_JEQ_X, X86_JE, X86_JNE);
 			COND_SEL(BPF_S_JMP_JSET_X,X86_JNE, X86_JE);
 
@@ -603,6 +607,8 @@ cond_branch:			f_offset = addrs[i + filter[i].jf] - addrs[i];
 				switch (filter[i].code) {
 				case BPF_S_JMP_JGT_X:
 				case BPF_S_JMP_JGE_X:
+				case BPF_S_JMP_JLT_X:
+				case BPF_S_JMP_JLE_X:
 				case BPF_S_JMP_JEQ_X:
 					seen |= SEEN_XREG;
 					EMIT2(0x39, 0xd8); /* cmp %ebx,%eax */
@@ -618,6 +624,8 @@ cond_branch:			f_offset = addrs[i + filter[i].jf] - addrs[i];
 					}
 				case BPF_S_JMP_JGT_K:
 				case BPF_S_JMP_JGE_K:
+				case BPF_S_JMP_JLT_K:
+				case BPF_S_JMP_JLE_K:
 					if (K <= 127)
 						EMIT3(0x83, 0xf8, K); /* cmp imm8,%eax */
 					else
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 3/8] sparc: bpf_jit_comp: add JMP instructions for BPF JIT
  2012-12-31 13:59 [PATCH net-next 0/8] Add complementary BPF conditional jump instructions Daniel Borkmann
  2012-12-31 13:59 ` [PATCH net-next 1/8] net: bpf: add lt,le jump operations to bpf machine Daniel Borkmann
  2012-12-31 13:59 ` [PATCH net-next 2/8] x86: bpf_jit_comp: add JMP instructions for BPF JIT Daniel Borkmann
@ 2012-12-31 13:59 ` Daniel Borkmann
  2012-12-31 13:59 ` [PATCH net-next 4/8] PPC: " Daniel Borkmann
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Daniel Borkmann @ 2012-12-31 13:59 UTC (permalink / raw)
  To: davem; +Cc: netdev

This patch is a follow-up for patch "net: bpf: add lt,le jump
operations to bpf machine" that implements BPF SPARC JIT parts
for BPF JMP_LT/JMP_LE operations.

Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
 arch/sparc/net/bpf_jit_comp.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/sparc/net/bpf_jit_comp.c b/arch/sparc/net/bpf_jit_comp.c
index 3109ca6..f5b4fc9 100644
--- a/arch/sparc/net/bpf_jit_comp.c
+++ b/arch/sparc/net/bpf_jit_comp.c
@@ -691,10 +691,14 @@ common_load_ind:		seen |= SEEN_DATAREF | SEEN_XREG;
 
 			COND_SEL(BPF_S_JMP_JGT_K, BGU, BLEU);
 			COND_SEL(BPF_S_JMP_JGE_K, BGEU, BLU);
+			COND_SEL(BPF_S_JMP_JLT_K, BLU, BGEU);
+			COND_SEL(BPF_S_JMP_JLE_K, BLEU, BGU);
 			COND_SEL(BPF_S_JMP_JEQ_K, BE, BNE);
 			COND_SEL(BPF_S_JMP_JSET_K, BNE, BE);
 			COND_SEL(BPF_S_JMP_JGT_X, BGU, BLEU);
 			COND_SEL(BPF_S_JMP_JGE_X, BGEU, BLU);
+			COND_SEL(BPF_S_JMP_JLT_X, BLU, BGEU);
+			COND_SEL(BPF_S_JMP_JLE_X, BLEU, BGU);
 			COND_SEL(BPF_S_JMP_JEQ_X, BE, BNE);
 			COND_SEL(BPF_S_JMP_JSET_X, BNE, BE);
 
@@ -711,6 +715,8 @@ cond_branch:			f_offset = addrs[i + filter[i].jf];
 				switch (filter[i].code) {
 				case BPF_S_JMP_JGT_X:
 				case BPF_S_JMP_JGE_X:
+				case BPF_S_JMP_JLT_X:
+				case BPF_S_JMP_JLE_X:
 				case BPF_S_JMP_JEQ_X:
 					seen |= SEEN_XREG;
 					emit_cmp(r_A, r_X);
@@ -722,6 +728,8 @@ cond_branch:			f_offset = addrs[i + filter[i].jf];
 				case BPF_S_JMP_JEQ_K:
 				case BPF_S_JMP_JGT_K:
 				case BPF_S_JMP_JGE_K:
+				case BPF_S_JMP_JLT_K:
+				case BPF_S_JMP_JLE_K:
 					if (is_simm13(K)) {
 						emit_cmpi(r_A, K);
 					} else {
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 4/8] PPC: bpf_jit_comp: add JMP instructions for BPF JIT
  2012-12-31 13:59 [PATCH net-next 0/8] Add complementary BPF conditional jump instructions Daniel Borkmann
                   ` (2 preceding siblings ...)
  2012-12-31 13:59 ` [PATCH net-next 3/8] sparc: " Daniel Borkmann
@ 2012-12-31 13:59 ` Daniel Borkmann
  2012-12-31 13:59 ` [PATCH net-next 5/8] net: bpf: add neq jump operations to bpf machine Daniel Borkmann
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Daniel Borkmann @ 2012-12-31 13:59 UTC (permalink / raw)
  To: davem; +Cc: netdev, Matt Evans

This patch is a follow-up for patch "net: bpf: add lt,le jump
operations to bpf machine" that implements BPF PowerPC JIT parts
for BPF JMP_LT/JMP_LE operations.

Cc: Matt Evans <matt@ozlabs.org>
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
 arch/powerpc/net/bpf_jit.h      |  1 +
 arch/powerpc/net/bpf_jit_comp.c | 12 ++++++++++++
 2 files changed, 13 insertions(+)

diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
index 8a5dfaf..f105b3b 100644
--- a/arch/powerpc/net/bpf_jit.h
+++ b/arch/powerpc/net/bpf_jit.h
@@ -221,6 +221,7 @@ static inline bool is_nearbranch(int offset)
 #define COND_EQ		(CR0_EQ | COND_CMP_TRUE)
 #define COND_NE		(CR0_EQ | COND_CMP_FALSE)
 #define COND_LT		(CR0_LT | COND_CMP_TRUE)
+#define COND_LE		(CR0_GT | COND_CMP_FALSE)
 
 #define SEEN_DATAREF 0x10000 /* might call external helpers */
 #define SEEN_XREG    0x20000 /* X reg is used */
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index e834f1e..46b4d21 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -484,6 +484,14 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
 		case BPF_S_JMP_JGE_X:
 			true_cond = COND_GE;
 			goto cond_branch;
+		case BPF_S_JMP_JLT_K:
+		case BPF_S_JMP_JLT_X:
+			true_cond = COND_LT;
+			goto cond_branch;
+		case BPF_S_JMP_JLE_K:
+		case BPF_S_JMP_JLE_X:
+			true_cond = COND_LE;
+			goto cond_branch;
 		case BPF_S_JMP_JEQ_K:
 		case BPF_S_JMP_JEQ_X:
 			true_cond = COND_EQ;
@@ -503,6 +511,8 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
 			switch (filter[i].code) {
 			case BPF_S_JMP_JGT_X:
 			case BPF_S_JMP_JGE_X:
+			case BPF_S_JMP_JLT_X:
+			case BPF_S_JMP_JLE_X:
 			case BPF_S_JMP_JEQ_X:
 				ctx->seen |= SEEN_XREG;
 				PPC_CMPLW(r_A, r_X);
@@ -514,6 +524,8 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
 			case BPF_S_JMP_JEQ_K:
 			case BPF_S_JMP_JGT_K:
 			case BPF_S_JMP_JGE_K:
+			case BPF_S_JMP_JLT_K:
+			case BPF_S_JMP_JLE_K:
 				if (K < 32768)
 					PPC_CMPLWI(r_A, K);
 				else {
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 5/8] net: bpf: add neq jump operations to bpf machine
  2012-12-31 13:59 [PATCH net-next 0/8] Add complementary BPF conditional jump instructions Daniel Borkmann
                   ` (3 preceding siblings ...)
  2012-12-31 13:59 ` [PATCH net-next 4/8] PPC: " Daniel Borkmann
@ 2012-12-31 13:59 ` Daniel Borkmann
  2013-01-01  3:25   ` Eric Dumazet
  2012-12-31 13:59 ` [PATCH net-next 7/8] sparc: bpf_jit_comp: add JMP_NEQ instructions for BPF JIT Daniel Borkmann
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 14+ messages in thread
From: Daniel Borkmann @ 2012-12-31 13:59 UTC (permalink / raw)
  To: davem; +Cc: netdev

This patch adds jump operations for neq (!=) that compare A
with K resp. X in order to facilitate filter programming with
conditional jumps, since currently only eq (==) is present in
the BPF machine. For user-space filter programming / compilers,
it might be good to also have this complementary operation.
They don't need to be as ancillary, since they fit into the
instruction encoding directly. Follow-up BPF JIT patches are
welcomed.

Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
 include/linux/filter.h      |  2 ++
 include/uapi/linux/filter.h |  1 +
 net/core/filter.c           | 14 ++++++++++++++
 3 files changed, 17 insertions(+)

diff --git a/include/linux/filter.h b/include/linux/filter.h
index 36630bc..256c01f 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -105,6 +105,8 @@ enum {
 	BPF_S_JMP_JA,
 	BPF_S_JMP_JEQ_K,
 	BPF_S_JMP_JEQ_X,
+	BPF_S_JMP_JNEQ_K,
+	BPF_S_JMP_JNEQ_X,
 	BPF_S_JMP_JGE_K,
 	BPF_S_JMP_JGE_X,
 	BPF_S_JMP_JGT_K,
diff --git a/include/uapi/linux/filter.h b/include/uapi/linux/filter.h
index 3ebcc2e..d909a6f 100644
--- a/include/uapi/linux/filter.h
+++ b/include/uapi/linux/filter.h
@@ -80,6 +80,7 @@ struct sock_fprog {	/* Required for SO_ATTACH_FILTER. */
 #define         BPF_JSET        0x40
 #define         BPF_JLT         0x50
 #define         BPF_JLE         0x60
+#define         BPF_JNEQ        0x70
 
 #define BPF_SRC(code)   ((code) & 0x08)
 #define         BPF_K           0x00
diff --git a/net/core/filter.c b/net/core/filter.c
index 2122eba..b360fb3 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -228,6 +228,9 @@ unsigned int sk_run_filter(const struct sk_buff *skb,
 		case BPF_S_JMP_JEQ_K:
 			fentry += (A == K) ? fentry->jt : fentry->jf;
 			continue;
+		case BPF_S_JMP_JNEQ_K:
+			fentry += (A != K) ? fentry->jt : fentry->jf;
+			continue;
 		case BPF_S_JMP_JSET_K:
 			fentry += (A & K) ? fentry->jt : fentry->jf;
 			continue;
@@ -246,6 +249,9 @@ unsigned int sk_run_filter(const struct sk_buff *skb,
 		case BPF_S_JMP_JEQ_X:
 			fentry += (A == X) ? fentry->jt : fentry->jf;
 			continue;
+		case BPF_S_JMP_JNEQ_X:
+			fentry += (A != X) ? fentry->jt : fentry->jf;
+			continue;
 		case BPF_S_JMP_JSET_X:
 			fentry += (A & X) ? fentry->jt : fentry->jf;
 			continue;
@@ -454,6 +460,8 @@ static int check_load_and_stores(struct sock_filter *filter, int flen)
 			break;
 		case BPF_S_JMP_JEQ_K:
 		case BPF_S_JMP_JEQ_X:
+		case BPF_S_JMP_JNEQ_K:
+		case BPF_S_JMP_JNEQ_X:
 		case BPF_S_JMP_JGE_K:
 		case BPF_S_JMP_JGE_X:
 		case BPF_S_JMP_JGT_K:
@@ -540,6 +548,8 @@ int sk_chk_filter(struct sock_filter *filter, unsigned int flen)
 		[BPF_JMP|BPF_JA]         = BPF_S_JMP_JA,
 		[BPF_JMP|BPF_JEQ|BPF_K]  = BPF_S_JMP_JEQ_K,
 		[BPF_JMP|BPF_JEQ|BPF_X]  = BPF_S_JMP_JEQ_X,
+		[BPF_JMP|BPF_JNEQ|BPF_K] = BPF_S_JMP_JNEQ_K,
+		[BPF_JMP|BPF_JNEQ|BPF_X] = BPF_S_JMP_JNEQ_X,
 		[BPF_JMP|BPF_JGE|BPF_K]  = BPF_S_JMP_JGE_K,
 		[BPF_JMP|BPF_JGE|BPF_X]  = BPF_S_JMP_JGE_X,
 		[BPF_JMP|BPF_JGT|BPF_K]  = BPF_S_JMP_JGT_K,
@@ -599,6 +609,8 @@ int sk_chk_filter(struct sock_filter *filter, unsigned int flen)
 			break;
 		case BPF_S_JMP_JEQ_K:
 		case BPF_S_JMP_JEQ_X:
+		case BPF_S_JMP_JNEQ_K:
+		case BPF_S_JMP_JNEQ_X:
 		case BPF_S_JMP_JGE_K:
 		case BPF_S_JMP_JGE_X:
 		case BPF_S_JMP_JGT_K:
@@ -852,6 +864,8 @@ static void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to)
 		[BPF_S_JMP_JA]		= BPF_JMP|BPF_JA,
 		[BPF_S_JMP_JEQ_K]	= BPF_JMP|BPF_JEQ|BPF_K,
 		[BPF_S_JMP_JEQ_X]	= BPF_JMP|BPF_JEQ|BPF_X,
+		[BPF_S_JMP_JNEQ_K]	= BPF_JMP|BPF_JNEQ|BPF_K,
+		[BPF_S_JMP_JNEQ_X]	= BPF_JMP|BPF_JNEQ|BPF_X,
 		[BPF_S_JMP_JGE_K]	= BPF_JMP|BPF_JGE|BPF_K,
 		[BPF_S_JMP_JGE_X]	= BPF_JMP|BPF_JGE|BPF_X,
 		[BPF_S_JMP_JGT_K]	= BPF_JMP|BPF_JGT|BPF_K,
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 7/8] sparc: bpf_jit_comp: add JMP_NEQ instructions for BPF JIT
  2012-12-31 13:59 [PATCH net-next 0/8] Add complementary BPF conditional jump instructions Daniel Borkmann
                   ` (4 preceding siblings ...)
  2012-12-31 13:59 ` [PATCH net-next 5/8] net: bpf: add neq jump operations to bpf machine Daniel Borkmann
@ 2012-12-31 13:59 ` Daniel Borkmann
  2012-12-31 13:59 ` [PATCH net-next 8/8] PPC: " Daniel Borkmann
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Daniel Borkmann @ 2012-12-31 13:59 UTC (permalink / raw)
  To: davem; +Cc: netdev

This patch is a follow-up for patch "net: bpf: add neq jump
operations to bpf machine" that implements BPF Sparc JIT parts
for the BPF JMP_NEQ operation.

Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
 arch/sparc/net/bpf_jit_comp.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/sparc/net/bpf_jit_comp.c b/arch/sparc/net/bpf_jit_comp.c
index f5b4fc9..5da318c 100644
--- a/arch/sparc/net/bpf_jit_comp.c
+++ b/arch/sparc/net/bpf_jit_comp.c
@@ -694,12 +694,14 @@ common_load_ind:		seen |= SEEN_DATAREF | SEEN_XREG;
 			COND_SEL(BPF_S_JMP_JLT_K, BLU, BGEU);
 			COND_SEL(BPF_S_JMP_JLE_K, BLEU, BGU);
 			COND_SEL(BPF_S_JMP_JEQ_K, BE, BNE);
+			COND_SEL(BPF_S_JMP_JNEQ_K, BNE, BE);
 			COND_SEL(BPF_S_JMP_JSET_K, BNE, BE);
 			COND_SEL(BPF_S_JMP_JGT_X, BGU, BLEU);
 			COND_SEL(BPF_S_JMP_JGE_X, BGEU, BLU);
 			COND_SEL(BPF_S_JMP_JLT_X, BLU, BGEU);
 			COND_SEL(BPF_S_JMP_JLE_X, BLEU, BGU);
 			COND_SEL(BPF_S_JMP_JEQ_X, BE, BNE);
+			COND_SEL(BPF_S_JMP_JNEQ_X, BNE, BE);
 			COND_SEL(BPF_S_JMP_JSET_X, BNE, BE);
 
 cond_branch:			f_offset = addrs[i + filter[i].jf];
@@ -718,6 +720,7 @@ cond_branch:			f_offset = addrs[i + filter[i].jf];
 				case BPF_S_JMP_JLT_X:
 				case BPF_S_JMP_JLE_X:
 				case BPF_S_JMP_JEQ_X:
+				case BPF_S_JMP_JNEQ_X:
 					seen |= SEEN_XREG;
 					emit_cmp(r_A, r_X);
 					break;
@@ -726,6 +729,7 @@ cond_branch:			f_offset = addrs[i + filter[i].jf];
 					emit_btst(r_A, r_X);
 					break;
 				case BPF_S_JMP_JEQ_K:
+				case BPF_S_JMP_JNEQ_K:
 				case BPF_S_JMP_JGT_K:
 				case BPF_S_JMP_JGE_K:
 				case BPF_S_JMP_JLT_K:
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 8/8] PPC: bpf_jit_comp: add JMP_NEQ instructions for BPF JIT
  2012-12-31 13:59 [PATCH net-next 0/8] Add complementary BPF conditional jump instructions Daniel Borkmann
                   ` (5 preceding siblings ...)
  2012-12-31 13:59 ` [PATCH net-next 7/8] sparc: bpf_jit_comp: add JMP_NEQ instructions for BPF JIT Daniel Borkmann
@ 2012-12-31 13:59 ` Daniel Borkmann
  2012-12-31 17:00 ` [PATCH net-next 6/8] x86: " Daniel Borkmann
  2012-12-31 22:37 ` [PATCH net-next 0/8] Add complementary BPF conditional jump instructions David Miller
  8 siblings, 0 replies; 14+ messages in thread
From: Daniel Borkmann @ 2012-12-31 13:59 UTC (permalink / raw)
  To: davem; +Cc: netdev, Matt Evans

This patch is a follow-up for patch "net: bpf: add neq jump
operations to bpf machine" that implements BPF PowerPC JIT
parts for the BPF JMP_NEQ operation.

Cc: Matt Evans <matt@ozlabs.org>
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
 arch/powerpc/net/bpf_jit_comp.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index 46b4d21..4b9ee59 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -496,6 +496,8 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
 		case BPF_S_JMP_JEQ_X:
 			true_cond = COND_EQ;
 			goto cond_branch;
+		case BPF_S_JMP_JNEQ_K:
+		case BPF_S_JMP_JNEQ_X:
 		case BPF_S_JMP_JSET_K:
 		case BPF_S_JMP_JSET_X:
 			true_cond = COND_NE;
@@ -514,6 +516,7 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
 			case BPF_S_JMP_JLT_X:
 			case BPF_S_JMP_JLE_X:
 			case BPF_S_JMP_JEQ_X:
+			case BPF_S_JMP_JNEQ_X:
 				ctx->seen |= SEEN_XREG;
 				PPC_CMPLW(r_A, r_X);
 				break;
@@ -522,6 +525,7 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
 				PPC_AND_DOT(r_scratch1, r_A, r_X);
 				break;
 			case BPF_S_JMP_JEQ_K:
+			case BPF_S_JMP_JNEQ_K:
 			case BPF_S_JMP_JGT_K:
 			case BPF_S_JMP_JGE_K:
 			case BPF_S_JMP_JLT_K:
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 6/8] x86: bpf_jit_comp: add JMP_NEQ instructions for BPF JIT
  2012-12-31 13:59 [PATCH net-next 0/8] Add complementary BPF conditional jump instructions Daniel Borkmann
                   ` (6 preceding siblings ...)
  2012-12-31 13:59 ` [PATCH net-next 8/8] PPC: " Daniel Borkmann
@ 2012-12-31 17:00 ` Daniel Borkmann
  2012-12-31 22:37 ` [PATCH net-next 0/8] Add complementary BPF conditional jump instructions David Miller
  8 siblings, 0 replies; 14+ messages in thread
From: Daniel Borkmann @ 2012-12-31 17:00 UTC (permalink / raw)
  To: davem; +Cc: netdev, Eric Dumazet

This patch is a follow-up for patch "net: bpf: add neq jump
operations to bpf machine" that implements BPF x86 JIT parts
for the BPF JMP_NEQ operation.

Cc: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
 arch/x86/net/bpf_jit_comp.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index 6d6a4ce..bd10c83 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -587,12 +587,14 @@ common_load_ind:		seen |= SEEN_DATAREF | SEEN_XREG;
 			COND_SEL(BPF_S_JMP_JLT_K, X86_JB, X86_JAE);
 			COND_SEL(BPF_S_JMP_JLE_K, X86_JBE, X86_JA);
 			COND_SEL(BPF_S_JMP_JEQ_K, X86_JE, X86_JNE);
+			COND_SEL(BPF_S_JMP_JNEQ_K,X86_JNE, X86_JE);
 			COND_SEL(BPF_S_JMP_JSET_K,X86_JNE, X86_JE);
 			COND_SEL(BPF_S_JMP_JGT_X, X86_JA, X86_JBE);
 			COND_SEL(BPF_S_JMP_JGE_X, X86_JAE, X86_JB);
 			COND_SEL(BPF_S_JMP_JLT_X, X86_JB, X86_JAE);
 			COND_SEL(BPF_S_JMP_JLE_X, X86_JBE, X86_JA);
 			COND_SEL(BPF_S_JMP_JEQ_X, X86_JE, X86_JNE);
+			COND_SEL(BPF_S_JMP_JNEQ_X,X86_JNE, X86_JE);
 			COND_SEL(BPF_S_JMP_JSET_X,X86_JNE, X86_JE);
 
 cond_branch:			f_offset = addrs[i + filter[i].jf] - addrs[i];
@@ -610,6 +612,7 @@ cond_branch:			f_offset = addrs[i + filter[i].jf] - addrs[i];
 				case BPF_S_JMP_JLT_X:
 				case BPF_S_JMP_JLE_X:
 				case BPF_S_JMP_JEQ_X:
+				case BPF_S_JMP_JNEQ_X:
 					seen |= SEEN_XREG;
 					EMIT2(0x39, 0xd8); /* cmp %ebx,%eax */
 					break;
@@ -618,6 +621,7 @@ cond_branch:			f_offset = addrs[i + filter[i].jf] - addrs[i];
 					EMIT2(0x85, 0xd8); /* test %ebx,%eax */
 					break;
 				case BPF_S_JMP_JEQ_K:
+				case BPF_S_JMP_JNEQ_K:
 					if (K == 0) {
 						EMIT2(0x85, 0xc0); /* test   %eax,%eax */
 						break;
-- 
1.7.11.7

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH net-next 0/8] Add complementary BPF conditional jump instructions
  2012-12-31 13:59 [PATCH net-next 0/8] Add complementary BPF conditional jump instructions Daniel Borkmann
                   ` (7 preceding siblings ...)
  2012-12-31 17:00 ` [PATCH net-next 6/8] x86: " Daniel Borkmann
@ 2012-12-31 22:37 ` David Miller
  2013-01-01  3:29   ` Eric Dumazet
  8 siblings, 1 reply; 14+ messages in thread
From: David Miller @ 2012-12-31 22:37 UTC (permalink / raw)
  To: dborkman; +Cc: netdev

From: Daniel Borkmann <dborkman@redhat.com>
Date: Mon, 31 Dec 2012 14:59:40 +0100

> This set adds adds jump operations for lt (<), le (<=), ne (!=) that
> compare A with K resp. X in order to facilitate filter programming
> with conditional jumps, as also available in McCanne et. al's BPF+
> paper (``BPF+: Exploiting Global Data-flow Optimization in a Generalized
> Packet Filter Architecture'').
> 
> Also, follow-up BPF JIT implementations for x86, Sparc and PowerPC
> are added in this set.

Whilst I agree that adding NE jumps adds great value and closes a
serious gap, the rest can be synthesized by simply swapping the
arguments and using a comparison that does already exist.

Why isn't that sufficient?

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH net-next 5/8] net: bpf: add neq jump operations to bpf machine
  2012-12-31 13:59 ` [PATCH net-next 5/8] net: bpf: add neq jump operations to bpf machine Daniel Borkmann
@ 2013-01-01  3:25   ` Eric Dumazet
  0 siblings, 0 replies; 14+ messages in thread
From: Eric Dumazet @ 2013-01-01  3:25 UTC (permalink / raw)
  To: Daniel Borkmann; +Cc: davem, netdev

On Mon, 2012-12-31 at 14:59 +0100, Daniel Borkmann wrote:
> This patch adds jump operations for neq (!=) that compare A
> with K resp. X in order to facilitate filter programming with
> conditional jumps, since currently only eq (==) is present in
> the BPF machine. For user-space filter programming / compilers,
> it might be good to also have this complementary operation.
> They don't need to be as ancillary, since they fit into the
> instruction encoding directly. Follow-up BPF JIT patches are
> welcomed.
> 
> Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
> ---
>  include/linux/filter.h      |  2 ++
>  include/uapi/linux/filter.h |  1 +
>  net/core/filter.c           | 14 ++++++++++++++
>  3 files changed, 17 insertions(+)
> 
> diff --git a/include/linux/filter.h b/include/linux/filter.h
> index 36630bc..256c01f 100644
> --- a/include/linux/filter.h
> +++ b/include/linux/filter.h
> @@ -105,6 +105,8 @@ enum {
>  	BPF_S_JMP_JA,
>  	BPF_S_JMP_JEQ_K,
>  	BPF_S_JMP_JEQ_X,
> +	BPF_S_JMP_JNEQ_K,
> +	BPF_S_JMP_JNEQ_X,
>  	BPF_S_JMP_JGE_K,
>  	BPF_S_JMP_JGE_X,
>  	BPF_S_JMP_JGT_K,
> diff --git a/include/uapi/linux/filter.h b/include/uapi/linux/filter.h
> index 3ebcc2e..d909a6f 100644
> --- a/include/uapi/linux/filter.h
> +++ b/include/uapi/linux/filter.h
> @@ -80,6 +80,7 @@ struct sock_fprog {	/* Required for SO_ATTACH_FILTER. */
>  #define         BPF_JSET        0x40
>  #define         BPF_JLT         0x50
>  #define         BPF_JLE         0x60
> +#define         BPF_JNEQ        0x70
>  
>  #define BPF_SRC(code)   ((code) & 0x08)
>  #define         BPF_K           0x00
> diff --git a/net/core/filter.c b/net/core/filter.c
> index 2122eba..b360fb3 100644
> --- a/net/core/filter.c
> +++ b/net/core/filter.c
> @@ -228,6 +228,9 @@ unsigned int sk_run_filter(const struct sk_buff *skb,
>  		case BPF_S_JMP_JEQ_K:
>  			fentry += (A == K) ? fentry->jt : fentry->jf;
>  			continue;
> +		case BPF_S_JMP_JNEQ_K:
> +			fentry += (A != K) ? fentry->jt : fentry->jf;
> +			continue;
>  		case BPF_S_JMP_JSET_K:
>  			fentry += (A & K) ? fentry->jt : fentry->jf;
>  			continue;

This makes no sense at all to me, it seems kernel bloat.

The JNE instruction already exists.

You only have to take the JEQ (jt,jf) and swap the jt/jf targets.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH net-next 0/8] Add complementary BPF conditional jump instructions
  2012-12-31 22:37 ` [PATCH net-next 0/8] Add complementary BPF conditional jump instructions David Miller
@ 2013-01-01  3:29   ` Eric Dumazet
  2013-01-01  5:18     ` David Miller
  0 siblings, 1 reply; 14+ messages in thread
From: Eric Dumazet @ 2013-01-01  3:29 UTC (permalink / raw)
  To: David Miller; +Cc: dborkman, netdev

On Mon, 2012-12-31 at 14:37 -0800, David Miller wrote:

> Whilst I agree that adding NE jumps adds great value and closes a
> serious gap, the rest can be synthesized by simply swapping the
> arguments and using a comparison that does already exist.
> 
> Why isn't that sufficient?

I am afraid none of these patches is needed at all.

Swapping the jt/jf is plainly enough for the user land compiler.

libcap seems to do it already

# tcpdump -i lo 'len!=0 && ip6' -d
(000) ld       #pktlen
(001) jeq      #0x0             jt 5	jf 2
(002) ldh      [12]
(003) jeq      #0x86dd          jt 4	jf 5
(004) ret      #96
(005) ret      #0
# tcpdump -i lo 'len==0 && ip6' -d
(000) ld       #pktlen
(001) jeq      #0x0             jt 2	jf 5
(002) ldh      [12]
(003) jeq      #0x86dd          jt 4	jf 5
(004) ret      #96
(005) ret      #0

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH net-next 0/8] Add complementary BPF conditional jump instructions
  2013-01-01  3:29   ` Eric Dumazet
@ 2013-01-01  5:18     ` David Miller
  2013-01-02 10:47       ` Daniel Borkmann
  0 siblings, 1 reply; 14+ messages in thread
From: David Miller @ 2013-01-01  5:18 UTC (permalink / raw)
  To: eric.dumazet; +Cc: dborkman, netdev

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Mon, 31 Dec 2012 19:29:02 -0800

> On Mon, 2012-12-31 at 14:37 -0800, David Miller wrote:
> 
>> Whilst I agree that adding NE jumps adds great value and closes a
>> serious gap, the rest can be synthesized by simply swapping the
>> arguments and using a comparison that does already exist.
>> 
>> Why isn't that sufficient?
> 
> I am afraid none of these patches is needed at all.
> 
> Swapping the jt/jf is plainly enough for the user land compiler.
> 
> libcap seems to do it already

Agreed.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH net-next 0/8] Add complementary BPF conditional jump instructions
  2013-01-01  5:18     ` David Miller
@ 2013-01-02 10:47       ` Daniel Borkmann
  0 siblings, 0 replies; 14+ messages in thread
From: Daniel Borkmann @ 2013-01-02 10:47 UTC (permalink / raw)
  To: David Miller; +Cc: eric.dumazet, netdev

On Tue, Jan 1, 2013 at 6:18 AM, David Miller <davem@davemloft.net> wrote:
> From: Eric Dumazet <eric.dumazet@gmail.com>
> Date: Mon, 31 Dec 2012 19:29:02 -0800
>
>> On Mon, 2012-12-31 at 14:37 -0800, David Miller wrote:
>>
>>> Whilst I agree that adding NE jumps adds great value and closes a
>>> serious gap, the rest can be synthesized by simply swapping the
>>> arguments and using a comparison that does already exist.
>>>
>>> Why isn't that sufficient?
>>
>> I am afraid none of these patches is needed at all.
>>
>> Swapping the jt/jf is plainly enough for the user land compiler.
>>
>> libcap seems to do it already
>
> Agreed.

Fair enough, it's probably better to let this be done by user space
via such a hack than adding the actual operations for this.

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2013-01-02 10:47 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-12-31 13:59 [PATCH net-next 0/8] Add complementary BPF conditional jump instructions Daniel Borkmann
2012-12-31 13:59 ` [PATCH net-next 1/8] net: bpf: add lt,le jump operations to bpf machine Daniel Borkmann
2012-12-31 13:59 ` [PATCH net-next 2/8] x86: bpf_jit_comp: add JMP instructions for BPF JIT Daniel Borkmann
2012-12-31 13:59 ` [PATCH net-next 3/8] sparc: " Daniel Borkmann
2012-12-31 13:59 ` [PATCH net-next 4/8] PPC: " Daniel Borkmann
2012-12-31 13:59 ` [PATCH net-next 5/8] net: bpf: add neq jump operations to bpf machine Daniel Borkmann
2013-01-01  3:25   ` Eric Dumazet
2012-12-31 13:59 ` [PATCH net-next 7/8] sparc: bpf_jit_comp: add JMP_NEQ instructions for BPF JIT Daniel Borkmann
2012-12-31 13:59 ` [PATCH net-next 8/8] PPC: " Daniel Borkmann
2012-12-31 17:00 ` [PATCH net-next 6/8] x86: " Daniel Borkmann
2012-12-31 22:37 ` [PATCH net-next 0/8] Add complementary BPF conditional jump instructions David Miller
2013-01-01  3:29   ` Eric Dumazet
2013-01-01  5:18     ` David Miller
2013-01-02 10:47       ` Daniel Borkmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).