git: 110801814911 - main - pf: Clear only the part of the packet descriptor that is read first
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 28 Oct 2026 16:00:48 UTC
The branch main has been updated by rcm:
URL: https://cgit.FreeBSD.org/src/commit/?id=11080181491144b9cad726bb6e84d87fa05a681e
commit 11080181491144b9cad726bb6e84d87fa05a681e
Author: R. Christian McDonald <rcm@FreeBSD.org>
AuthorDate: 2026-10-28 16:00:03 +0000
Commit: R. Christian McDonald <rcm@FreeBSD.org>
CommitDate: 2026-10-28 16:00:03 +0000
pf: Clear only the part of the packet descriptor that is read first
pf_init_pdesc() cleared the whole structure, 336 bytes on amd64, for
every packet and twice for a forwarded one. kif, m, pf_mtag, act and
the SCTP job list are set before they are read, so move them to the end
and clear only the 240 bytes before them. On amd64 that also stays
below the 256 bytes from which memset() switches to rep stosb.
Reviewed by: kp
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D60948
---
sys/net/pfvar.h | 14 +++++++++-----
sys/netpfil/pf/pf.c | 4 +++-
2 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 6c7c7d364ba2..5b4d87a22301 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1950,9 +1950,6 @@ struct pf_pdesc {
struct pf_addr nsaddr; /* src address after NAT */
struct pf_addr ndaddr; /* dst address after NAT */
- struct pfi_kkif *kif; /* incomming interface */
- struct mbuf *m;
-
struct pf_addr *src; /* src address */
struct pf_addr *dst; /* dst address */
struct pf_addr osrc;
@@ -1964,8 +1961,6 @@ struct pf_pdesc {
u_int16_t odport;
u_int16_t nsport; /* src port after NAT */
u_int16_t ndport; /* dst port after NAT */
- struct pf_mtag *pf_mtag;
- struct pf_rule_actions act;
u_int32_t off; /* protocol header offset */
bool df; /* IPv4 Don't fragment flag. */
@@ -2011,6 +2006,15 @@ struct pf_pdesc {
u_int16_t sctp_dummy_sum;
struct pf_krule *related_rule;
+ /*
+ * pf_init_pdesc() zeroes the members above this point only; those
+ * below are set before they are read.
+ */
+#define pd_endzero kif
+ struct pfi_kkif *kif; /* incoming interface */
+ struct mbuf *m;
+ struct pf_mtag *pf_mtag;
+ struct pf_rule_actions act;
struct pf_sctp_multihome_jobs sctp_multihome_jobs;
};
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 5961039bbb87..94985f47677c 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -11279,7 +11279,7 @@ pf_walk_header6(struct pf_pdesc *pd, struct ip6_hdr *h, u_short *reason)
static void
pf_init_pdesc(struct pf_pdesc *pd, struct mbuf *m)
{
- memset(pd, 0, sizeof(*pd));
+ memset(pd, 0, offsetof(struct pf_pdesc, pd_endzero));
pd->pf_mtag = pf_find_mtag(m);
pd->m = m;
}
@@ -11301,6 +11301,8 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0,
TAILQ_INIT(&pd->sctp_multihome_jobs);
if (default_actions != NULL)
memcpy(&pd->act, default_actions, sizeof(pd->act));
+ else
+ memset(&pd->act, 0, sizeof(pd->act));
if (pd->pf_mtag && pd->pf_mtag->dnpipe) {
pd->act.dnpipe = pd->pf_mtag->dnpipe;