Hello Giovanni,

thank you for bug report. diff below should fix the issue.
Can you give it a try?

I've decided to deal with consequences instead of making pfctl(8)
parser bit smarter. As soon as we load rule:

    match out on em0 from 192.168.1.0/24 to any \
        nat-to { 172.16.1.1 } round-robin

we get rpool->counter set to zero, which makes pf_match_addr() at
line 501 to return 0 (success):

488         case PF_POOL_ROUNDROBIN:
489                 if (rpool->addr.type == PF_ADDR_TABLE ||
490                     rpool->addr.type == PF_ADDR_DYNIFTL) {
491                         if (pfr_pool_get(rpool, &raddr, &rmask, af)) {
492                                 /*
493                                  * reset counter in case its value
494                                  * has been removed from the pool.
495                                  */
496                                 memset(&rpool->counter, 0,
497                                     sizeof(rpool->counter));
498                                 if (pfr_pool_get(rpool, &raddr, &rmask, af))
499                                         return (1);
500                         }
501                 } else if (pf_match_addr(0, raddr, rmask, &rpool->counter, 
af))
502                         return (1);
503 
504                 /* iterate over table if it contains entries which are 
weighted */
505                 if ((rpool->addr.type == PF_ADDR_TABLE &&

this allows pf(4) to create sessions with source translation as follows:
        0.0.0.1, 0.0.0.2, 0.0.0.3 ...

I've also gave a try to rule:

    match out on em0 from 192.168.1.0/24 to any \
        nat-to { 172.16.1.1, 172.16.10.1 } round-robin

rule above works as expected with diff below applied.

let me know if it works for you too.

thanks and
regards
sashan

--------8<---------------8<---------------8<------------------8<--------
diff --git a/sys/net/pf_lb.c b/sys/net/pf_lb.c
index 65f70ef9102..ac84c34452e 100644
--- a/sys/net/pf_lb.c
+++ b/sys/net/pf_lb.c
@@ -498,6 +498,13 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct 
pf_addr *saddr,
                                if (pfr_pool_get(rpool, &raddr, &rmask, af))
                                        return (1);
                        }
+               } else if (PF_AZERO(&rpool->counter, af)) {
+                       /*
+                        * fall back to POOL_NONE if there are no addresses in
+                        * pool
+                        */
+                       pf_addrcpy(naddr, raddr, af);
+                       break;
                } else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af))
                        return (1);
 

Reply via email to