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
    dera...@i386.openbsd.org:/usr/src/sys/arch/i386/compile/GENERIC
cpu0: Intel(R) Pentium(R) 4 CPU 2.80GHz ("GenuineIntel" 686-class) 2.80 GHz

Reply via email to