The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=029532e77b92d0c74976e3e3fc79a0ca5e0e3dc0
commit 029532e77b92d0c74976e3e3fc79a0ca5e0e3dc0 Author: Kristof Provost <k...@freebsd.org> AuthorDate: 2025-07-30 15:22:36 +0000 Commit: Kristof Provost <k...@freebsd.org> CommitDate: 2025-08-05 22:27:15 +0000 pf: also allocate ethernet anchors from a UMA zone As per the previous commit, ensure we can't endlessly allocate ethernet anchors. Sponsored by: Rubicon Communications, LLC ("Netgate") --- sbin/pfctl/pfctl.c | 1 + sys/net/pfvar.h | 2 ++ sys/netpfil/pf/pf.c | 7 +++++++ sys/netpfil/pf/pf.h | 3 ++- sys/netpfil/pf/pf_ioctl.c | 1 + sys/netpfil/pf/pf_norm.c | 1 + sys/netpfil/pf/pf_ruleset.c | 8 ++++---- 7 files changed, 18 insertions(+), 5 deletions(-) diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c index a96eed7fc94a..ae772395e0ef 100644 --- a/sbin/pfctl/pfctl.c +++ b/sbin/pfctl/pfctl.c @@ -184,6 +184,7 @@ static const struct { { "frags", PF_LIMIT_FRAGS }, { "table-entries", PF_LIMIT_TABLE_ENTRIES }, { "anchors", PF_LIMIT_ANCHORS }, + { "eth-anchors", PF_LIMIT_ETH_ANCHORS }, { NULL, 0 } }; diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index c933ff395992..c397f0b67896 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -2340,6 +2340,8 @@ VNET_DECLARE(uma_zone_t, pf_state_scrub_z); #define V_pf_state_scrub_z VNET(pf_state_scrub_z) VNET_DECLARE(uma_zone_t, pf_anchor_z); #define V_pf_anchor_z VNET(pf_anchor_z) +VNET_DECLARE(uma_zone_t, pf_eth_anchor_z); +#define V_pf_eth_anchor_z VNET(pf_eth_anchor_z) extern void pf_purge_thread(void *); extern void pf_unload_vnet_purge(void); diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 408d0d3c96e3..19702fde7d22 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -1262,6 +1262,13 @@ pf_initialize(void) uma_zone_set_max(V_pf_anchor_z, PF_ANCHOR_HIWAT); uma_zone_set_warning(V_pf_anchor_z, "PF anchor limit reached"); + V_pf_eth_anchor_z = uma_zcreate("pf Ethernet anchors", + sizeof(struct pf_keth_anchor), NULL, NULL, NULL, NULL, + UMA_ALIGN_PTR, 0); + V_pf_limits[PF_LIMIT_ETH_ANCHORS].zone = V_pf_eth_anchor_z; + uma_zone_set_max(V_pf_eth_anchor_z, PF_ANCHOR_HIWAT); + uma_zone_set_warning(V_pf_eth_anchor_z, "PF Ethernet anchor limit reached"); + /* ALTQ */ TAILQ_INIT(&V_pf_altqs[0]); TAILQ_INIT(&V_pf_altqs[1]); diff --git a/sys/netpfil/pf/pf.h b/sys/netpfil/pf/pf.h index a41443fb9404..51b3fd6390e1 100644 --- a/sys/netpfil/pf/pf.h +++ b/sys/netpfil/pf/pf.h @@ -120,7 +120,8 @@ enum { enum { PF_NOPFROUTE, PF_FASTROUTE, PF_ROUTETO, PF_DUPTO, PF_REPLYTO }; enum { PF_LIMIT_STATES, PF_LIMIT_SRC_NODES, PF_LIMIT_FRAGS, - PF_LIMIT_TABLE_ENTRIES, PF_LIMIT_ANCHORS, PF_LIMIT_MAX }; + PF_LIMIT_TABLE_ENTRIES, PF_LIMIT_ANCHORS, PF_LIMIT_ETH_ANCHORS, + PF_LIMIT_MAX }; #define PF_POOL_IDMASK 0x0f enum { PF_POOL_NONE, PF_POOL_BITMASK, PF_POOL_RANDOM, PF_POOL_SRCHASH, PF_POOL_ROUNDROBIN }; diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c index 935747d9f58a..b6f5d74b5b42 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -332,6 +332,7 @@ pfattach_vnet(void) V_pf_limits[PF_LIMIT_STATES].limit = PFSTATE_HIWAT; V_pf_limits[PF_LIMIT_SRC_NODES].limit = PFSNODE_HIWAT; V_pf_limits[PF_LIMIT_ANCHORS].limit = PF_ANCHOR_HIWAT; + V_pf_limits[PF_LIMIT_ETH_ANCHORS].limit = PF_ANCHOR_HIWAT; RB_INIT(&V_pf_anchors); pf_init_kruleset(&pf_main_ruleset); diff --git a/sys/netpfil/pf/pf_norm.c b/sys/netpfil/pf/pf_norm.c index 2b822dca55b5..a684d778ab42 100644 --- a/sys/netpfil/pf/pf_norm.c +++ b/sys/netpfil/pf/pf_norm.c @@ -119,6 +119,7 @@ VNET_DEFINE_STATIC(uma_zone_t, pf_frnode_z); VNET_DEFINE_STATIC(uma_zone_t, pf_frag_z); #define V_pf_frag_z VNET(pf_frag_z) VNET_DEFINE(uma_zone_t, pf_anchor_z); +VNET_DEFINE(uma_zone_t, pf_eth_anchor_z); TAILQ_HEAD(pf_fragqueue, pf_fragment); TAILQ_HEAD(pf_cachequeue, pf_fragment); diff --git a/sys/netpfil/pf/pf_ruleset.c b/sys/netpfil/pf/pf_ruleset.c index 7f21b3f8fc47..039908a53126 100644 --- a/sys/netpfil/pf/pf_ruleset.c +++ b/sys/netpfil/pf/pf_ruleset.c @@ -613,7 +613,7 @@ pf_find_or_create_keth_ruleset(const char *path) rs_free(p); return (NULL); } - anchor = (struct pf_keth_anchor *)rs_malloc(sizeof(*anchor)); + anchor = uma_zalloc(V_pf_eth_anchor_z, M_NOWAIT | M_ZERO); if (anchor == NULL) { rs_free(p); return (NULL); @@ -631,7 +631,7 @@ pf_find_or_create_keth_ruleset(const char *path) printf("%s: RB_INSERT1 " "'%s' '%s' collides with '%s' '%s'\n", __func__, anchor->path, anchor->name, dup->path, dup->name); - rs_free(anchor); + uma_zfree(V_pf_eth_anchor_z, anchor); rs_free(p); return (NULL); } @@ -645,7 +645,7 @@ pf_find_or_create_keth_ruleset(const char *path) anchor->name, dup->path, dup->name); RB_REMOVE(pf_keth_anchor_global, &V_pf_keth_anchors, anchor); - rs_free(anchor); + uma_zfree(V_pf_eth_anchor_z, anchor); rs_free(p); return (NULL); } @@ -754,7 +754,7 @@ pf_remove_if_empty_keth_ruleset(struct pf_keth_ruleset *ruleset) if ((parent = ruleset->anchor->parent) != NULL) RB_REMOVE(pf_keth_anchor_node, &parent->children, ruleset->anchor); - rs_free(ruleset->anchor); + uma_zfree(V_pf_eth_anchor_z, ruleset->anchor); if (parent == NULL) return; ruleset = &parent->ruleset;