Bug was reported by Chriss Cappucio. It has turned out my earlier change
authorsashan <sashan@openbsd.org>
Wed, 3 Aug 2022 08:16:04 +0000 (08:16 +0000)
committersashan <sashan@openbsd.org>
Wed, 3 Aug 2022 08:16:04 +0000 (08:16 +0000)
commitc2364f2ab38e3255986defad064283e6e86862e7
tree88ebbc3bc7293cab77a85f5bea6aa364253cc24b
parent07e4740f85bb7e37ebff07421a133561825b178f
Bug was reported by Chriss Cappucio. It has turned out my earlier change
to pf_lb.c was not complete. We must add a test to determine number of
addresses defined by pool, so we don't treat pool definition
172.16.0.0/16 as a single IP address in pool. If pool is defined as
172.16.0.0/16, then we don't want to fall back to PF_POOL_NONE. Missing
this measure in pf_map_addr() may cause pf_get_sport() to enter infinite
loop when source ports translation become depleted for the first address
found in pool (like 172.16.0.1), because the bug prevents pf_map_addr()
to move to next address in pool (like 172.16.0.2).

while investigating issue I've also noticed an oddity for small random
pools such as 192.168.1.32/28. One would expect the addresses for nat
will be randomly picked from range .32 - .47 in this case. however the
random selection yield significantly more (like 20%) addresses ending by .32
In order to fix it we make random pool to use arc4random_uniform(~mask + 1)
instead of current arc4random().

feedback by claudio@
tested by hrvoje@
sys/net/pf_lb.c