Hi,

The diff fixes 2 problems of "least-states":

- states whose address is selected by sticky-address is not counted
  for the number of states.
- interface is not selected properly if selected table entry specifies
  an interface.

ok?

Increase state counter for least-states when the address is selected
by sticky-address.  Also fix the problem that the interface which is
specified by the selected table entry is not used properly.

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 11:06:05 -0000
@@ -97,6 +97,8 @@ u_int64_t              pf_hash(struct pf_addr *, st
 int                     pf_get_sport(struct pf_pdesc *, struct pf_rule *,
                            struct pf_addr *, u_int16_t *, u_int16_t,
                            u_int16_t, struct pf_src_node **);
+int                     pf_map_addr_states_increase(sa_family_t,
+                               struct pf_pool *, struct pf_addr *);
 int                     pf_get_transaddr_af(struct pf_rule *,
                            struct pf_pdesc *, struct pf_src_node **);
 int                     pf_map_addr_sticky(sa_family_t, struct pf_rule *,
@@ -319,6 +321,12 @@ pf_map_addr_sticky(sa_family_t af, struc
                sns[type] = NULL;
                return (-1);
        }
+
+       if ((rpool->opts & PF_POOL_TYPEMASK) == PF_POOL_LEASTSTATES) {
+               if (pf_map_addr_states_increase(af, rpool, naddr) == -1)
+                       return (-1);
+       }
+
        if (!PF_AZERO(cached, af))
                pf_addrcpy(naddr, cached, af);
        if (pf_status.debug >= LOG_DEBUG) {
@@ -345,6 +353,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 pfi_kif          *kif;
        u_int64_t                states;
        u_int16_t                weight;
        u_int64_t                load;
@@ -539,6 +548,7 @@ pf_map_addr(sa_family_t af, struct pf_ru
 
                states = rpool->states;
                weight = rpool->weight;
+               kif = rpool->kif;
 
                if ((rpool->addr.type == PF_ADDR_TABLE &&
                    rpool->addr.p.tbl->pfrkt_refcntcost > 0) ||
@@ -581,6 +591,7 @@ pf_map_addr(sa_family_t af, struct pf_ru
                        if (cload < load) {
                                states = rpool->states;
                                weight = rpool->weight;
+                               kif = rpool->kif;
                                load = cload;
 
                                pf_addrcpy(naddr, &rpool->counter, af);
@@ -591,29 +602,10 @@ pf_map_addr(sa_family_t af, struct pf_ru
                } while (pf_match_addr(1, &faddr, rmask, &rpool->counter, af) &&
                    (states > 0));
 
-               if (rpool->addr.type == PF_ADDR_TABLE) {
-                       if (pfr_states_increase(rpool->addr.p.tbl,
-                           naddr, af) == -1) {
-                               if (pf_status.debug >= LOG_DEBUG) {
-                                       log(LOG_DEBUG,"pf: pf_map_addr: "
-                                           "selected address ");
-                                       pf_print_host(naddr, 0, af);
-                                       addlog(". Failed to increase count!\n");
-                               }
-                               return (1);
-                       }
-               } else if (rpool->addr.type == PF_ADDR_DYNIFTL) {
-                       if (pfr_states_increase(rpool->addr.p.dyn->pfid_kt,
-                           naddr, af) == -1) {
-                               if (pf_status.debug >= LOG_DEBUG) {
-                                       log(LOG_DEBUG, "pf: pf_map_addr: "
-                                           "selected address ");
-                                       pf_print_host(naddr, 0, af);
-                                       addlog(". Failed to increase count!\n");
-                               }
-                               return (1);
-                       }
-               }
+               if (pf_map_addr_states_increase(af, rpool, naddr) == -1)
+                       return (1);
+               /* revert the kif which was set by pfr_pool_get() */
+               rpool->kif = kif;
                break;
        }
 
@@ -642,6 +634,38 @@ pf_map_addr(sa_family_t af, struct pf_ru
                addlog("\n");
        }
 
+       return (0);
+}
+
+int
+pf_map_addr_states_increase(sa_family_t af, struct pf_pool *rpool,
+    struct pf_addr *naddr)
+{
+       if (rpool->addr.type == PF_ADDR_TABLE) {
+               if (pfr_states_increase(rpool->addr.p.tbl,
+                   naddr, af) == -1) {
+                       if (pf_status.debug >= LOG_DEBUG) {
+                               log(LOG_DEBUG,
+                                   "pf: pf_map_addr_states_increase: "
+                                   "selected address ");
+                               pf_print_host(naddr, 0, af);
+                               addlog(". Failed to increase count!\n");
+                       }
+                       return (1);
+               }
+       } else if (rpool->addr.type == PF_ADDR_DYNIFTL) {
+               if (pfr_states_increase(rpool->addr.p.dyn->pfid_kt,
+                   naddr, af) == -1) {
+                       if (pf_status.debug >= LOG_DEBUG) {
+                               log(LOG_DEBUG,
+                                   "pf: pf_map_addr_states_increase: "
+                                   "selected address ");
+                               pf_print_host(naddr, 0, af);
+                               addlog(". Failed to increase count!\n");
+                       }
+                       return (1);
+               }
+       }
        return (0);
 }
 

Reply via email to