Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Implement BPF_COP/BPF_COPX instructions in the misc category...



details:   https://anonhg.NetBSD.org/src/rev/5d2333e1ca36
branches:  trunk
changeset: 789639:5d2333e1ca36
user:      rmind <rmind%NetBSD.org@localhost>
date:      Thu Aug 29 14:25:40 2013 +0000

description:
Implement BPF_COP/BPF_COPX instructions in the misc category (BPF_MISC)
which add a capability to call external functions in a predetermined way.

It can be thought as a BPF "coprocessor" -- a generic mechanism to offload
more complex packet inspection operations.  There is no default coprocessor
and this functionality is not targeted to the /dev/bpf.  This is primarily
targeted to the kernel subsystems, therefore there is no way to set a custom
coprocessor at the userlevel.

Discussed on: tech-net@
OK: core@

diffstat:

 share/man/man4/bpf.4               |  12 ++++++-
 sys/external/bsd/ipf/netinet/fil.c |   9 +++-
 sys/net/bpf.c                      |   7 ++-
 sys/net/bpf.h                      |  25 +++++++++++--
 sys/net/bpf_filter.c               |  69 ++++++++++++++++++++++++++++++++++++-
 sys/net/if_ppp.c                   |  20 +++++-----
 sys/net/npf/npf_ruleset.c          |   7 ++-
 7 files changed, 124 insertions(+), 25 deletions(-)

diffs (truncated from 334 to 300 lines):

diff -r 42cb11194245 -r 5d2333e1ca36 share/man/man4/bpf.4
--- a/share/man/man4/bpf.4      Thu Aug 29 09:46:04 2013 +0000
+++ b/share/man/man4/bpf.4      Thu Aug 29 14:25:40 2013 +0000
@@ -1,6 +1,6 @@
 .\" -*- nroff -*-
 .\"
-.\"    $NetBSD: bpf.4,v 1.51 2012/10/28 20:19:30 alnsn Exp $
+.\"    $NetBSD: bpf.4,v 1.52 2013/08/29 14:25:41 rmind Exp $
 .\"
 .\" Copyright (c) 1990, 1991, 1992, 1993, 1994
 .\"    The Regents of the University of California.  All rights reserved.
@@ -630,6 +630,16 @@
 .It Sy BPF_MISC+BPF_TAX Ta X \*[Lt]- A
 .It Sy BPF_MISC+BPF_TXA Ta A \*[Lt]- X
 .El
+.Pp
+Also, two instructions to call a "coprocessor" if initialized by the kernel
+component.  There is no coprocessor by default.
+.Bl -column "BPF_MISC+BPF_COP" "A \*[Lt]- funcs[X](...)" -offset indent
+.It Sy BPF_MISC+BPF_COP Ta A \*[Lt]- funcs[k](..)
+.It Sy BPF_MISC+BPF_COPX Ta A \*[Lt]- funcs[X](..)
+.El
+.Pp
+If the coprocessor is not set or the function index is out of range, these
+instructions will abort the program and return zero.
 .El
 .Pp
 The BPF interface provides the following macros to facilitate
