The branch main has been updated by kp:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=7c5cc952ff73f9b70d0f22d6600ddb1885daa784

commit 7c5cc952ff73f9b70d0f22d6600ddb1885daa784
Author:     Kristof Provost <k...@freebsd.org>
AuthorDate: 2025-07-07 10:02:58 +0000
Commit:     Kristof Provost <k...@freebsd.org>
CommitDate: 2025-07-12 09:57:52 +0000

    pf: Use the table on root always if current table is not active.
    
    ok sashan
    
    Obtained from:  OpenBSD, yasuoka <yasu...@openbsd.org>, 26b6297991
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
---
 sys/net/pfvar.h           |  2 ++
 sys/netpfil/pf/pf_lb.c    | 49 ++++++++++++++++++++---------------------------
 sys/netpfil/pf/pf_table.c | 26 ++++++++++++++++---------
 3 files changed, 40 insertions(+), 37 deletions(-)

diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 36fab1a03ee6..f915f6d0f8fa 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -2534,6 +2534,8 @@ int       pfr_ina_rollback(struct pfr_table *, u_int32_t, 
int *, int);
 int    pfr_ina_commit(struct pfr_table *, u_int32_t, int *, int *, int);
 int    pfr_ina_define(struct pfr_table *, struct pfr_addr *, int, int *,
            int *, u_int32_t, int);
+struct pfr_ktable
+       *pfr_ktable_select_active(struct pfr_ktable *);
 
 MALLOC_DECLARE(PFI_MTYPE);
 VNET_DECLARE(struct pfi_kkif *,                 pfi_all);
