git: 7c5cc952ff73 - main - pf: Use the table on root always if current table is not active.

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Sat, 12 Jul 2025 13:39:00 UTC
The branch main has been updated by kp:

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

commit 7c5cc952ff73f9b70d0f22d6600ddb1885daa784
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2025-07-07 10:02:58 +0000
Commit:     Kristof Provost <kp@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 <yasuoka@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);
+}