If you pass multiple interfaces to a binat-to rule, internally pfctl
generates n^2/2 rules:
# echo "pass on {a, b, c, d, e, f, g } binat-to 1.2.3.4" | pfctl -a test -f-
# pfctl -a test -sr
pass out on a inet all flags S/SA keep state nat-to 1.2.3.4 static-port
pass in on a inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass in on b inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass in on c inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass in on d inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass in on e inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass in on f inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass in on g inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass out on b inet all flags S/SA keep state nat-to 1.2.3.4 static-port
pass in on b inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass in on c inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass in on d inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass in on e inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass in on f inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass in on g inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass out on c inet all flags S/SA keep state nat-to 1.2.3.4 static-port
pass in on c inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass in on d inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass in on e inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass in on f inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass in on g inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass out on d inet all flags S/SA keep state nat-to 1.2.3.4 static-port
pass in on d inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass in on e inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass in on f inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass in on g inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass out on e inet all flags S/SA keep state nat-to 1.2.3.4 static-port
pass in on e inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass in on f inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass in on g inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass out on f inet all flags S/SA keep state nat-to 1.2.3.4 static-port
pass in on f inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass in on g inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
pass out on g inet all flags S/SA keep state nat-to 1.2.3.4 static-port
pass in on g inet from any to 1.2.3.4 flags S/SA keep state rdr-to any
It looks like it's re-parsing all latter entries at each entry.
I realize this rule is kind of silly, although it does similar
behavior if I pass an explicit address. And even then, I'm not sure
it makes any sense to pass in multiple interfaces to binat-to anyway,
although maybe I'm not being imaginative enough.
Found on August 9th snapshot, but also in 4.7 main.
# uname -mprsv
OpenBSD 4.8 GENERIC#134 i386 Intel(R) Pentium(R) 4 CPU 2.80GHz
("GenuineIntel" 686-class)
# dmesg | head -3
OpenBSD 4.8 (GENERIC) #134: Mon Aug 9 11:58:12 MDT 2010
[email protected]:/usr/src/sys/arch/i386/compile/GENERIC
cpu0: Intel(R) Pentium(R) 4 CPU 2.80GHz ("GenuineIntel" 686-class) 2.80 GHz