Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Implement copfuncs and external memory in bpfjit.
details: https://anonhg.NetBSD.org/src/rev/a84824baf00f
branches: trunk
changeset: 796897:a84824baf00f
user: alnsn <alnsn%NetBSD.org@localhost>
date: Tue Jun 24 10:53:30 2014 +0000
description:
Implement copfuncs and external memory in bpfjit.
diffstat:
sys/net/bpf.c | 29 +-
sys/net/bpf.h | 72 +-
sys/net/bpf_filter.c | 91 +-
sys/net/bpfjit.c | 441 ++++++++-
sys/net/bpfjit.h | 20 +-
sys/net/npf/npf_ruleset.c | 10 +-
tests/lib/libbpfjit/t_bpfjit.c | 1005 ++++++++++++-----------
usr.sbin/npf/npftest/libnpftest/npf_bpf_test.c | 4 +-
8 files changed, 1048 insertions(+), 624 deletions(-)
diffs (truncated from 3177 to 300 lines):
diff -r 2f4a1bb98e95 -r a84824baf00f sys/net/bpf.c
--- a/sys/net/bpf.c Tue Jun 24 10:08:45 2014 +0000
+++ b/sys/net/bpf.c Tue Jun 24 10:53:30 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bpf.c,v 1.182 2014/03/16 05:20:30 dholland Exp $ */
+/* $NetBSD: bpf.c,v 1.183 2014/06/24 10:53:30 alnsn Exp $ */
/*
* Copyright (c) 1990, 1991, 1993
@@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.182 2014/03/16 05:20:30 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.183 2014/06/24 10:53:30 alnsn Exp $");
#if defined(_KERNEL_OPT)
#include "opt_bpf.h"
@@ -197,6 +197,7 @@
bpfjit_func_t
bpf_jit_generate(bpf_ctx_t *bc, void *code, size_t size)
{
+
membar_consumer();
if (bpfjit_module_ops.bj_generate_code != NULL) {
return bpfjit_module_ops.bj_generate_code(bc, code, size);
@@ -1114,10 +1115,8 @@
return EINVAL;
}
membar_consumer();
- if (bpf_jit) {
- bpf_ctx_t *bc = bpf_default_ctx();
- jcode = bpf_jit_generate(bc, fcode, flen);
- }
+ if (bpf_jit)
+ jcode = bpf_jit_generate(NULL, fcode, flen);
} else {
fcode = NULL;
}
@@ -1388,17 +1387,17 @@
bpf_deliver(struct bpf_if *bp, void *(*cpfn)(void *, const void *, size_t),
void *pkt, u_int pktlen, u_int buflen, const bool rcv)
{
- bpf_ctx_t *bc = bpf_default_ctx();
- bpf_args_t args = {
- .pkt = pkt,
- .wirelen = pktlen,
- .buflen = buflen,
- .arg = NULL
- };
+ struct timespec ts;
+ bpf_args_t args;
struct bpf_d *d;
- struct timespec ts;
+
+ const bpf_ctx_t *bc = NULL;
bool gottime = false;
+ args.pkt = (const uint8_t *)pkt;
+ args.wirelen = pktlen;
+ args.buflen = buflen;
+
/*
* Note that the IPL does not have to be raised at this point.
* The only problem that could arise here is that if two different
@@ -1414,7 +1413,7 @@
bpf_gstats.bs_recv++;
if (d->bd_jitcode)
- slen = d->bd_jitcode(pkt, pktlen, buflen);
+ slen = d->bd_jitcode(bc, &args);
else
slen = bpf_filter_ext(bc, d->bd_filter, &args);
diff -r 2f4a1bb98e95 -r a84824baf00f sys/net/bpf.h
--- a/sys/net/bpf.h Tue Jun 24 10:08:45 2014 +0000
+++ b/sys/net/bpf.h Tue Jun 24 10:53:30 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bpf.h,v 1.63 2013/11/15 00:12:44 rmind Exp $ */
+/* $NetBSD: bpf.h,v 1.64 2014/06/24 10:53:30 alnsn Exp $ */
/*
* Copyright (c) 1990, 1991, 1993
@@ -45,6 +45,9 @@
/* BSD style release date */
#define BPF_RELEASE 199606
+/* Date when COP instructions and external memory have been released. */
+#define BPF_COP_EXTMEM_RELEASE 20140624
+
__BEGIN_DECLS
typedef int bpf_int32;
@@ -280,6 +283,32 @@
#define BPF_MEMWORDS 16
/*
+ * Each bit in bpf_memword_init_t value indicates if the corresponding
+ * external memory word is initialised prior to calling a bpf program.
+ * Note that when used internally, a meaning is often flipped: bits
+ * indicate which memory words need to be initialised prior to
+ * executing a bpf program.
+ */
+typedef uint32_t bpf_memword_init_t;
+#define BPF_MEMWORD_INIT(k) (UINT32_C(1) << (k))
+
+/* Two most significant bits are reserved by bpfjit. */
+__CTASSERT(BPF_MEMWORDS + 2 <= sizeof(bpf_memword_init_t) * NBBY);
+
+#ifdef _KERNEL
+/*
+ * Max number of external memory words (for BPF_LD|BPF_MEM and BPF_ST).
+ */
+#define BPF_MAX_MEMWORDS 30
+__CTASSERT(BPF_MAX_MEMWORDS >= BPF_MEMWORDS);
+
+#ifdef __BPF_PRIVATE
+/* Two most significant bits are reserved by bpfjit. */
+__CTASSERT(BPF_MAX_MEMWORDS + 2 <= sizeof(bpf_memword_init_t) * NBBY);
+#endif
+#endif
+
+/*
* Structure to retrieve available DLTs for the interface.
*/
struct bpf_dltlist {
@@ -293,20 +322,35 @@
struct bpf_args;
typedef struct bpf_args bpf_args_t;
-#if defined(_KERNEL) || defined(__BPF_PRIVATE)
-typedef uint32_t (*bpf_copfunc_t)(bpf_ctx_t *, bpf_args_t *, uint32_t);
+struct bpf_args {
+ const uint8_t * pkt;
+ size_t wirelen;
+ size_t buflen;
+ /*
+ * The following arguments are used only by some kernel
+ * subsystems.
+ * They aren't required for classical bpf filter programs.
+ * For such programs, bpfjit generated code doesn't read
+ * those arguments at all. Note however that bpf interpreter
+ * always needs a pointer to memstore.
+ */
+ uint32_t * mem; /* pointer to external memory store */
+ void * arg; /* auxiliary argument for a copfunc */
+};
-struct bpf_args {
- const struct mbuf * pkt;
- size_t wirelen;
- size_t buflen;
- uint32_t mem[BPF_MEMWORDS];
- void * arg;
-};
+#if defined(_KERNEL) || defined(__BPF_PRIVATE)
+typedef uint32_t (*bpf_copfunc_t)(const bpf_ctx_t *, bpf_args_t *, uint32_t);
struct bpf_ctx {
const bpf_copfunc_t * copfuncs;
size_t nfuncs;
+ /*
+ * Number of external memwords, up to BPF_MAX_MEMWORDS or 0.
+ * The latter forces a switch to internal memstore with a
+ * fixed number (BPF_MEMWORDS) of memwords.
+ */
+ size_t extwords;
+ bpf_memword_init_t noinit; /* pre-initialised external memwords */
};
#endif
@@ -411,12 +455,12 @@
void bpfilterattach(int);
bpf_ctx_t *bpf_create(void);
-bpf_ctx_t *bpf_default_ctx(void);
void bpf_destroy(bpf_ctx_t *);
-int bpf_set_cop(bpf_ctx_t *, const bpf_copfunc_t *, size_t);
-u_int bpf_filter_ext(bpf_ctx_t *, const struct bpf_insn *, bpf_args_t *);
-int bpf_validate_ext(bpf_ctx_t *, const struct bpf_insn *, int);
+int bpf_set_cop(bpf_ctx_t *, const bpf_copfunc_t *, size_t);
+int bpf_set_extmem(bpf_ctx_t *, size_t, bpf_memword_init_t);
+u_int bpf_filter_ext(const bpf_ctx_t *, const struct bpf_insn *, bpf_args_t *);
+int bpf_validate_ext(const bpf_ctx_t *, const struct bpf_insn *, int);
bpfjit_func_t bpf_jit_generate(bpf_ctx_t *, void *, size_t);
void bpf_jit_freecode(bpfjit_func_t);
diff -r 2f4a1bb98e95 -r a84824baf00f sys/net/bpf_filter.c
--- a/sys/net/bpf_filter.c Tue Jun 24 10:08:45 2014 +0000
+++ b/sys/net/bpf_filter.c Tue Jun 24 10:53:30 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bpf_filter.c,v 1.61 2013/11/15 00:12:44 rmind Exp $ */
+/* $NetBSD: bpf_filter.c,v 1.62 2014/06/24 10:53:30 alnsn Exp $ */
/*-
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bpf_filter.c,v 1.61 2013/11/15 00:12:44 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bpf_filter.c,v 1.62 2014/06/24 10:53:30 alnsn Exp $");
#if 0
#if !(defined(lint) || defined(KERNEL))
@@ -56,9 +56,6 @@
#ifdef _KERNEL
-/* Default BPF context (zeroed). */
-static bpf_ctx_t bpf_def_ctx;
-
bpf_ctx_t *
bpf_create(void)
{
@@ -79,10 +76,14 @@
return 0;
}
-bpf_ctx_t *
-bpf_default_ctx(void)
+int
+bpf_set_extmem(bpf_ctx_t *bc, size_t nwords, bpf_memword_init_t preinited)
{
- return &bpf_def_ctx;
+ /* XXX check arguments */
+
+ bc->extwords = nwords;
+ bc->noinit = preinited;
+ return 0;
}
#endif
@@ -104,9 +105,13 @@
} \
}
-uint32_t m_xword (const struct mbuf *, uint32_t, int *);
-uint32_t m_xhalf (const struct mbuf *, uint32_t, int *);
-uint32_t m_xbyte (const struct mbuf *, uint32_t, int *);
+uint32_t m_xword(const struct mbuf *, uint32_t, int *);
+uint32_t m_xhalf(const struct mbuf *, uint32_t, int *);
+uint32_t m_xbyte(const struct mbuf *, uint32_t, int *);
+
+#define xword(p, k, err) m_xword((const struct mbuf *)(p), (k), (err))
+#define xhalf(p, k, err) m_xhalf((const struct mbuf *)(p), (k), (err))
+#define xbyte(p, k, err) m_xbyte((const struct mbuf *)(p), (k), (err))
uint32_t
m_xword(const struct mbuf *m, uint32_t k, int *err)
@@ -185,17 +190,20 @@
bpf_filter(const struct bpf_insn *pc, const u_char *p, u_int wirelen,
u_int buflen)
{
+ uint32_t mem[BPF_MEMWORDS];
bpf_args_t args = {
- .pkt = (const struct mbuf *)p,
+ .pkt = p,
.wirelen = wirelen,
.buflen = buflen,
+ .mem = mem,
.arg = NULL
};
- return bpf_filter_ext(&bpf_def_ctx, pc, &args);
+
+ return bpf_filter_ext(NULL, pc, &args);
}
u_int
-bpf_filter_ext(bpf_ctx_t *bc, const struct bpf_insn *pc, bpf_args_t *args)
+bpf_filter_ext(const bpf_ctx_t *bc, const struct bpf_insn *pc, bpf_args_t *args)
#else
u_int
bpf_filter(const struct bpf_insn *pc, const u_char *p, u_int wirelen,
@@ -204,15 +212,17 @@
{
uint32_t A, X, k;
#ifndef _KERNEL
+ uint32_t mem[BPF_MEMWORDS];
bpf_args_t args_store = {
- .pkt = (const struct mbuf *)p,
+ .pkt = p,
.wirelen = wirelen,
.buflen = buflen,
+ .mem = mem,
.arg = NULL
};
bpf_args_t * const args = &args_store;
#else
- const uint8_t * const p = (const uint8_t *)args->pkt;
+ const uint8_t * const p = args->pkt;
#endif
if (pc == 0) {
/*
@@ -255,7 +265,7 @@
if (args->buflen != 0)
return 0;
- A = m_xword(args->pkt, k, &merr);
Home |
Main Index |
Thread Index |
Old Index