Page MenuHomeFreeBSD

D37977.diff
No OneTemporary

D37977.diff

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);

File Metadata

Mime Type
text/plain
Expires
Thu, Feb 6, 12:19 PM (21 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16493390
Default Alt Text
D37977.diff (22 KB)

Event Timeline