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")
This commit is contained in:
Kristof Provost 2025-07-30 17:22:36 +02:00
parent 31131a9d6a
commit 029532e77b
7 changed files with 18 additions and 5 deletions

View file

@ -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 }
};

View file

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

View file

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

View file

@ -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 };

View file

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

View file

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

View file

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