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;

Reply via email to