Dear List, With help from various people here I've composed a pf ruleset that allows "load splitting" between two (or more) ISP connections on the basis of the client (internal) IP addressess.
The problem I have with this is when one or more of the ISPs provide a DHCP assigned address/route. While the (ifn) notation provides for reading an assigned address for an interface, I can find no way of dealing with an assigned (route) gateway for the ... route-to { ($ext_if $ext_gw) } ... notation. Here's the ruleset. Let me know if you have a use for it or know of some way of getting the DHCP gateway. Thanks, Dhu ext_if1 = "re0" ext_if2 = "vr0" ext_gw1 = "xx.xx.xx.xx" ext_gw2 = "xx.xx.xx.xx" int_if = "axe0" int_net = "192.168.117.0/24" int_clS = "{ 192.168.117.46,192.168.117.45,192.168.117.47 }" # tcp_services provided by this server on the external interface tcp_services = "{ 22,123 }" # 22 ssh # 25 smtp # 53 dns # 80 http # 110 pop # 123 ntp # 443 https # 587 smtp-submit # 3389 rdesk # 8118 privoxy # 9001 tor external # 9050 tor # 9051 tor ctl # udp_services provided by this server on the external interface udp_services = "{ 123 }" # 53 dns # 69 tftp # 123 ntp # 587 smtp_submit icmp_types = "echoreq" set skip on lo0 scrub in # nat outgoing connections on each internet interface nat on $ext_if2 from $int_net to any -> ($ext_if2) nat on $ext_if1 from $int_clS to any -> ($ext_if1) # default deny block in from any to any block out from any to any # pass all outgoing packets on internal interface pass out log on $int_if from any to $int_net # pass in quick any packets destined for the gateway itself pass in log quick on $int_if from $int_net to $int_if # Pass in tcp_services pass in log on $ext_if1 inet proto tcp from any to ($ext_if1) port $tcp_services flags S/SA keep state pass in log on $ext_if2 inet proto tcp from any to ($ext_if2) port $tcp_services flags S/SA keep state # Pass in udp_services pass in log on $ext_if1 inet proto udp from any to ($ext_if1) port $udp_services keep state pass in log on $ext_if2 inet proto udp from any to ($ext_if2) port $udp_services keep state # Pass in from int_net pass in log on $int_if route-to { ($ext_if2 $ext_gw2) } proto tcp from $int_net to any flags S/SA modulate state pass in log on $int_if route-to { ($ext_if2 $ext_gw2) } proto { udp, esp, icmp } from $int_net to any keep state # Pass in from int_clS pass in log on $int_if route-to { ($ext_if1 $ext_gw1) } proto tcp from $int_clS to any flags S/SA modulate state pass in log on $int_if route-to { ($ext_if1 $ext_gw1) } proto { udp, esp, icmp } from $int_clS to any keep state # general "pass out" rules for external interfaces pass out log on $ext_if1 proto tcp from any to any flags S/SA modulate state pass out log on $ext_if1 proto { udp, icmp } from any to any keep state pass out log on $ext_if2 proto tcp from any to any flags S/SA modulate state pass out log on $ext_if2 proto { udp, icmp } from any to any keep state # route packets from any IPs on $ext_if1 to $ext_gw1 and the same for # $ext_if2 and $ext_gw2 pass out log on $ext_if1 route-to ($ext_if2 $ext_gw2) from $ext_if2 to any pass out log on $ext_if2 route-to ($ext_if1 $ext_gw1) from $ext_if1 to any # Pass ICMPing pass in log inet proto icmp all icmp-type $icmp_types keep state pass out log on $ext_if1 proto { icmp } all keep state pass out log on $ext_if2 proto { icmp } all keep state