svn commit: r307707 - in head: share/man/man4 sys/amd64/amd64 sys/i386/i386 sys/net

Jung-uk Kim jkim at FreeBSD.org
Fri Oct 21 06:55:09 UTC 2016


Author: jkim
Date: Fri Oct 21 06:55:07 2016
New Revision: 307707
URL: https://svnweb.freebsd.org/changeset/base/307707

Log:
  Implement BPF_MOD and BPF_XOR instructions.
  
  These two ALU instructions first appeared on Linux.  Then, libpcap adopted
  and made them available since 1.6.2.  Now more platforms including NetBSD
  have them in kernel.  So do we.
   --이 줄 이하는 자동으로 제거됩니다--
  > Description of fields to fill in above:                     76 columns --|
  > PR:                       If and which Problem Report is related.
  > Submitted by:             If someone else sent in the change.
  > Reported by:              If someone else reported the issue.
  > Reviewed by:              If someone else reviewed your modification.
  > Approved by:              If you needed approval for this commit.
  > Obtained from:            If the change is from a third party.
  > MFC after:                N [day[s]|week[s]|month[s]].  Request a reminder email.
  > MFH:                      Ports tree branch name.  Request approval for merge.
  > Relnotes:                 Set to 'yes' for mention in release notes.
  > Security:                 Vulnerability reference (one per line) or description.
  > Sponsored by:             If the change was sponsored by an organization.
  > Differential Revision:    https://reviews.freebsd.org/D### (*full* phabric URL needed).
  > Empty fields above will be automatically removed.
  
  M    share/man/man4/bpf.4
  M    sys/amd64/amd64/bpf_jit_machdep.c
  M    sys/amd64/amd64/bpf_jit_machdep.h
  M    sys/i386/i386/bpf_jit_machdep.c
  M    sys/i386/i386/bpf_jit_machdep.h
  M    sys/net/bpf_filter.c

Modified:
  head/share/man/man4/bpf.4
  head/sys/amd64/amd64/bpf_jit_machdep.c
  head/sys/amd64/amd64/bpf_jit_machdep.h
  head/sys/i386/i386/bpf_jit_machdep.c
  head/sys/i386/i386/bpf_jit_machdep.h
  head/sys/net/bpf_filter.c

Modified: head/share/man/man4/bpf.4
==============================================================================
--- head/share/man/man4/bpf.4	Fri Oct 21 06:32:45 2016	(r307706)
+++ head/share/man/man4/bpf.4	Fri Oct 21 06:55:07 2016	(r307707)
@@ -49,7 +49,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd June 15, 2010
+.Dd October 21, 2016
 .Dt BPF 4
 .Os
 .Sh NAME
@@ -881,16 +881,20 @@ BPF_ALU+BPF_ADD+BPF_K	A <- A + k
 BPF_ALU+BPF_SUB+BPF_K	A <- A - k
 BPF_ALU+BPF_MUL+BPF_K	A <- A * k
 BPF_ALU+BPF_DIV+BPF_K	A <- A / k
+BPF_ALU+BPF_MOD+BPF_K	A <- A % k
 BPF_ALU+BPF_AND+BPF_K	A <- A & k
 BPF_ALU+BPF_OR+BPF_K	A <- A | k
+BPF_ALU+BPF_XOR+BPF_K	A <- A ^ k
 BPF_ALU+BPF_LSH+BPF_K	A <- A << k
 BPF_ALU+BPF_RSH+BPF_K	A <- A >> k
 BPF_ALU+BPF_ADD+BPF_X	A <- A + X
 BPF_ALU+BPF_SUB+BPF_X	A <- A - X
 BPF_ALU+BPF_MUL+BPF_X	A <- A * X
 BPF_ALU+BPF_DIV+BPF_X	A <- A / X
+BPF_ALU+BPF_MOD+BPF_X	A <- A % X
 BPF_ALU+BPF_AND+BPF_X	A <- A & X
 BPF_ALU+BPF_OR+BPF_X	A <- A | X
+BPF_ALU+BPF_XOR+BPF_X	A <- A ^ X
 BPF_ALU+BPF_LSH+BPF_X	A <- A << X
 BPF_ALU+BPF_RSH+BPF_X	A <- A >> X
 BPF_ALU+BPF_NEG		A <- -A

