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