summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/net/pfil.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-08-21 09:39:55 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-21 10:29:40 +0200
commit2df56dbd60bb5d925d2ce0ddbdefdbe6107ea783 (patch)
treebd7bad558534db4a1f400bc38a2c9aa7ea4f411e /freebsd/sys/net/pfil.c
parentUpdate to FreeBSD head 2018-02-01 (diff)
downloadrtems-libbsd-2df56dbd60bb5d925d2ce0ddbdefdbe6107ea783.tar.bz2
Update to FreeBSD head 2018-04-01
Git mirror commit 8dfb1ccc26d1cea7e2529303003ff61f9f1784c4. Update #3472.
Diffstat (limited to 'freebsd/sys/net/pfil.c')
-rw-r--r--freebsd/sys/net/pfil.c59
1 files changed, 52 insertions, 7 deletions
diff --git a/freebsd/sys/net/pfil.c b/freebsd/sys/net/pfil.c
index e29cd5e7..65af515f 100644
--- a/freebsd/sys/net/pfil.c
+++ b/freebsd/sys/net/pfil.c
@@ -59,7 +59,8 @@ MTX_SYSINIT(pfil_heads_lock, &pfil_global_lock, "pfil_head_list lock",
static struct packet_filter_hook *pfil_chain_get(int, struct pfil_head *);
static int pfil_chain_add(pfil_chain_t *, struct packet_filter_hook *, int);
-static int pfil_chain_remove(pfil_chain_t *, pfil_func_t, void *);
+static int pfil_chain_remove(pfil_chain_t *, void *, void *);
+static int pfil_add_hook_priv(void *, void *, int, struct pfil_head *, bool);
LIST_HEAD(pfilheadhead, pfil_head);
VNET_DEFINE(struct pfilheadhead, pfil_head_list);
@@ -97,7 +98,7 @@ VNET_DEFINE(struct rmlock, pfil_lock);
*/
int
pfil_run_hooks(struct pfil_head *ph, struct mbuf **mp, struct ifnet *ifp,
- int dir, struct inpcb *inp)
+ int dir, int flags, struct inpcb *inp)
{
struct rm_priotracker rmpt;
struct packet_filter_hook *pfh;
@@ -108,6 +109,12 @@ pfil_run_hooks(struct pfil_head *ph, struct mbuf **mp, struct ifnet *ifp,
KASSERT(ph->ph_nhooks >= 0, ("Pfil hook count dropped < 0"));
for (pfh = pfil_chain_get(dir, ph); pfh != NULL;
pfh = TAILQ_NEXT(pfh, pfil_chain)) {
+ if (pfh->pfil_func_flags != NULL) {
+ rv = (*pfh->pfil_func_flags)(pfh->pfil_arg, &m, ifp,
+ dir, flags, inp);
+ if (rv != 0 || m == NULL)
+ break;
+ }
if (pfh->pfil_func != NULL) {
rv = (*pfh->pfil_func)(pfh->pfil_arg, &m, ifp, dir,
inp);
@@ -260,6 +267,21 @@ pfil_head_get(int type, u_long val)
}
/*
+ * pfil_add_hook_flags() adds a function to the packet filter hook. the
+ * flags are:
+ * PFIL_IN call me on incoming packets
+ * PFIL_OUT call me on outgoing packets
+ * PFIL_ALL call me on all of the above
+ * PFIL_WAITOK OK to call malloc with M_WAITOK.
+ */
+int
+pfil_add_hook_flags(pfil_func_flags_t func, void *arg, int flags,
+ struct pfil_head *ph)
+{
+ return (pfil_add_hook_priv(func, arg, flags, ph, true));
+}
+
+/*
* pfil_add_hook() adds a function to the packet filter hook. the
* flags are:
* PFIL_IN call me on incoming packets
@@ -270,6 +292,13 @@ pfil_head_get(int type, u_long val)
int
pfil_add_hook(pfil_func_t func, void *arg, int flags, struct pfil_head *ph)
{
+ return (pfil_add_hook_priv(func, arg, flags, ph, false));
+}
+
+static int
+pfil_add_hook_priv(void *func, void *arg, int flags,
+ struct pfil_head *ph, bool hasflags)
+{
struct packet_filter_hook *pfh1 = NULL;
struct packet_filter_hook *pfh2 = NULL;
int err;
@@ -292,7 +321,8 @@ pfil_add_hook(pfil_func_t func, void *arg, int flags, struct pfil_head *ph)
}
PFIL_WLOCK(ph);
if (flags & PFIL_IN) {
- pfh1->pfil_func = func;
+ pfh1->pfil_func_flags = hasflags ? func : NULL;
+ pfh1->pfil_func = hasflags ? NULL : func;
pfh1->pfil_arg = arg;
err = pfil_chain_add(&ph->ph_in, pfh1, flags & ~PFIL_OUT);
if (err)
@@ -300,7 +330,8 @@ pfil_add_hook(pfil_func_t func, void *arg, int flags, struct pfil_head *ph)
ph->ph_nhooks++;
}
if (flags & PFIL_OUT) {
- pfh2->pfil_func = func;
+ pfh2->pfil_func_flags = hasflags ? func : NULL;
+ pfh2->pfil_func = hasflags ? NULL : func;
pfh2->pfil_arg = arg;
err = pfil_chain_add(&ph->ph_out, pfh2, flags & ~PFIL_IN);
if (err) {
@@ -323,6 +354,17 @@ error:
}
/*
+ * pfil_remove_hook_flags removes a specific function from the packet filter hook
+ * chain.
+ */
+int
+pfil_remove_hook_flags(pfil_func_flags_t func, void *arg, int flags,
+ struct pfil_head *ph)
+{
+ return (pfil_remove_hook((pfil_func_t)func, arg, flags, ph));
+}
+
+/*
* pfil_remove_hook removes a specific function from the packet filter hook
* chain.
*/
@@ -358,7 +400,9 @@ pfil_chain_add(pfil_chain_t *chain, struct packet_filter_hook *pfh1, int flags)
* First make sure the hook is not already there.
*/
TAILQ_FOREACH(pfh, chain, pfil_chain)
- if (pfh->pfil_func == pfh1->pfil_func &&
+ if (((pfh->pfil_func != NULL && pfh->pfil_func == pfh1->pfil_func) ||
+ (pfh->pfil_func_flags != NULL &&
+ pfh->pfil_func_flags == pfh1->pfil_func_flags)) &&
pfh->pfil_arg == pfh1->pfil_arg)
return (EEXIST);
@@ -377,12 +421,13 @@ pfil_chain_add(pfil_chain_t *chain, struct packet_filter_hook *pfh1, int flags)
* Internal: Remove a pfil hook from a hook chain.
*/
static int
-pfil_chain_remove(pfil_chain_t *chain, pfil_func_t func, void *arg)
+pfil_chain_remove(pfil_chain_t *chain, void *func, void *arg)
{
struct packet_filter_hook *pfh;
TAILQ_FOREACH(pfh, chain, pfil_chain)
- if (pfh->pfil_func == func && pfh->pfil_arg == arg) {
+ if ((pfh->pfil_func == func || pfh->pfil_func_flags == func) &&
+ pfh->pfil_arg == arg) {
TAILQ_REMOVE(chain, pfh, pfil_chain);
free(pfh, M_IFADDR);
return (0);