Modified: head/sys/amd64/amd64/bpf_jit_machdep.c
==============================================================================
--- head/sys/amd64/amd64/bpf_jit_machdep.c	Fri Oct 21 06:32:45 2016	(r307706)
+++ head/sys/amd64/amd64/bpf_jit_machdep.c	Fri Oct 21 06:55:07 2016	(r307707)
@@ -1,6 +1,6 @@
 /*-
  * Copyright (C) 2002-2003 NetGroup, Politecnico di Torino (Italy)
- * Copyright (C) 2005-2009 Jung-uk Kim <jkim at FreeBSD.org>
+ * Copyright (C) 2005-2016 Jung-uk Kim <jkim at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -494,6 +494,7 @@ bpf_jit_compile(struct bpf_insn *prog, u
 				break;
 
 			case BPF_ALU|BPF_DIV|BPF_X:
+			case BPF_ALU|BPF_MOD|BPF_X:
 				TESTrd(EDX, EDX);
 				if (fmem) {
 					JNEb(4);
@@ -507,6 +508,8 @@ bpf_jit_compile(struct bpf_insn *prog, u
 				MOVrd(EDX, ECX);
 				ZEROrd(EDX);
 				DIVrd(ECX);
+				if (BPF_OP(ins->code) == BPF_MOD)
+					MOVrd(EDX, EAX);
 				MOVrd(ECX, EDX);
 				break;
 
@@ -518,6 +521,10 @@ bpf_jit_compile(struct bpf_insn *prog, u
 				ORrd(EDX, EAX);
 				break;
 
+			case BPF_ALU|BPF_XOR|BPF_X:
+				XORrd(EDX, EAX);
+				break;
+
 			case BPF_ALU|BPF_LSH|BPF_X:
 				MOVrd(EDX, ECX);
 				SHL_CLrb(EAX);
@@ -544,10 +551,13 @@ bpf_jit_compile(struct bpf_insn *prog, u
 				break;
 
 			case BPF_ALU|BPF_DIV|BPF_K:
+			case BPF_ALU|BPF_MOD|BPF_K:
 				MOVrd(EDX, ECX);
 				ZEROrd(EDX);
 				MOVid(ins->k, ESI);
 				DIVrd(ESI);
+				if (BPF_OP(ins->code) == BPF_MOD)
+					MOVrd(EDX, EAX);
 				MOVrd(ECX, EDX);
 				break;
 
@@ -559,6 +569,10 @@ bpf_jit_compile(struct bpf_insn *prog, u
 				ORid(ins->k, EAX);
 				break;
 
+			case BPF_ALU|BPF_XOR|BPF_K:
+				XORid(ins->k, EAX);
+				break;
+
 			case BPF_ALU|BPF_LSH|BPF_K:
 				SHLib((ins->k) & 0xff, EAX);
 				break;

Modified: head/sys/amd64/amd64/bpf_jit_machdep.h
==============================================================================
--- head/sys/amd64/amd64/bpf_jit_machdep.h	Fri Oct 21 06:32:45 2016	(r307706)
+++ head/sys/amd64/amd64/bpf_jit_machdep.h	Fri Oct 21 06:55:07 2016	(r307707)
@@ -1,6 +1,6 @@
 /*-
  * Copyright (C) 2002-2003 NetGroup, Politecnico di Torino (Italy)
- * Copyright (C) 2005-2009 Jung-uk Kim <jkim at FreeBSD.org>
+ * Copyright (C) 2005-2016 Jung-uk Kim <jkim at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -357,6 +357,24 @@ typedef void (*emit_func)(bpf_bin_stream
 	emitm(&stream, i32, 4);						\
 } while (0)
 
+/* xorl sr32,dr32 */
+#define XORrd(sr32, dr32) do {						\
+	emitm(&stream, 0x31, 1);					\
+	emitm(&stream,							\
+	    (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1);		\
+} while (0)
+
+/* xorl i32,r32 */
+#define XORid(i32, r32) do {						\
+	if (r32 == EAX) {						\
+		emitm(&stream, 0x35, 1);				\
+	} else {							\
+		emitm(&stream, 0x81, 1);				\
+		emitm(&stream, (25 << 3) | r32, 1);			\
+	}								\
+	emitm(&stream, i32, 4);						\
+} while (0)
+
 /* shll i8,r32 */
 #define SHLib(i8, r32) do {						\
 	emitm(&stream, 0xc1, 1);					\