diff --git a/sys/netpfil/pf/pf_lb.c b/sys/netpfil/pf/pf_lb.c
index 308d76c46e5b..97e69c9d1986 100644
--- a/sys/netpfil/pf/pf_lb.c
+++ b/sys/netpfil/pf/pf_lb.c
@@ -545,6 +545,7 @@ pf_map_addr(sa_family_t af, struct pf_krule *r, struct 
pf_addr *saddr,
 {
        u_short                  reason = PFRES_MATCH;
        struct pf_addr          *raddr = NULL, *rmask = NULL;
+       struct pfr_ktable       *kt;
        uint64_t                 hashidx;
        int                      cnt;
 
@@ -600,29 +601,25 @@ pf_map_addr(sa_family_t af, struct pf_krule *r, struct 
pf_addr *saddr,
                pf_poolmask(naddr, raddr, rmask, saddr, af);
                break;
        case PF_POOL_RANDOM:
-               if (rpool->cur->addr.type == PF_ADDR_TABLE) {
-                       cnt = rpool->cur->addr.p.tbl->pfrkt_cnt;
-                       if (cnt == 0)
-                               rpool->tblidx = 0;
+               if (rpool->cur->addr.type == PF_ADDR_TABLE ||
+                   rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
+                       if (rpool->cur->addr.type == PF_ADDR_TABLE)
+                               kt = rpool->cur->addr.p.tbl;
                        else
-                               rpool->tblidx = (int)arc4random_uniform(cnt);
-                       memset(&rpool->counter, 0, sizeof(rpool->counter));
-                       if (pfr_pool_get(rpool->cur->addr.p.tbl,
-                           &rpool->tblidx, &rpool->counter, af, NULL)) {
+                               kt = rpool->cur->addr.p.dyn->pfid_kt;
+                       kt = pfr_ktable_select_active(kt);
+                       if (kt == NULL) {
                                reason = PFRES_MAPFAILED;
                                goto done_pool_mtx; /* unsupported */
                        }
-                       pf_addrcpy(naddr, &rpool->counter, af);
-               } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
-                       cnt = rpool->cur->addr.p.dyn->pfid_kt->pfrkt_cnt;
+                       cnt = kt->pfrkt_cnt;
                        if (cnt == 0)
                                rpool->tblidx = 0;
                        else
                                rpool->tblidx = (int)arc4random_uniform(cnt);
                        memset(&rpool->counter, 0, sizeof(rpool->counter));
-                       if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
-                           &rpool->tblidx, &rpool->counter, af,
-                           pf_islinklocal)) {
+                       if (pfr_pool_get(kt, &rpool->tblidx, &rpool->counter,
+                           af, pf_islinklocal)) {
                                reason = PFRES_MAPFAILED;
                                goto done_pool_mtx; /* unsupported */
                        }
@@ -671,29 +668,25 @@ pf_map_addr(sa_family_t af, struct pf_krule *r, struct 
pf_addr *saddr,
 
                hashidx =
                    pf_hash(saddr, (struct pf_addr *)&hash, &rpool->key, af);
-               if (rpool->cur->addr.type == PF_ADDR_TABLE) {
-                       cnt = rpool->cur->addr.p.tbl->pfrkt_cnt;
-                       if (cnt == 0)
-                               rpool->tblidx = 0;
+               if (rpool->cur->addr.type == PF_ADDR_TABLE ||
+                   rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
+                       if (rpool->cur->addr.type == PF_ADDR_TABLE)
+                               kt = rpool->cur->addr.p.tbl;
                        else
-                               rpool->tblidx = (int)(hashidx % cnt);
-                       memset(&rpool->counter, 0, sizeof(rpool->counter));
-                       if (pfr_pool_get(rpool->cur->addr.p.tbl,
-                           &rpool->tblidx, &rpool->counter, af, NULL)) {
+                               kt = rpool->cur->addr.p.dyn->pfid_kt;
+                       kt = pfr_ktable_select_active(kt);
+                       if (kt == NULL) {
                                reason = PFRES_MAPFAILED;
                                goto done_pool_mtx; /* unsupported */
                        }
-                       pf_addrcpy(naddr, &rpool->counter, af);
-               } else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
-                       cnt = rpool->cur->addr.p.dyn->pfid_kt->pfrkt_cnt;
+                       cnt = kt->pfrkt_cnt;
                        if (cnt == 0)
                                rpool->tblidx = 0;
                        else
                                rpool->tblidx = (int)(hashidx % cnt);
                        memset(&rpool->counter, 0, sizeof(rpool->counter));
-                       if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
-                           &rpool->tblidx, &rpool->counter, af,
-                           pf_islinklocal)) {
+                       if (pfr_pool_get(kt, &rpool->tblidx, &rpool->counter,
+                           af, pf_islinklocal)) {
                                reason = PFRES_MAPFAILED;
                                goto done_pool_mtx; /* unsupported */
                        }
diff --git a/sys/netpfil/pf/pf_table.c b/sys/netpfil/pf/pf_table.c
index 4faf328a2315..2034f4422ef1 100644
--- a/sys/netpfil/pf/pf_table.c
+++ b/sys/netpfil/pf/pf_table.c
@@ -2082,9 +2082,8 @@ pfr_kentry_byaddr(struct pfr_ktable *kt, struct pf_addr 
*a, sa_family_t af,
 
        PF_RULES_RASSERT();
 
-       if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
-               kt = kt->pfrkt_root;
-       if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
+       kt = pfr_ktable_select_active(kt);
+       if (kt == NULL)
                return (0);
 
        switch (af) {
@@ -2150,9 +2149,8 @@ pfr_update_stats(struct pfr_ktable *kt, struct pf_addr 
*a, sa_family_t af,
 {
        struct pfr_kentry       *ke = NULL;
 
-       if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
-               kt = kt->pfrkt_root;
-       if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
+       kt = pfr_ktable_select_active(kt);
+       if (kt == NULL)
                return;
 
        switch (af) {
@@ -2321,9 +2319,8 @@ pfr_pool_get(struct pfr_ktable *kt, int *pidx, struct 
pf_addr *counter,
                unhandled_af(af);
        }
 
-       if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
-               kt = kt->pfrkt_root;
-       if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
+       kt = pfr_ktable_select_active(kt);
+       if (kt == NULL)
                return (-1);
 
        idx = *pidx;
@@ -2470,3 +2467,14 @@ pfr_dynaddr_update(struct pfr_ktable *kt, struct 
pfi_dynaddr *dyn)
                unhandled_af(dyn->pfid_af);
        }
 }
+
+struct pfr_ktable *
+pfr_ktable_select_active(struct pfr_ktable *kt)
+{
+       if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
+               kt = kt->pfrkt_root;
+       if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
+               return (NULL);
+
+       return (kt);
+}

Reply via email to