Source-Changes-HG archive

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

[src/trunk]: src/sys Restructure the PFIL_HOOKS mechanism a bit:



details:   https://anonhg.NetBSD.org/src/rev/b3a139f59151
branches:  trunk
changeset: 499092:b3a139f59151
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Sat Nov 11 00:52:36 2000 +0000

description:
Restructure the PFIL_HOOKS mechanism a bit:
- All packets are passed to PFIL_HOOKS as they come off the wire, i.e.
  fields in protocol headers in network order, etc.
- Allow for multiple hooks to be registered, using a "key" and a "dlt".
  The "dlt" is a BPF data link type, indicating what type of header is
  present.
- INET and INET6 register with key == AF_INET or AF_INET6, and
  dlt == DLT_RAW.
- PFIL_HOOKS now take an argument for the filter hook, and mbuf **,
  an ifnet *, and a direction (PFIL_IN or PFIL_OUT), thus making them
  less IP (really, IP Filter) centric.

Maintain compatibility with IP Filter by adding wrapper functions for
IP Filter.

diffstat:

 sys/net/pfil.c            |  184 ++++++++++++++++++++++++++++++----------------
 sys/net/pfil.h            |   40 +++++++--
 sys/netinet/fil.c         |   48 +++++++++++-
 sys/netinet/ip_fil.c      |   77 +++++++++++++++++-
 sys/netinet/ip_fil.h      |    8 +-
 sys/netinet/ip_input.c    |   54 +++++++------
 sys/netinet/ip_output.c   |   69 +++++++++-------
 sys/netinet6/ip6_input.c  |   40 +++++----
 sys/netinet6/ip6_output.c |   31 ++-----
 sys/netinet6/ip6protosw.h |    4 +-
 sys/sys/protosw.h         |    8 +-
 11 files changed, 376 insertions(+), 187 deletions(-)

diffs (truncated from 996 to 300 lines):

diff -r d3e7638a1459 -r b3a139f59151 sys/net/pfil.c
--- a/sys/net/pfil.c    Sat Nov 11 00:46:36 2000 +0000
+++ b/sys/net/pfil.c    Sat Nov 11 00:52:36 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pfil.c,v 1.15 2000/02/23 02:35:42 mycroft Exp $        */
+/*     $NetBSD: pfil.c,v 1.16 2000/11/11 00:52:36 thorpej Exp $        */
 
 /*
  * Copyright (c) 1996 Matthew R. Green
@@ -40,20 +40,90 @@
 #include <net/if.h>
 #include <net/pfil.h>
 
-static void pfil_init __P((struct pfil_head *));
 static int pfil_list_add(pfil_list_t *,
-    int (*) __P((void *, int, struct ifnet *, int, struct mbuf **)), int);
+    int (*)(void *, struct mbuf **, struct ifnet *, int), void *, int);
+
 static int pfil_list_remove(pfil_list_t *,
-    int (*) __P((void *, int, struct ifnet *, int, struct mbuf **)));
+    int (*)(void *, struct mbuf **, struct ifnet *, int), void *);
+
+LIST_HEAD(, pfil_head) pfil_head_list =
+    LIST_HEAD_INITIALIZER(&pfil_head_list);
+
+/*
+ * pfil_run_hooks() runs the specified packet filter hooks.
+ */
+int
+pfil_run_hooks(struct pfil_head *ph, struct mbuf **mp, struct ifnet *ifp,
+    int dir)
+{
+       struct packet_filter_hook *pfh;
+       struct mbuf *m = *mp;
+       int rv = 0;
 
-static void
-pfil_init(ph)
-        struct pfil_head *ph;
+       for (pfh = pfil_hook_get(dir, ph); pfh != NULL;
+            pfh = TAILQ_NEXT(pfh, pfil_link)) {
+               if (pfh->pfil_func != NULL) {
+                       rv = (*pfh->pfil_func)(pfh->pfil_arg, &m, ifp, dir);
+                       if (rv != 0 || m == NULL)
+                               break;
+               }
+       }
+
+       *mp = m;
+       return (rv);
+}
+
+/*
+ * pfil_head_register() registers a pfil_head with the packet filter
+ * hook mechanism.
+ */
+int
+pfil_head_register(struct pfil_head *ph)
 {
+       struct pfil_head *lph;
+
+       for (lph = LIST_FIRST(&pfil_head_list); lph != NULL;
+            lph = LIST_NEXT(lph, ph_list)) {
+               if (lph->ph_key == ph->ph_key &&
+                   lph->ph_dlt == ph->ph_dlt)
+                       return EEXIST;
+       }
 
        TAILQ_INIT(&ph->ph_in);
        TAILQ_INIT(&ph->ph_out);
-       ph->ph_init = 1;
+
+       LIST_INSERT_HEAD(&pfil_head_list, ph, ph_list);
+
+       return (0);
+}
+
+/*
+ * pfil_head_unregister() removes a pfil_head from the packet filter
+ * hook mechanism.
+ */
+int
+pfil_head_unregister(struct pfil_head *pfh)
+{
+
+       LIST_REMOVE(pfh, ph_list);
+       return (0);
+}
+
+/*
+ * pfil_head_get() returns the pfil_head for a given key/dlt.
+ */
+struct pfil_head *
+pfil_head_get(void *key, int dlt)
+{
+       struct pfil_head *ph;
+
+       for (ph = LIST_FIRST(&pfil_head_list); ph != NULL;
+            ph = LIST_NEXT(ph, ph_list)) {
+               if (ph->ph_key == key && ph->ph_dlt == dlt)
+                       break;
+       }
+
+       return (ph);
 }
 
 /*
@@ -65,54 +135,61 @@
  *     PFIL_WAITOK     OK to call malloc with M_WAITOK.
  */
 int
