> Hi,
>
> I have two ISPs and a LAN. I need to load balance outgoing connections
> from the LAN between the ISPs.
>
> My router is running OpenBSD 4.6-stable, up-to-date.
>
> -----------------
> | |
> ISP 1 ---(isp1 box)---+-ext1_if |
> | |
> | int_if-+--- LAN
> | |
> ISP 2 ---(isp2 box)---+-ext2_if |
> | |
> -----------------
> OpenBSD
>
> int_if -> interface to LAN
> int_net -> 192.168.0.0/24
>
> ext1_if -> interface to ISP 1 (192.168.1.2)
> ext1_gw -> ISP 1 gateway (192.168.1.1)
>
> ext2_if -> interface to ISP 2 (192.168.2.2)
> ext2_gw -> ISP 2 gateway (192.168.2.1)
>
> There is no default route (empty /etc/mygate).
>
> Following
http://www.openbsd.org/faq/pf/pools.html#outgoing I ended up
> with the following :
>
> ---sysctl.conf---
> net.inet.ip.forwarding=1
> ---sysctl.conf---
>
> ---pf.conf---
> set debug loud
> set block-policy return
> #set optimization aggressive
> #set timeout src.track 300
> set skip on lo
>
> nat log on $ext1_if from $int_net -> ($ext1_if)
> nat log on $ext2_if from $int_net -> ($ext2_if)
>
> block log
>
> pass in log on $int_if route-to \
> { ($ext1_if $ext1_gw), ($ext2_if $ext2_gw) } \
> from $int_net
>
> pass in log on $int_if from $int_net to $int_if
>
> pass out log
> pass out log on $ext1_if route-to ($ext2_if $ext2_gw) from $ext2_if
> pass out log on $ext2_if route-to ($ext1_if $ext1_gw) from $ext1_if
> ---pf.conf---
>
> Everything works fine with this setup but https and some ftp servers
> are very sensitive to IP changes, so I did add sticky-address to bind
> a connection to an ISP and fix this issue :
>
> pass in log on $int_if route-to \
> { ($ext1_if $ext1_gw), ($ext2_if $ext2_gw) } sticky-address \
> from $int_net
>
> This works when only one PC open a connection. When another PC open
> a connection the first one has no longer access to the internet. After
> some time in tcpdump and /var/log/messages, it seems because packets
> are routed to the wrong interface.
>
> /var/log/messages analysis :
>
> 192.168.0.78 tries a connection :
> /bsd: pf_map_addr: selected address 192.168.2.1
> /bsd: pf_map_addr: selected address 192.168.2.2
> /bsd: pf_map_addr: src tracking maps 192.168.0.78 to 192.168.2.1
> /bsd: pf_map_addr: src tracking maps 192.168.0.78 to 192.168.2.2
> /bsd: pf_map_addr: src tracking maps 192.168.0.78 to 192.168.2.1
> /bsd: pf_map_addr: src tracking maps 192.168.0.78 to 192.168.2.2
>
> Looks ok, now 192.168.0.29 tries a connection too :
> /bsd: pf_map_addr: selected address 192.168.1.1
> /bsd: pf_map_addr: selected address 192.168.1.2
> /bsd: pf_map_addr: src tracking maps 192.168.0.29 to 192.168.1.1
> /bsd: pf_map_addr: src tracking maps 192.168.0.29 to 192.168.1.2
> /bsd: pf_map_addr: src tracking maps 192.168.0.29 to 192.168.1.1
> /bsd: pf_map_addr: src tracking maps 192.168.0.29 to 192.168.1.2
>
> Looks good, now 192.168.0.78 retries a connection :
> /bsd: pf_map_addr: src tracking maps 192.168.0.78 to 192.168.2.1
> /bsd: pf_map_addr: selected address 192.168.1.2
> [and that's all]
>
> This is confirmed by tcpdump (on pflog0, bge0, em0 and em1) : the
> packets are routed to the wrong interface. Three SYN are sent, then
> client bail out. Tests were quickly done, so there is no state/track
> timeout here.
>
> Is there something I am doing wrong ?
>