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;
