Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109470964
D37977.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
22 KB
Referenced Files
None
Subscribers
None
D37977.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D37977: pfil: add pfil_mem_{in,out}() and retire pfil_run_hooks()
Attached
Detach File
Event Timeline
Log In to Comment