Modified: head/sys/i386/i386/bpf_jit_machdep.c
==============================================================================
--- head/sys/i386/i386/bpf_jit_machdep.c	Fri Oct 21 06:32:45 2016	(r307706)
+++ head/sys/i386/i386/bpf_jit_machdep.c	Fri Oct 21 06:55:07 2016	(r307707)
@@ -1,6 +1,6 @@
 /*-
  * Copyright (C) 2002-2003 NetGroup, Politecnico di Torino (Italy)
- * Copyright (C) 2005-2009 Jung-uk Kim <jkim at FreeBSD.org>
+ * Copyright (C) 2005-2016 Jung-uk Kim <jkim at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -139,6 +139,7 @@ bpf_jit_optimize(struct bpf_insn *prog, 
 			flags |= BPF_JIT_FJMP;
 			break;
 		case BPF_ALU|BPF_DIV|BPF_K:
+		case BPF_ALU|BPF_MOD|BPF_K:
 			flags |= BPF_JIT_FADK;
 			break;
 		}
@@ -515,6 +516,7 @@ bpf_jit_compile(struct bpf_insn *prog, u
 				break;
 
 			case BPF_ALU|BPF_DIV|BPF_X:
+			case BPF_ALU|BPF_MOD|BPF_X:
 				TESTrd(EDX, EDX);
 				if (save_esp) {
 					if (fpkt) {
@@ -536,6 +538,8 @@ bpf_jit_compile(struct bpf_insn *prog, u
 				MOVrd(EDX, ECX);
 				ZEROrd(EDX);
 				DIVrd(ECX);
+				if (BPF_OP(ins->code) == BPF_MOD)
+					MOVrd(EDX, EAX);
 				MOVrd(ECX, EDX);
 				break;
 
@@ -547,6 +551,10 @@ bpf_jit_compile(struct bpf_insn *prog, u
 				ORrd(EDX, EAX);
 				break;
 
+			case BPF_ALU|BPF_XOR|BPF_X:
+				XORrd(EDX, EAX);
+				break;
+
 			case BPF_ALU|BPF_LSH|BPF_X:
 				MOVrd(EDX, ECX);
 				SHL_CLrb(EAX);
@@ -573,10 +581,13 @@ bpf_jit_compile(struct bpf_insn *prog, u
 				break;
 
 			case BPF_ALU|BPF_DIV|BPF_K:
+			case BPF_ALU|BPF_MOD|BPF_K:
 				MOVrd(EDX, ECX);
 				ZEROrd(EDX);
 				MOVid(ins->k, ESI);
 				DIVrd(ESI);
+				if (BPF_OP(ins->code) == BPF_MOD)
+					MOVrd(EDX, EAX);
 				MOVrd(ECX, EDX);
 				break;
 
@@ -588,6 +599,10 @@ bpf_jit_compile(struct bpf_insn *prog, u
 				ORid(ins->k, EAX);
 				break;
 
+			case BPF_ALU|BPF_XOR|BPF_K:
+				XORid(ins->k, EAX);
+				break;
+
 			case BPF_ALU|BPF_LSH|BPF_K:
 				SHLib((ins->k) & 0xff, EAX);
 				break;

Modified: head/sys/i386/i386/bpf_jit_machdep.h
==============================================================================
--- head/sys/i386/i386/bpf_jit_machdep.h	Fri Oct 21 06:32:45 2016	(r307706)
+++ head/sys/i386/i386/bpf_jit_machdep.h	Fri Oct 21 06:55:07 2016	(r307707)
@@ -1,6 +1,6 @@
 /*-
  * Copyright (C) 2002-2003 NetGroup, Politecnico di Torino (Italy)
- * Copyright (C) 2005-2009 Jung-uk Kim <jkim at FreeBSD.org>
+ * Copyright (C) 2005-2016 Jung-uk Kim <jkim at FreeBSD.org>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -302,6 +302,24 @@ typedef void (*emit_func)(bpf_bin_stream
 	emitm(&stream, i32, 4);						\
 } while (0)
 
+/* xorl sr32,dr32 */
+#define XORrd(sr32, dr32) do {						\
+	emitm(&stream, 0x31, 1);					\
+	emitm(&stream,							\
+	    (3 << 6) | ((sr32 & 0x7) << 3) | (dr32 & 0x7), 1);		\
+} while (0)
+
+/* xorl i32,r32 */
+#define XORid(i32, r32) do {						\
+	if (r32 == EAX) {						\
+		emitm(&stream, 0x35, 1);				\
+	} else {							\
+		emitm(&stream, 0x81, 1);				\
+		emitm(&stream, (25 << 3) | r32, 1);			\
+	}								\
+	emitm(&stream, i32, 4);						\
+} while (0)
+
 /* shll i8,r32 */
 #define SHLib(i8, r32) do {						\
 	emitm(&stream, 0xc1, 1);					\

