On Mon, Feb 14, 2022 at 02:14:19PM +0100, Alexandr Nedvedicky wrote:
> 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.
>
diff makes sense and works as expected, thanks.
ok giovanni@
> 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);
>
>
signature.asc
Description: PGP signature
