Index: sys/net/pfil.h =================================================================== --- sys/net/pfil.h +++ sys/net/pfil.h @@ -194,6 +194,10 @@ /* Public functions to run the packet inspection by inspection points. */ int pfil_run_hooks(struct pfil_head *, pfil_packet_t, struct ifnet *, int, struct inpcb *inp); +int pfil_run_hooks_in(pfil_chain_t *, pfil_packet_t, struct ifnet *, int, + struct inpcb *inp); +int pfil_run_hooks_out(pfil_chain_t *, pfil_packet_t, struct ifnet *, int, + struct inpcb *inp); /* * Minimally exposed structure to avoid function call in case of absence * of any filters by protocols and macros to do the check. Index: sys/net/pfil.c =================================================================== --- sys/net/pfil.c +++ sys/net/pfil.c @@ -198,6 +198,43 @@ return (rv); } +static __always_inline int +pfil_run_hooks_simple(pfil_chain_t *pch, pfil_packet_t p, struct ifnet *ifp, + int flags, struct inpcb *inp) +{ + struct pfil_link *link; + pfil_return_t rv; + + NET_EPOCH_ASSERT(); + + KASSERT(flags == PFIL_IN || flags == PFIL_OUT, + ("%s: unsupported flags %d", flags)); + + rv = PFIL_PASS; + CK_STAILQ_FOREACH(link, pch, link_chain) { + rv = (*link->link_func)(p, ifp, flags, link->link_ruleset, inp); + if (rv == PFIL_DROPPED || rv == PFIL_CONSUMED) + break; + } + return (rv); +} + +int +pfil_run_hooks_in(struct pfil_head *head, pfil_packet_t p, struct ifnet *ifp, + int flags, struct inpcb *inp) +{ + + return (pfil_run_hooks_simple(&head->head_in, p, ifp, PFIL_IN, inp)); +} + +int +pfil_run_hooks_in(struct pfil_head *head, pfil_packet_t p, struct ifnet *ifp, + int flags, struct inpcb *inp) +{ + + return (pfil_run_hooks_simple(&head->head_out, p, ifp, PFIL_OUT, inp)); +} + /* * pfil_head_register() registers a pfil_head with the packet filter hook * mechanism.