Hi,

Last month, I fixed the problem "route-to least-state" in an anchor
didn't work.

https://marc.info/?t=159117457800002&r=1&w=2

I noticed the same problem happens on "random" and "srchash" as well.

ok?

Use the table on root always if current table is not active.

Index: sys/net/pf_lb.c
===================================================================
RCS file: /disk/cvs/openbsd/src/sys/net/pf_lb.c,v
retrieving revision 1.64
diff -u -p -r1.64 pf_lb.c
--- sys/net/pf_lb.c     2 Jul 2019 09:04:53 -0000       1.64
+++ sys/net/pf_lb.c     23 Jul 2020 10:45:48 -0000
@@ -345,6 +345,7 @@ pf_map_addr(sa_family_t af, struct pf_ru
        struct pf_addr           faddr;
        struct pf_addr          *raddr = &rpool->addr.v.a.addr;
        struct pf_addr          *rmask = &rpool->addr.v.a.mask;
+       struct pfr_ktable       *kt;
        u_int64_t                states;
        u_int16_t                weight;
        u_int64_t                load;
@@ -396,18 +397,17 @@ pf_map_addr(sa_family_t af, struct pf_ru
                pf_poolmask(naddr, raddr, rmask, saddr, af);
                break;
        case PF_POOL_RANDOM:
-               if (rpool->addr.type == PF_ADDR_TABLE) {
-                       cnt = rpool->addr.p.tbl->pfrkt_cnt;
-                       if (cnt == 0)
-                               rpool->tblidx = 0;
+               if (rpool->addr.type == PF_ADDR_TABLE ||
+                   rpool->addr.type == PF_ADDR_DYNIFTL) {
+                       if (rpool->addr.type == PF_ADDR_TABLE)
+                               kt = rpool->addr.p.tbl;
                        else
-                               rpool->tblidx = (int)arc4random_uniform(cnt);
-                       memset(&rpool->counter, 0, sizeof(rpool->counter));
-                       if (pfr_pool_get(rpool, &raddr, &rmask, af))
+                               kt = rpool->addr.p.dyn->pfid_kt;
+                       kt = pfr_ktable_select_active(kt);
+                       if (!kt)
                                return (1);
-                       pf_addrcpy(naddr, &rpool->counter, af);
-               } else if (rpool->addr.type == PF_ADDR_DYNIFTL) {
-                       cnt = rpool->addr.p.dyn->pfid_kt->pfrkt_cnt;
+
+                       cnt = kt->pfrkt_cnt;
                        if (cnt == 0)
                                rpool->tblidx = 0;
                        else
@@ -453,18 +453,18 @@ pf_map_addr(sa_family_t af, struct pf_ru
        case PF_POOL_SRCHASH:
                hashidx =
                    pf_hash(saddr, (struct pf_addr *)&hash, &rpool->key, af);
-               if (rpool->addr.type == PF_ADDR_TABLE) {
-                       cnt = rpool->addr.p.tbl->pfrkt_cnt;
-                       if (cnt == 0)
-                               rpool->tblidx = 0;
+
+               if (rpool->addr.type == PF_ADDR_TABLE ||
+                   rpool->addr.type == PF_ADDR_DYNIFTL) {
+                       if (rpool->addr.type == PF_ADDR_TABLE)
+                               kt = rpool->addr.p.tbl;
                        else
-                               rpool->tblidx = (int)(hashidx % cnt);
-                       memset(&rpool->counter, 0, sizeof(rpool->counter));
-                       if (pfr_pool_get(rpool, &raddr, &rmask, af))
+                               kt = rpool->addr.p.dyn->pfid_kt;
+                       kt = pfr_ktable_select_active(kt);
+                       if (!kt)
                                return (1);
-                       pf_addrcpy(naddr, &rpool->counter, af);
-               } else if (rpool->addr.type == PF_ADDR_DYNIFTL) {
-                       cnt = rpool->addr.p.dyn->pfid_kt->pfrkt_cnt;
+
+                       cnt = kt->pfrkt_cnt;
                        if (cnt == 0)
                                rpool->tblidx = 0;
                        else
Index: sys/net/pf_table.c
===================================================================
RCS file: /disk/cvs/openbsd/src/sys/net/pf_table.c,v
retrieving revision 1.133
diff -u -p -r1.133 pf_table.c
--- sys/net/pf_table.c  24 Jun 2020 22:03:43 -0000      1.133
+++ sys/net/pf_table.c  23 Jul 2020 10:45:48 -0000
@@ -2108,9 +2108,8 @@ pfr_kentry_byaddr(struct pfr_ktable *kt,
        struct sockaddr_in6      tmp6;
 #endif /* INET6 */
 
-       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)
                return (0);
 
        switch (af) {
@@ -2153,9 +2152,8 @@ pfr_update_stats(struct pfr_ktable *kt, 
        int                      dir_idx = (pd->dir == PF_OUT);
        int                      op_idx;
 
-       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)
                return;
 
        switch (af) {
@@ -2308,9 +2306,8 @@ pfr_pool_get(struct pf_pool *rpool, stru
                kt = rpool->addr.p.dyn->pfid_kt;
        else
                return (-1);
-       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)
                return (-1);
 
        counter = &rpool->counter;
@@ -2564,4 +2561,15 @@ pfr_ktable_winfo_update(struct pfr_ktabl
                if (kt->pfrkt_maxweight < weight)
                        kt->pfrkt_maxweight = weight;
        }
+}
+
+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);
 }
Index: sys/net/pfvar.h
===================================================================
RCS file: /disk/cvs/openbsd/src/sys/net/pfvar.h,v
retrieving revision 1.494
diff -u -p -r1.494 pfvar.h
--- sys/net/pfvar.h     21 Jul 2020 14:10:51 -0000      1.494
+++ sys/net/pfvar.h     23 Jul 2020 10:45:49 -0000
@@ -1845,6 +1845,8 @@ int       pfr_ina_rollback(struct pfr_table *,
 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 *);
 
 extern struct pfi_kif          *pfi_all;
 

Reply via email to