I've been further looking at this, trying to work out where to 'fix'
it.
Various options seem to be:
1) Get the tun interface to re-calculate the TCP checksums
2) Get pf to have a flag telling it to calculate the checksums always
for a given rule
3) Get OpenVPN to calculate the checksums at some point
However I've managed to come up with a simpler scenario that does
not involve NAT and that still fails.
I have a bridge with two members:
bridge0:
bnx0 (192.168.1.1/24)
tun0
tun0 has OpenVPN running on it to some endpoint, but this could be any
other type of tunnel.
the IP of the OpenBSD box is assigned to the bnx0 interface. I am on a
laptop on the other end of the bridged OpenVPN link with IP address
192.168.1.145.
# arp -n 192.168.1.145
? (192.168.1.145) at 2a:ff:11:02:ea:76 on bnx0
# ifconfig bridge0 | grep 2a:ff:11:02:ea:76
2a:ff:11:02:ea:76 tun0 1 flags=0<>
# route -n get 192.168.1.145
route to: 192.168.1.145
destination: 192.168.1.145
interface: bnx0
if address: 192.168.1.1
priority: 8 (static)
flags: <UP,HOST,DONE,LLINFO,STATIC>
use mtu expire
540 0L 1189
I *can't* get a TCP connection from my laptop (192.168.1.145) to the
OpenBSD box (192.168.1.1). The TCP checksums are invalid.
Based on the info above it would seem that the routing table thinks
the packet should be routed to bnx0 based on the IP address. bnx0
supports HW tcp checksums, so the OS does not create the checksum
itself.
But the packet never goes out bnx0, it is picked up by the bridge and
sent down tun0 instead. tun interfaces do no recompute the tcp
checksum and so by the time the packet gets to my laptop the checksum
has never been correctly calculated and my laptop ignores the packet.
So what do we need to do to fix this? Is getting the tun interface to
calculate the checksums the way to go?
-Matt