diff -r 42cb11194245 -r 5d2333e1ca36 sys/external/bsd/ipf/netinet/fil.c
--- a/sys/external/bsd/ipf/netinet/fil.c        Thu Aug 29 09:46:04 2013 +0000
+++ b/sys/external/bsd/ipf/netinet/fil.c        Thu Aug 29 14:25:40 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fil.c,v 1.8 2013/01/09 13:23:20 christos Exp $ */
+/*     $NetBSD: fil.c,v 1.9 2013/08/29 14:25:40 rmind Exp $    */
 
 /*
  * Copyright (C) 2012 by Darren Reed.
@@ -138,7 +138,7 @@
 #if !defined(lint)
 #if defined(__NetBSD__)
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fil.c,v 1.8 2013/01/09 13:23:20 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fil.c,v 1.9 2013/08/29 14:25:40 rmind Exp $");
 #else
 static const char sccsid[] = "@(#)fil.c        1.36 6/5/96 (C) 1993-2000 Darren Reed";
 static const char rcsid[] = "@(#)Id: fil.c,v 1.1.1.2 2012/07/22 13:45:07 darrenr Exp $";
@@ -2405,8 +2405,13 @@
                                continue;
                        mc = (u_char *)fin->fin_m;
                        wlen = fin->fin_dlen + fin->fin_hlen;
+#if defined(__NetBSD__)
+                       if (!bpf_filter(bpf_def_ctx, fr->fr_data, mc, wlen, 0))
+                               continue;
+#else
                        if (!bpf_filter(fr->fr_data, mc, wlen, 0))
                                continue;
+#endif
                        break;
                    }
 #endif
diff -r 42cb11194245 -r 5d2333e1ca36 sys/net/bpf.c
--- a/sys/net/bpf.c     Thu Aug 29 09:46:04 2013 +0000
+++ b/sys/net/bpf.c     Thu Aug 29 14:25:40 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bpf.c,v 1.173 2012/10/27 22:36:14 alnsn Exp $  */
+/*     $NetBSD: bpf.c,v 1.174 2013/08/29 14:25:41 rmind Exp $  */
 
 /*
  * Copyright (c) 1990, 1991, 1993
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.173 2012/10/27 22:36:14 alnsn Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.174 2013/08/29 14:25:41 rmind Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_bpf.h"
@@ -1382,7 +1382,8 @@
                if (d->bd_jitcode != NULL)
                        slen = d->bd_jitcode(pkt, pktlen, buflen);
                else
-                       slen = bpf_filter(d->bd_filter, pkt, pktlen, buflen);
+                       slen = bpf_filter(bpf_def_ctx, d->bd_filter,
+                           pkt, pktlen, buflen);
 
                if (!slen) {
                        continue;
diff -r 42cb11194245 -r 5d2333e1ca36 sys/net/bpf.h
--- a/sys/net/bpf.h     Thu Aug 29 09:46:04 2013 +0000
+++ b/sys/net/bpf.h     Thu Aug 29 14:25:40 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bpf.h,v 1.59 2012/03/15 00:57:56 christos Exp $        */
+/*     $NetBSD: bpf.h,v 1.60 2013/08/29 14:25:41 rmind Exp $   */
 
 /*
  * Copyright (c) 1990, 1991, 1993
@@ -254,6 +254,8 @@
 /* misc */
 #define BPF_MISCOP(code) ((code) & 0xf8)
 #define                BPF_TAX         0x00
+#define                BPF_COP         0x20
+#define                BPF_COPX        0x40
 #define                BPF_TXA         0x80
 
 /*
@@ -378,10 +380,25 @@
 
 void    bpfilterattach(int);
 
-#endif
+struct bpf_ctx;
+typedef struct bpf_ctx bpf_ctx_t;
+typedef uint32_t (*bpf_copfunc_t)(const struct mbuf *, uint32_t, uint32_t *);
+extern bpf_ctx_t *bpf_def_ctx;
+
+bpf_ctx_t *bpf_create(void);
+void   bpf_destroy(bpf_ctx_t *);
 
-int     bpf_validate(const struct bpf_insn *, int);
-u_int   bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int);
+int    bpf_set_cop(bpf_ctx_t *, const bpf_copfunc_t *, size_t);
+u_int  bpf_filter(bpf_ctx_t *, const struct bpf_insn *,
+           const u_char *, u_int, u_int);
+int    bpf_validate(const struct bpf_insn *, int);
+
+#else
+
+int    bpf_validate(const struct bpf_insn *, int);
+u_int  bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int);
+
+#endif
 
 __END_DECLS
 
diff -r 42cb11194245 -r 5d2333e1ca36 sys/net/bpf_filter.c
--- a/sys/net/bpf_filter.c      Thu Aug 29 09:46:04 2013 +0000
+++ b/sys/net/bpf_filter.c      Thu Aug 29 14:25:40 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bpf_filter.c,v 1.55 2012/10/27 22:36:14 alnsn Exp $    */
+/*     $NetBSD: bpf_filter.c,v 1.56 2013/08/29 14:25:41 rmind 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.55 2012/10/27 22:36:14 alnsn Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bpf_filter.c,v 1.56 2013/08/29 14:25:41 rmind Exp $");
 
 #if 0
 #if !(defined(lint) || defined(KERNEL))
@@ -51,6 +51,41 @@
 #include <sys/kmem.h>
 #include <sys/endian.h>
 
+#include <net/bpf.h>
+
+#ifdef _KERNEL
+
+struct bpf_ctx {
+       const bpf_copfunc_t *   copfuncs;
+       size_t                  nfuncs;
+};
+
+/* Default BPF context (zeroed). */
+static bpf_ctx_t               bpf_def_ctx1;
+bpf_ctx_t *                    bpf_def_ctx = &bpf_def_ctx1;
+
+bpf_ctx_t *
+bpf_create(void)
+{
+       return kmem_zalloc(sizeof(bpf_ctx_t), KM_SLEEP);
+}
+
+void
+bpf_destroy(bpf_ctx_t *bc)
+{
+       kmem_free(bc, sizeof(bpf_ctx_t));
+}
+
+int
+bpf_set_cop(bpf_ctx_t *bc, const bpf_copfunc_t *funcs, size_t n)
+{
+       bc->copfuncs = funcs;
+       bc->nfuncs = n;
+       return 0;
+}
+
+#endif
+
 #define EXTRACT_SHORT(p)       be16dec(p)
 #define EXTRACT_LONG(p)                be32dec(p)
 