Modified: head/sys/net/bpf_filter.c
==============================================================================
--- head/sys/net/bpf_filter.c	Fri Oct 21 06:32:45 2016	(r307706)
+++ head/sys/net/bpf_filter.c	Fri Oct 21 06:55:07 2016	(r307707)
@@ -434,6 +434,12 @@ bpf_filter(const struct bpf_insn *pc, u_
 			A /= X;
 			continue;
 
+		case BPF_ALU|BPF_MOD|BPF_X:
+			if (X == 0)
+				return (0);
+			A %= X;
+			continue;
+
 		case BPF_ALU|BPF_AND|BPF_X:
 			A &= X;
 			continue;
@@ -442,6 +448,10 @@ bpf_filter(const struct bpf_insn *pc, u_
 			A |= X;
 			continue;
 
+		case BPF_ALU|BPF_XOR|BPF_X:
+			A ^= X;
+			continue;
+
 		case BPF_ALU|BPF_LSH|BPF_X:
 			A <<= X;
 			continue;
@@ -466,6 +476,10 @@ bpf_filter(const struct bpf_insn *pc, u_
 			A /= pc->k;
 			continue;
 
+		case BPF_ALU|BPF_MOD|BPF_K:
+			A %= pc->k;
+			continue;
+
 		case BPF_ALU|BPF_AND|BPF_K:
 			A &= pc->k;
 			continue;
@@ -474,6 +488,10 @@ bpf_filter(const struct bpf_insn *pc, u_
 			A |= pc->k;
 			continue;
 
+		case BPF_ALU|BPF_XOR|BPF_K:
+			A ^= pc->k;
+			continue;
+
 		case BPF_ALU|BPF_LSH|BPF_K:
 			A <<= pc->k;
 			continue;
@@ -508,8 +526,8 @@ static const u_short	bpf_code_map[] = {
 	0x1013,	/* 0x60-0x6f: 1100100000001000 */
 	0x1010,	/* 0x70-0x7f: 0000100000001000 */
 	0x0093,	/* 0x80-0x8f: 1100100100000000 */
-	0x0000,	/* 0x90-0x9f: 0000000000000000 */
-	0x0000,	/* 0xa0-0xaf: 0000000000000000 */
+	0x1010,	/* 0x90-0x9f: 0000100000001000 */
+	0x1010,	/* 0xa0-0xaf: 0000100000001000 */
 	0x0002,	/* 0xb0-0xbf: 0100000000000000 */
 	0x0000,	/* 0xc0-0xcf: 0000000000000000 */
 	0x0000,	/* 0xd0-0xdf: 0000000000000000 */
@@ -577,7 +595,8 @@ bpf_validate(const struct bpf_insn *f, i
 		/*
 		 * Check for constant division by 0.
 		 */
-		if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0)
+		if ((p->code == (BPF_ALU|BPF_DIV|BPF_K) ||
+		    p->code == (BPF_ALU|BPF_MOD|BPF_K)) && p->k == 0)
 			return (0);
 	}
 	return (BPF_CLASS(f[len - 1].code) == BPF_RET);


More information about the svn-src-head mailing list