-pfil_add_hook(func, flags, ph)
-       int     (*func) __P((void *, int, struct ifnet *, int,
-                            struct mbuf **));
-       int     flags;
-       struct  pfil_head       *ph;
+pfil_add_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int),
+    void *arg, int flags, struct pfil_head *ph)
 {
        int err = 0;
 
-       if (ph->ph_init == 0)
-               pfil_init(ph);
-
-       if (flags & PFIL_IN)
-               err = pfil_list_add(&ph->ph_in, func, flags & ~PFIL_OUT);
-       if (err)
-               return err;
-       if (flags & PFIL_OUT)
-               err = pfil_list_add(&ph->ph_out, func, flags & ~PFIL_IN);
-       if (err) {
-               if (flags & PFIL_IN)
-                       pfil_list_remove(&ph->ph_in, func);
-               return err;
+       if (flags & PFIL_IN) {
+               err = pfil_list_add(&ph->ph_in, func, arg, flags & ~PFIL_OUT);
+               if (err)
+                       return err;
+       }
+       if (flags & PFIL_OUT) {
+               err = pfil_list_add(&ph->ph_out, func, arg, flags & ~PFIL_IN);
+               if (err) {
+                       if (flags & PFIL_IN)
+                               pfil_list_remove(&ph->ph_in, func, arg);
+                       return err;
+               }
        }
        return 0;
 }
 
 static int
-pfil_list_add(list, func, flags)
-       pfil_list_t *list;
-       int     (*func) __P((void *, int, struct ifnet *, int,
-                            struct mbuf **));
-       int flags;
+pfil_list_add(pfil_list_t *list,
+    int (*func)(void *, struct mbuf **, struct ifnet *, int), void *arg,
+    int flags)
 {
        struct packet_filter_hook *pfh;
 
+       /*
+        * First make sure the hook is not already there.
+        */
+       for (pfh = TAILQ_FIRST(list); pfh != NULL;
+            pfh = TAILQ_NEXT(pfh, pfil_link)) {
+               if (pfh->pfil_func == func &&
+                   pfh->pfil_arg == arg)
+                       return EEXIST;
+       }
+
        pfh = (struct packet_filter_hook *)malloc(sizeof(*pfh), M_IFADDR,
-           flags & PFIL_WAITOK ? M_WAITOK : M_NOWAIT);
+           (flags & PFIL_WAITOK) ? M_WAITOK : M_NOWAIT);
        if (pfh == NULL)
                return ENOMEM;
+
        pfh->pfil_func = func;
+       pfh->pfil_arg  = arg;
+
        /*
         * insert the input list in reverse order of the output list
         * so that the same path is followed in or out of the kernel.
         */
-       
        if (flags & PFIL_IN)
                TAILQ_INSERT_HEAD(list, pfh, pfil_link);
        else
                TAILQ_INSERT_TAIL(list, pfh, pfil_link);
+
        return 0;
 }
 
