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