diff --git a/sys/dev/cxgbe/t4_sge.c b/sys/dev/cxgbe/t4_sge.c --- a/sys/dev/cxgbe/t4_sge.c +++ b/sys/dev/cxgbe/t4_sge.c @@ -1998,8 +1998,7 @@ sc->params.sge.fl_pktshift; frame = sd->cl + fl->rx_offset + sc->params.sge.fl_pktshift; CURVNET_SET_QUIET(ifp->if_vnet); - rc = pfil_run_hooks(vi->pfil, frame, ifp, - slen | PFIL_MEMPTR | PFIL_IN, NULL); + rc = pfil_mem_in(vi->pfil, frame, slen, ifp, &m0); CURVNET_RESTORE(); if (rc == PFIL_DROPPED || rc == PFIL_CONSUMED) { skip_fl_payload(sc, fl, plen); @@ -2007,7 +2006,6 @@ } if (rc == PFIL_REALLOCED) { skip_fl_payload(sc, fl, plen); - m0 = pfil_mem2mbuf(frame); goto have_mbuf; } } diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c b/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c --- a/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c +++ b/sys/dev/mlx5/mlx5_en/mlx5_en_rx.c @@ -536,9 +536,8 @@ } if (pfil != NULL && PFIL_HOOKED_IN(pfil)) { seglen = MIN(byte_cnt, MLX5E_MAX_RX_BYTES); - rv = pfil_run_hooks(rq->channel->priv->pfil, - rq->mbuf[wqe_counter].data, rq->ifp, - seglen | PFIL_MEMPTR | PFIL_IN, NULL); + rv = pfil_mem_in(rq->channel->priv->pfil, + rq->mbuf[wqe_counter].data, seglen, rq->ifp, &mb); switch (rv) { case PFIL_DROPPED: @@ -556,7 +555,6 @@ * and receive the new mbuf allocated * by the Filter */ - mb = pfil_mem2mbuf(rq->mbuf[wqe_counter].data); goto rx_common; default: /* diff --git a/sys/net/iflib.c b/sys/net/iflib.c --- a/sys/net/iflib.c +++ b/sys/net/iflib.c @@ -2732,8 +2732,7 @@ payload = *sd->ifsd_cl; payload += ri->iri_pad; len = ri->iri_len - ri->iri_pad; - *pf_rv = pfil_run_hooks(rxq->pfil, payload, ri->iri_ifp, - len | PFIL_MEMPTR | PFIL_IN, NULL); + *pf_rv = pfil_mem_in(rxq->pfil, payload, len, ri->iri_ifp, &m); switch (*pf_rv) { case PFIL_DROPPED: case PFIL_CONSUMED: @@ -2746,8 +2745,8 @@ case PFIL_REALLOCED: /* * The filter copied it. Everything is recycled. + * 'm' points at new mbuf. */ - m = pfil_mem2mbuf(payload); unload = 0; break; case PFIL_PASS: diff --git a/sys/net/pfil.h b/sys/net/pfil.h --- a/sys/net/pfil.h +++ b/sys/net/pfil.h @@ -82,41 +82,16 @@ #define PFIL_OUT 0x00020000 /* UNUSED 0x00040000 */ #define PFIL_DIR(f) ((f) & (PFIL_IN|PFIL_OUT)) -#define PFIL_MEMPTR 0x00080000 #define PFIL_HEADPTR 0x00100000 #define PFIL_HOOKPTR 0x00200000 #define PFIL_APPEND 0x00400000 #define PFIL_UNLINK 0x00800000 -#define PFIL_LENMASK 0x0000ffff -#define PFIL_LENGTH(f) ((f) & PFIL_LENMASK) #ifdef _KERNEL struct mbuf; struct ifnet; struct inpcb; -typedef union { - struct mbuf **m; - void *mem; - uintptr_t __ui; -} pfil_packet_t __attribute__((__transparent_union__)); - -static inline pfil_packet_t -pfil_packet_align(pfil_packet_t p) -{ - - return ((pfil_packet_t ) (((uintptr_t)(p).mem + - (_Alignof(void *) - 1)) & - _Alignof(void *))); -} - -static inline struct mbuf * -pfil_mem2mbuf(void *v) -{ - - return (*(struct mbuf **) (((uintptr_t)(v) + - (_Alignof(void *) - 1)) & - _Alignof(void *))); -} - typedef enum { PFIL_PASS = 0, PFIL_DROPPED, @@ -124,8 +99,11 @@ PFIL_REALLOCED, } pfil_return_t; -typedef pfil_return_t (*pfil_func_t)(pfil_packet_t, struct ifnet *, int, +typedef pfil_return_t (*pfil_mbuf_chk_t)(struct mbuf **, struct ifnet *, int, void *, struct inpcb *); +typedef pfil_return_t (*pfil_mem_chk_t)(void *, u_int, int, struct ifnet *, + void *, struct mbuf **); + /* * A pfil head is created by a packet intercept point. * @@ -142,14 +120,15 @@ /* * Give us a chance to modify pfil_xxx_args structures in future. */ -#define PFIL_VERSION 1 +#define PFIL_VERSION 2 /* Argument structure used by packet filters to register themselves. */ struct pfil_hook_args { int pa_version; int pa_flags; enum pfil_types pa_type; - pfil_func_t pa_func; + pfil_mbuf_chk_t pa_mbuf_chk; + pfil_mem_chk_t pa_mem_chk; void *pa_ruleset; const char *pa_modname; const char *pa_rulname; @@ -192,12 +171,15 @@ void pfil_head_unregister(pfil_head_t); /* Public functions to run the packet inspection by inspection points. */ -int pfil_run_hooks(struct pfil_head *, pfil_packet_t, struct ifnet *, int, +int pfil_mem_in(struct pfil_head *, void *, u_int, struct ifnet *, + struct mbuf **); +int pfil_mem_out(struct pfil_head *, void *, u_int, struct ifnet *, + struct mbuf **); +int pfil_mbuf_in(struct pfil_head *, struct mbuf **, struct ifnet *, struct inpcb *inp); -int pfil_mbuf_in(struct pfil_head *, pfil_packet_t, struct ifnet *, - struct inpcb *inp); -int pfil_mbuf_out(struct pfil_head *, pfil_packet_t, struct ifnet *, +int pfil_mbuf_out(struct pfil_head *, struct mbuf **, struct ifnet *, 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. @@ -209,10 +191,5 @@ #define PFIL_HOOKED_IN(p) (((struct _pfil_head *)(p))->head_nhooksin > 0) #define PFIL_HOOKED_OUT(p) (((struct _pfil_head *)(p))->head_nhooksout > 0) -/* - * Alloc mbuf to be used instead of memory pointer. - */ -int pfil_realloc(pfil_packet_t *, int, struct ifnet *); - #endif /* _KERNEL */ #endif /* _NET_PFIL_H_ */ diff --git a/sys/net/pfil.c b/sys/net/pfil.c --- a/sys/net/pfil.c +++ b/sys/net/pfil.c @@ -70,7 +70,8 @@ #define PFIL_LOCK_ASSERT() mtx_assert(&pfil_lock, MA_OWNED) struct pfil_hook { - pfil_func_t hook_func; + pfil_mbuf_chk_t hook_mbuf_chk; + pfil_mem_chk_t hook_mem_chk; void *hook_ruleset; int hook_flags; int hook_links; @@ -82,7 +83,8 @@ struct pfil_link { CK_STAILQ_ENTRY(pfil_link) link_chain; - pfil_func_t link_func; + pfil_mbuf_chk_t link_mbuf_chk; + pfil_mem_chk_t link_mem_chk; void *link_ruleset; int link_flags; struct pfil_hook *link_hook; @@ -114,92 +116,86 @@ static struct pfil_link *pfil_link_remove(pfil_chain_t *, pfil_hook_t ); static void pfil_link_free(epoch_context_t); -int -pfil_realloc(pfil_packet_t *p, int flags, struct ifnet *ifp) -{ - struct mbuf *m; - - MPASS(flags & PFIL_MEMPTR); - - if ((m = m_devget(p->mem, PFIL_LENGTH(flags), 0, ifp, NULL)) == NULL) - return (ENOMEM); - *p = pfil_packet_align(*p); - *p->m = m; - - return (0); -} - +/* + * To couple a filtering point that provides memory pointer with a filter that + * works on mbufs only. + */ static __noinline int -pfil_fake_mbuf(pfil_func_t func, pfil_packet_t *p, struct ifnet *ifp, int flags, - void *ruleset, struct inpcb *inp) +pfil_fake_mbuf(pfil_mbuf_chk_t func, void *mem, u_int len, struct ifnet *ifp, + int flags, void *ruleset, struct mbuf **mp) { - struct mbuf m, *mp; + struct mbuf m; pfil_return_t rv; (void)m_init(&m, M_NOWAIT, MT_DATA, M_NOFREE | M_PKTHDR); - m_extadd(&m, p->mem, PFIL_LENGTH(flags), NULL, NULL, NULL, 0, - EXT_RXRING); - m.m_len = m.m_pkthdr.len = PFIL_LENGTH(flags); - mp = &m; - flags &= ~(PFIL_MEMPTR | PFIL_LENMASK); - - rv = func(&mp, ifp, flags, ruleset, inp); - if (rv == PFIL_PASS && mp != &m) { + m_extadd(&m, mem, len, NULL, NULL, NULL, 0, EXT_RXRING); + m.m_len = m.m_pkthdr.len = len; + *mp = &m; + + rv = func(mp, ifp, flags, ruleset, NULL); + if (rv == PFIL_PASS && *mp != &m) { /* * Firewalls that need pfil_fake_mbuf() most likely don't * know they need return PFIL_REALLOCED. */ rv = PFIL_REALLOCED; - *p = pfil_packet_align(*p); - *p->m = mp; } return (rv); } -/* - * pfil_run_hooks() runs the specified packet filter hook chain. - */ -int -pfil_run_hooks(struct pfil_head *head, pfil_packet_t p, struct ifnet *ifp, - int flags, struct inpcb *inp) +static __always_inline int +pfil_mem_common(pfil_chain_t *pch, void *mem, u_int len, int flags, + struct ifnet *ifp, struct mbuf **m) { - pfil_chain_t *pch; struct pfil_link *link; pfil_return_t rv; bool realloc = false; NET_EPOCH_ASSERT(); - - if (PFIL_DIR(flags) == PFIL_IN) - pch = &head->head_in; - else if (__predict_true(PFIL_DIR(flags) == PFIL_OUT)) - pch = &head->head_out; - else - panic("%s: bogus flags %d", __func__, flags); + KASSERT(flags == PFIL_IN || flags == PFIL_OUT, + ("%s: unsupported flags %d", __func__, flags)); rv = PFIL_PASS; CK_STAILQ_FOREACH(link, pch, link_chain) { - if ((flags & PFIL_MEMPTR) && !(link->link_flags & PFIL_MEMPTR)) - rv = pfil_fake_mbuf(link->link_func, &p, ifp, flags, - link->link_ruleset, inp); + if (__predict_true(link->link_mem_chk != NULL && !realloc)) + rv = link->link_mem_chk(mem, len, flags, ifp, + link->link_ruleset, m); + else if (!realloc) + rv = pfil_fake_mbuf(link->link_mbuf_chk, mem, len, ifp, + flags, link->link_ruleset, m); else - rv = (*link->link_func)(p, ifp, flags, - link->link_ruleset, inp); + rv = link->link_mbuf_chk(m, ifp, flags, + link->link_ruleset, NULL); + if (rv == PFIL_DROPPED || rv == PFIL_CONSUMED) break; - else if (rv == PFIL_REALLOCED) { - flags &= ~(PFIL_MEMPTR | PFIL_LENMASK); + else if (rv == PFIL_REALLOCED) realloc = true; - } } if (realloc && rv == PFIL_PASS) rv = PFIL_REALLOCED; return (rv); } +int +pfil_mem_in(struct pfil_head *head, void *mem, u_int len, struct ifnet *ifp, + struct mbuf **m) +{ + + return (pfil_mem_common(&head->head_in, mem, len, PFIL_IN, ifp, m)); +} + +int +pfil_mem_out(struct pfil_head *head, void *mem, u_int len, struct ifnet *ifp, + struct mbuf **m) +{ + + return (pfil_mem_common(&head->head_out, mem, len, PFIL_OUT, ifp, m)); +} + static __always_inline int -pfil_mbuf_common(pfil_chain_t *pch, pfil_packet_t p, struct ifnet *ifp, +pfil_mbuf_common(pfil_chain_t *pch, struct mbuf **m, struct ifnet *ifp, int flags, struct inpcb *inp) { struct pfil_link *link; @@ -211,7 +207,8 @@ rv = PFIL_PASS; CK_STAILQ_FOREACH(link, pch, link_chain) { - rv = (*link->link_func)(p, ifp, flags, link->link_ruleset, inp); + rv = link->link_mbuf_chk(m, ifp, flags, link->link_ruleset, + inp); if (rv == PFIL_DROPPED || rv == PFIL_CONSUMED) break; } @@ -219,19 +216,19 @@ } int -pfil_mbuf_in(struct pfil_head *head, pfil_packet_t p, struct ifnet *ifp, +pfil_mbuf_in(struct pfil_head *head, struct mbuf **m, struct ifnet *ifp, struct inpcb *inp) { - return (pfil_mbuf_common(&head->head_in, p, ifp, PFIL_IN, inp)); + return (pfil_mbuf_common(&head->head_in, m, ifp, PFIL_IN, inp)); } int -pfil_mbuf_out(struct pfil_head *head, pfil_packet_t p, struct ifnet *ifp, +pfil_mbuf_out(struct pfil_head *head, struct mbuf **m, struct ifnet *ifp, struct inpcb *inp) { - return (pfil_mbuf_common(&head->head_out, p, ifp, PFIL_OUT, inp)); + return (pfil_mbuf_common(&head->head_out, m, ifp, PFIL_OUT, inp)); } /* @@ -298,7 +295,8 @@ MPASS(pa->pa_version == PFIL_VERSION); hook = malloc(sizeof(struct pfil_hook), M_PFIL, M_WAITOK | M_ZERO); - hook->hook_func = pa->pa_func; + hook->hook_mbuf_chk = pa->pa_mbuf_chk; + hook->hook_mem_chk = pa->pa_mem_chk; hook->hook_ruleset = pa->pa_ruleset; hook->hook_flags = pa->pa_flags; hook->hook_type = pa->pa_type; @@ -416,7 +414,8 @@ if (pa->pa_flags & PFIL_IN) { in->link_hook = hook; - in->link_func = hook->hook_func; + in->link_mbuf_chk = hook->hook_mbuf_chk; + in->link_mem_chk = hook->hook_mem_chk; in->link_flags = hook->hook_flags; in->link_ruleset = hook->hook_ruleset; if (pa->pa_flags & PFIL_APPEND) @@ -428,7 +427,8 @@ } if (pa->pa_flags & PFIL_OUT) { out->link_hook = hook; - out->link_func = hook->hook_func; + out->link_mbuf_chk = hook->hook_mbuf_chk; + out->link_mem_chk = hook->hook_mem_chk; out->link_flags = hook->hook_flags; out->link_ruleset = hook->hook_ruleset; if (pa->pa_flags & PFIL_APPEND) diff --git a/sys/netinet/siftr.c b/sys/netinet/siftr.c --- a/sys/netinet/siftr.c +++ b/sys/netinet/siftr.c @@ -1139,18 +1139,16 @@ static int siftr_pfil(int action) { - struct pfil_hook_args pha; - struct pfil_link_args pla; - - pha.pa_version = PFIL_VERSION; - pha.pa_flags = PFIL_IN | PFIL_OUT; - pha.pa_modname = "siftr"; - pha.pa_ruleset = NULL; - pha.pa_rulname = "default"; - - pla.pa_version = PFIL_VERSION; - pla.pa_flags = PFIL_IN | PFIL_OUT | - PFIL_HEADPTR | PFIL_HOOKPTR; + struct pfil_hook_args pha = { + .pa_version = PFIL_VERSION, + .pa_flags = PFIL_IN | PFIL_OUT, + .pa_modname = "siftr", + .pa_rulname = "default", + }; + struct pfil_link_args pla = { + .pa_version = PFIL_VERSION, + .pa_flags = PFIL_IN | PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR, + }; VNET_ITERATOR_DECL(vnet_iter); @@ -1159,14 +1157,14 @@ CURVNET_SET(vnet_iter); if (action == HOOK) { - pha.pa_func = siftr_chkpkt; + pha.pa_mbuf_chk = siftr_chkpkt; pha.pa_type = PFIL_TYPE_IP4; V_siftr_inet_hook = pfil_add_hook(&pha); pla.pa_hook = V_siftr_inet_hook; pla.pa_head = V_inet_pfil_head; (void)pfil_link(&pla); #ifdef SIFTR_IPV6 - pha.pa_func = siftr_chkpkt6; + pha.pa_mbuf_chk = siftr_chkpkt6; pha.pa_type = PFIL_TYPE_IP6; V_siftr_inet6_hook = pfil_add_hook(&pha); pla.pa_hook = V_siftr_inet6_hook; diff --git a/sys/netpfil/ipfilter/netinet/ip_fil_freebsd.c b/sys/netpfil/ipfilter/netinet/ip_fil_freebsd.c --- a/sys/netpfil/ipfilter/netinet/ip_fil_freebsd.c +++ b/sys/netpfil/ipfilter/netinet/ip_fil_freebsd.c @@ -1311,31 +1311,31 @@ } int ipf_pfil_hook(void) { - struct pfil_hook_args pha; - struct pfil_link_args pla; int error, error6; - pha.pa_version = PFIL_VERSION; - pha.pa_flags = PFIL_IN | PFIL_OUT; - pha.pa_modname = "ipfilter"; - pha.pa_rulname = "default-ip4"; - pha.pa_func = ipf_check_wrapper; - pha.pa_ruleset = NULL; - pha.pa_type = PFIL_TYPE_IP4; + struct pfil_hook_args pha = { + .pa_version = PFIL_VERSION, + .pa_flags = PFIL_IN | PFIL_OUT, + .pa_modname = "ipfilter", + .pa_rulname = "default-ip4", + .pa_mbuf_chk = ipf_check_wrapper, + .pa_type = PFIL_TYPE_IP4, + }; V_ipf_inet_hook = pfil_add_hook(&pha); #ifdef USE_INET6 pha.pa_rulname = "default-ip6"; - pha.pa_func = ipf_check_wrapper6; + pha.pa_mbuf_chk = ipf_check_wrapper6; pha.pa_type = PFIL_TYPE_IP6; V_ipf_inet6_hook = pfil_add_hook(&pha); #endif - pla.pa_version = PFIL_VERSION; - pla.pa_flags = PFIL_IN | PFIL_OUT | - PFIL_HEADPTR | PFIL_HOOKPTR; - pla.pa_head = V_inet_pfil_head; - pla.pa_hook = V_ipf_inet_hook; + struct pfil_link_args pla = { + .pa_version = PFIL_VERSION, + .pa_flags = PFIL_IN | PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR, + .pa_head = V_inet_pfil_head, + .pa_hook = V_ipf_inet_hook, + }; error = pfil_link(&pla); error6 = 0; diff --git a/sys/netpfil/ipfw/ip_fw_pfil.c b/sys/netpfil/ipfw/ip_fw_pfil.c --- a/sys/netpfil/ipfw/ip_fw_pfil.c +++ b/sys/netpfil/ipfw/ip_fw_pfil.c @@ -327,52 +327,104 @@ } /* - * ipfw processing for ethernet packets (in and out). + * ipfw processing for ethernet packets (in and out), mbuf version. */ static pfil_return_t -ipfw_check_frame(pfil_packet_t p, struct ifnet *ifp, int flags, +ipfw_check_frame_mbuf(struct mbuf **m0, struct ifnet *ifp, const int flags, void *ruleset __unused, struct inpcb *inp) { - struct ip_fw_args args; + struct ip_fw_args args = { + .flags = IPFW_ARGS_ETHER | + ((flags & PFIL_IN) ? IPFW_ARGS_IN : IPFW_ARGS_OUT), + .ifp = ifp, + .inp = inp, + }; + struct m_tag *mtag; pfil_return_t ret; - bool mem, realloc; int ipfw; - if (flags & PFIL_MEMPTR) { - mem = true; - realloc = false; - args.flags = PFIL_LENGTH(flags) | IPFW_ARGS_ETHER; - args.mem = p.mem; - } else { - mem = realloc = false; - args.flags = IPFW_ARGS_ETHER; +again: + /* + * Fetch start point from rule, if any. + * Remove the tag if present. + */ + mtag = m_tag_locate(*m0, MTAG_IPFW_RULE, 0, NULL); + if (mtag != NULL) { + args.rule = *((struct ipfw_rule_ref *)(mtag+1)); + m_tag_delete(*m0, mtag); + if (args.rule.info & IPFW_ONEPASS) + return (PFIL_PASS); + args.flags |= IPFW_ARGS_REF; } - args.flags |= (flags & PFIL_IN) ? IPFW_ARGS_IN : IPFW_ARGS_OUT; - args.ifp = ifp; - args.inp = inp; + args.m = *m0, -again: - if (!mem) { - /* - * Fetch start point from rule, if any. - * Remove the tag if present. - */ - struct m_tag *mtag; - - mtag = m_tag_locate(*p.m, MTAG_IPFW_RULE, 0, NULL); - if (mtag != NULL) { - args.rule = *((struct ipfw_rule_ref *)(mtag+1)); - m_tag_delete(*p.m, mtag); - if (args.rule.info & IPFW_ONEPASS) - return (PFIL_PASS); - args.flags |= IPFW_ARGS_REF; + ipfw = ipfw_chk(&args); + *m0 = args.m; + + ret = PFIL_PASS; + switch (ipfw) { + case IP_FW_PASS: + break; + + case IP_FW_DENY: + ret = PFIL_DROPPED; + break; + + case IP_FW_DUMMYNET: + if (ip_dn_io_ptr == NULL) { + ret = PFIL_DROPPED; + break; } - args.m = *p.m; + MPASS(args.flags & IPFW_ARGS_REF); + ip_dn_io_ptr(m0, &args); + return (PFIL_CONSUMED); + + case IP_FW_NGTEE: + case IP_FW_NETGRAPH: + if (ng_ipfw_input_p == NULL) { + ret = PFIL_DROPPED; + break; + } + MPASS(args.flags & IPFW_ARGS_REF); + (void )ng_ipfw_input_p(m0, &args, ipfw == IP_FW_NGTEE); + if (ipfw == IP_FW_NGTEE) /* ignore errors for NGTEE */ + goto again; /* continue with packet */ + ret = PFIL_CONSUMED; + break; + + default: + KASSERT(0, ("%s: unknown retval", __func__)); } + if (ret != PFIL_PASS) { + if (*m0) + FREE_PKT(*m0); + *m0 = NULL; + } + + return (ret); +} + +/* + * ipfw processing for ethernet packets (in and out), memory pointer version, + * two in/out accessors. + */ +static pfil_return_t +ipfw_check_frame_mem(void *mem, u_int len, int flags, struct ifnet *ifp, + void *ruleset __unused, struct mbuf **m) +{ + struct ip_fw_args args = { + .flags = len | IPFW_ARGS_ETHER | + ((flags & PFIL_IN) ? IPFW_ARGS_IN : IPFW_ARGS_OUT), + .ifp = ifp, + .mem = mem, + }; + pfil_return_t ret; + int ipfw; + + *m = NULL; +again: ipfw = ipfw_chk(&args); - if (!mem) - *p.m = args.m; ret = PFIL_PASS; switch (ipfw) { @@ -388,16 +440,13 @@ ret = PFIL_DROPPED; break; } - if (mem) { - if (pfil_realloc(&p, flags, ifp) != 0) { - ret = PFIL_DROPPED; - break; - } - mem = false; - realloc = true; + *m = m_devget(mem, len, 0, ifp, NULL); + if (*m == NULL) { + ret = PFIL_DROPPED; + break; } MPASS(args.flags & IPFW_ARGS_REF); - ip_dn_io_ptr(p.m, &args); + ip_dn_io_ptr(m, &args); return (PFIL_CONSUMED); case IP_FW_NGTEE: @@ -406,16 +455,13 @@ ret = PFIL_DROPPED; break; } - if (mem) { - if (pfil_realloc(&p, flags, ifp) != 0) { - ret = PFIL_DROPPED; - break; - } - mem = false; - realloc = true; + *m = m_devget(mem, len, 0, ifp, NULL); + if (*m == NULL) { + ret = PFIL_DROPPED; + break; } MPASS(args.flags & IPFW_ARGS_REF); - (void )ng_ipfw_input_p(p.m, &args, ipfw == IP_FW_NGTEE); + (void )ng_ipfw_input_p(m, &args, ipfw == IP_FW_NGTEE); if (ipfw == IP_FW_NGTEE) /* ignore errors for NGTEE */ goto again; /* continue with packet */ ret = PFIL_CONSUMED; @@ -425,13 +471,7 @@ KASSERT(0, ("%s: unknown retval", __func__)); } - if (!mem && ret != PFIL_PASS) { - if (*p.m) - FREE_PKT(*p.m); - *p.m = NULL; - } - - if (realloc && ret == PFIL_PASS) + if (*m != NULL && ret == PFIL_PASS) ret = PFIL_REALLOCED; return (ret); @@ -543,34 +583,33 @@ static void ipfw_hook(int pf) { - struct pfil_hook_args pha; + struct pfil_hook_args pha = { + .pa_version = PFIL_VERSION, + .pa_flags = PFIL_IN | PFIL_OUT, + .pa_modname = "ipfw", + }; pfil_hook_t *h; - pha.pa_version = PFIL_VERSION; - pha.pa_flags = PFIL_IN | PFIL_OUT; - pha.pa_modname = "ipfw"; - pha.pa_ruleset = NULL; - switch (pf) { case AF_INET: - pha.pa_func = ipfw_check_packet; + pha.pa_mbuf_chk = ipfw_check_packet; pha.pa_type = PFIL_TYPE_IP4; pha.pa_rulname = "default"; h = &V_ipfw_inet_hook; break; #ifdef INET6 case AF_INET6: - pha.pa_func = ipfw_check_packet; + pha.pa_mbuf_chk = ipfw_check_packet; pha.pa_type = PFIL_TYPE_IP6; pha.pa_rulname = "default6"; h = &V_ipfw_inet6_hook; break; #endif case AF_LINK: - pha.pa_func = ipfw_check_frame; + pha.pa_mbuf_chk = ipfw_check_frame_mbuf; + pha.pa_mem_chk = ipfw_check_frame_mem; pha.pa_type = PFIL_TYPE_ETHERNET; pha.pa_rulname = "default-link"; - pha.pa_flags |= PFIL_MEMPTR; h = &V_ipfw_link_hook; break; } diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -6532,21 +6532,20 @@ static void hook_pf_eth(void) { - struct pfil_hook_args pha; - struct pfil_link_args pla; + struct pfil_hook_args pha = { + .pa_version = PFIL_VERSION, + .pa_modname = "pf", + .pa_type = PFIL_TYPE_ETHERNET, + }; + struct pfil_link_args pla = { + .pa_version = PFIL_VERSION, + }; int ret __diagused; if (atomic_load_bool(&V_pf_pfil_eth_hooked)) return; - pha.pa_version = PFIL_VERSION; - pha.pa_modname = "pf"; - pha.pa_ruleset = NULL; - - pla.pa_version = PFIL_VERSION; - - pha.pa_type = PFIL_TYPE_ETHERNET; - pha.pa_func = pf_eth_check_in; + pha.pa_mbuf_chk = pf_eth_check_in; pha.pa_flags = PFIL_IN; pha.pa_rulname = "eth-in"; V_pf_eth_in_hook = pfil_add_hook(&pha); @@ -6555,7 +6554,7 @@ pla.pa_hook = V_pf_eth_in_hook; ret = pfil_link(&pla); MPASS(ret == 0); - pha.pa_func = pf_eth_check_out; + pha.pa_mbuf_chk = pf_eth_check_out; pha.pa_flags = PFIL_OUT; pha.pa_rulname = "eth-out"; V_pf_eth_out_hook = pfil_add_hook(&pha); @@ -6571,22 +6570,21 @@ static void hook_pf(void) { - struct pfil_hook_args pha; - struct pfil_link_args pla; + struct pfil_hook_args pha = { + .pa_version = PFIL_VERSION, + .pa_modname = "pf", + }; + struct pfil_link_args pla = { + .pa_version = PFIL_VERSION, + }; int ret __diagused; if (atomic_load_bool(&V_pf_pfil_hooked)) return; - pha.pa_version = PFIL_VERSION; - pha.pa_modname = "pf"; - pha.pa_ruleset = NULL; - - pla.pa_version = PFIL_VERSION; - #ifdef INET pha.pa_type = PFIL_TYPE_IP4; - pha.pa_func = pf_check_in; + pha.pa_mbuf_chk = pf_check_in; pha.pa_flags = PFIL_IN; pha.pa_rulname = "default-in"; V_pf_ip4_in_hook = pfil_add_hook(&pha); @@ -6595,7 +6593,7 @@ pla.pa_hook = V_pf_ip4_in_hook; ret = pfil_link(&pla); MPASS(ret == 0); - pha.pa_func = pf_check_out; + pha.pa_mbuf_chk = pf_check_out; pha.pa_flags = PFIL_OUT; pha.pa_rulname = "default-out"; V_pf_ip4_out_hook = pfil_add_hook(&pha); @@ -6607,7 +6605,7 @@ #endif #ifdef INET6 pha.pa_type = PFIL_TYPE_IP6; - pha.pa_func = pf_check6_in; + pha.pa_mbuf_chk = pf_check6_in; pha.pa_flags = PFIL_IN; pha.pa_rulname = "default-in6"; V_pf_ip6_in_hook = pfil_add_hook(&pha); @@ -6616,7 +6614,7 @@ pla.pa_hook = V_pf_ip6_in_hook; ret = pfil_link(&pla); MPASS(ret == 0); - pha.pa_func = pf_check6_out; + pha.pa_mbuf_chk = pf_check6_out; pha.pa_rulname = "default-out6"; pha.pa_flags = PFIL_OUT; V_pf_ip6_out_hook = pfil_add_hook(&pha);