@@ -121,21 +198,15 @@
  * hook list.
  */
 int
-pfil_remove_hook(func, flags, ph)
-       int     (*func) __P((void *, int, struct ifnet *, int,
-                            struct mbuf **));
-       int     flags;
-       struct  pfil_head       *ph;
+pfil_remove_hook(int (*func)(void *, struct mbuf **, struct ifnet *, int),
+    void *arg, int flags, struct pfil_head *ph)
 {
        int err = 0;
 
-       if (ph->ph_init == 0)
-               pfil_init(ph);
-
        if (flags & PFIL_IN)
-               err = pfil_list_remove(&ph->ph_in, func);
+               err = pfil_list_remove(&ph->ph_in, func, arg);
        if ((err == 0) && (flags & PFIL_OUT))
-               err = pfil_list_remove(&ph->ph_out, func);
+               err = pfil_list_remove(&ph->ph_out, func, arg);
        return err;
 }
 
@@ -144,33 +215,18 @@
  * specified list.
  */
 static int
-pfil_list_remove(list, func)
-       pfil_list_t *list;
-       int     (*func) __P((void *, int, struct ifnet *, int,
-                            struct mbuf **));
+pfil_list_remove(pfil_list_t *list,
+    int (*func)(void *, struct mbuf **, struct ifnet *, int), void *arg)
 {
        struct packet_filter_hook *pfh;
 
-       for (pfh = list->tqh_first; pfh; pfh = pfh->pfil_link.tqe_next)
-               if (pfh->pfil_func == func) {
+       for (pfh = TAILQ_FIRST(list); pfh != NULL;
+            pfh = TAILQ_NEXT(pfh, pfil_link)) {
+               if (pfh->pfil_func == func && pfh->pfil_arg == arg) {
                        TAILQ_REMOVE(list, pfh, pfil_link);
                        free(pfh, M_IFADDR);
                        return 0;
                }
+       }
        return ENOENT;
 }
-
-struct packet_filter_hook *
-pfil_hook_get(flag, ph)
-       int flag;
-       struct  pfil_head       *ph;
-{
-       if (ph->ph_init != 0)
-               switch (flag) {
-               case PFIL_IN:
-                       return (ph->ph_in.tqh_first);
-               case PFIL_OUT:
-                       return (ph->ph_out.tqh_first);
-               }
-       return NULL;
-}
diff -r d3e7638a1459 -r b3a139f59151 sys/net/pfil.h
--- a/sys/net/pfil.h    Sat Nov 11 00:46:36 2000 +0000
+++ b/sys/net/pfil.h    Sat Nov 11 00:52:36 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pfil.h,v 1.13 2000/04/19 04:46:23 itojun Exp $ */
+/*     $NetBSD: pfil.h,v 1.14 2000/11/11 00:52:36 thorpej Exp $        */
 
 /*
  * Copyright (c) 1996 Matthew R. Green
@@ -32,6 +32,7 @@
 #define _NET_PFIL_H_
 
 #include <sys/queue.h>
+#include <net/bpf.h>
 
 struct mbuf;
 struct ifnet;
@@ -42,8 +43,8 @@
  */
 struct packet_filter_hook {
         TAILQ_ENTRY(packet_filter_hook) pfil_link;
-        int    (*pfil_func) __P((void *, int, struct ifnet *, int,
-                                 struct mbuf **));
+       int     (*pfil_func)(void *, struct mbuf **, struct ifnet *, int);
+       void    *pfil_arg;
        int     pfil_flags;
 };
 
@@ -57,15 +58,36 @@
 struct pfil_head {
        pfil_list_t     ph_in;
        pfil_list_t     ph_out;
-       int             ph_init;
+       void            *ph_key;
+       int             ph_dlt;
+       LIST_ENTRY(pfil_head) ph_list;
 };
 typedef struct pfil_head pfil_head_t;
 
-struct packet_filter_hook *pfil_hook_get __P((int, struct pfil_head *));



Home | Main Index | Thread Index | Old Index