@@ -143,13 +178,23 @@
  * wirelen is the length of the original packet
  * buflen is the amount of data present
  */
+#ifdef _KERNEL
+u_int
+bpf_filter(bpf_ctx_t *bc, const struct bpf_insn *pc, const u_char *p,
+    u_int wirelen, u_int buflen)
+#else
 u_int
 bpf_filter(const struct bpf_insn *pc, const u_char *p, u_int wirelen,
     u_int buflen)
+#endif
 {
        uint32_t A, X, k;
        uint32_t mem[BPF_MEMWORDS];
 
+#ifdef _KERNEL
+       KASSERT(bc != NULL);
+#endif
+
        if (pc == 0) {
                /*
                 * No filter means accept all.
@@ -465,6 +510,26 @@
                case BPF_MISC|BPF_TXA:
                        A = X;
                        continue;
+
+               case BPF_MISC|BPF_COP:
+#ifdef _KERNEL
+                       if (pc->k < bc->nfuncs) {
+                               const bpf_copfunc_t fn = bc->copfuncs[pc->k];
+                               A = fn((const struct mbuf *)p, A, mem);
+                               continue;
+                       }
+#endif
+                       return 0;
+
+               case BPF_MISC|BPF_COPX:
+#ifdef _KERNEL
+                       if (X < bc->nfuncs) {
+                               const bpf_copfunc_t fn = bc->copfuncs[X];
+                               A = fn((const struct mbuf *)p, A, mem);
+                               continue;
+                       }
+#endif
+                       return 0;
                }
        }
 }
diff -r 42cb11194245 -r 5d2333e1ca36 sys/net/if_ppp.c
--- a/sys/net/if_ppp.c  Thu Aug 29 09:46:04 2013 +0000
+++ b/sys/net/if_ppp.c  Thu Aug 29 14:25:40 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_ppp.c,v 1.138 2012/11/25 09:06:43 mbalmer Exp $     */
+/*     $NetBSD: if_ppp.c,v 1.139 2013/08/29 14:25:41 rmind Exp $       */
 /*     Id: if_ppp.c,v 1.6 1997/03/04 03:33:00 paulus Exp       */
 
 /*
@@ -102,7 +102,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ppp.c,v 1.138 2012/11/25 09:06:43 mbalmer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ppp.c,v 1.139 2013/08/29 14:25:41 rmind Exp $");
 
 #include "ppp.h"
 
@@ -946,8 +946,8 @@
         * but only if it is a data packet.
         */
        if (sc->sc_pass_filt_out.bf_insns != 0
-           && bpf_filter(sc->sc_pass_filt_out.bf_insns, (u_char *) m0,
-                         len, 0) == 0) {
+           && bpf_filter(bpf_def_ctx, sc->sc_pass_filt_out.bf_insns,
+                         (u_char *)m0, len, 0) == 0) {
            error = 0;          /* drop this packet */
            goto bad;
        }
@@ -956,8 +956,8 @@
         * Update the time we sent the most recent packet.
         */
        if (sc->sc_active_filt_out.bf_insns == 0
-           || bpf_filter(sc->sc_active_filt_out.bf_insns, (u_char *) m0,
-                         len, 0))
+           || bpf_filter(bpf_def_ctx, sc->sc_active_filt_out.bf_insns,
+                         (u_char *)m0, len, 0))
            sc->sc_last_sent = time_second;
 #else
        /*
@@ -1584,15 +1584,15 @@
         * if it counts as link activity.
         */
        if (sc->sc_pass_filt_in.bf_insns != 0
-           && bpf_filter(sc->sc_pass_filt_in.bf_insns, (u_char *) m,
-                         ilen, 0) == 0) {
+           && bpf_filter(bpf_def_ctx, sc->sc_pass_filt_in.bf_insns,
+                         (u_char *)m, ilen, 0) == 0) {
            /* drop this packet */
            m_freem(m);
            return;
        }
        if (sc->sc_active_filt_in.bf_insns == 0
-           || bpf_filter(sc->sc_active_filt_in.bf_insns, (u_char *) m,



Home | Main Index | Thread Index | Old Index