L2 bridge with OpenVPN TAP – client not accessible on the LAN

Hello everyone,

I am working on an L2 transparent bridge via OpenVPN, but I'm having trouble with the connectivity between the VPN client and the physical LAN.

1. Requirement and goal:
The goal is to seamlessly and transparently connect a remote location to the local network. The connection should be Layer 2 based so that the remote client behaves like a locally connected device.

2. Overview of previous tests:
Server (FreeBSD): OpenVPN runs in TAP mode. A bridge (ifbridge) connects the physical network interface to the OpenVPN tap0 interface.
Client (FreeBSD): The client is also connected via OpenVPN, with its network interfaces configured to match the bridge.
Bridge function: Analysis with tcpdump has shown that the bridge on the server is functioning correctly. Network traffic (ARP) from the LAN is forwarded correctly through the tunnel to the client.

3. Current status and issue:
Although the data packets reach the client, it is not possible to establish a L3 connection. The client cannot be reached from the LAN via ping or similar tools. It seems that the client is not responding correctly to network requests, even though it is receiving them.

Has anyone experienced similar problems with L2 bridges under FreeBSD, or does anyone know what might be causing this one-way connection?

Thank you very much for your support.

##################
# Server Configuration #
##################

# ifconfig

Code:
vmx0:

flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1492
options=4e403bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6,HWSTATS,MEXTPG>
ether 00:13:23:02:15:01
inet XX3.XX9.XX4.XX0 netmask 0xfffffe00 broadcast XX3.XX9.XX5.XX<5
media: Ethernet autoselect
status: active
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>

vmx1 (trunc-port):
flags=1008943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
options=4a400b9<RXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,VLAN_HWTSO,RXCSUM_IPV6,HWSTATS,MEXTPG>
ether 00:13:26:03:06:00
media: Ethernet autoselect
status: active
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>

bridge0:
flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
options=0
ether 58:9c:fc:10:ff:e5
id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
maxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200
root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0
member:tap0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
ifmaxaddr 0 port 6 priority 128 path cost 2000000
member: vmx1 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
ifmaxaddr 0 port 2 priority 128 path cost 2000
groups: bridge
nd6 options=9<PERFORMNUD,IFDISABLED>

tap0:
flags=1008943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
options=4080000<LINKSTATE,MEXTPG>
ether 58:9c:fc:10:ff:fa
inet 172.16.50.240 netmask 0xfffffff0 broadcast 172.16.50.255
groups: tap
media: Ethernet 1000baseT
status: active
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
Opened by PID 29013


###############################
# OpenVPN Configuration VPN-BRIDGE #
###############################

Code:
port 1194
proto udp
dev tap0
vlan-tagging
topology subnet
mode server
tls-server

ca/usr/local/etc/openvpn/server/ca.crt
cert/usr/local/etc/openvpn/server/server.crt
key/usr/local/etc/openvpn/server/server.key
dh/usr/local/etc/openvpn/server/dh.pem

cipherAES-256-GCM
data-ciphersAES-256-GCM:AES-128-GCM:CHACHA20-POLY1305

ifconfig 172.16.50.240 255.255.255.240
ifconfig-pool 172.16.50.241 172.16.50.254 255.255.255.240

push "dhcp-option DNS 10.168.1.251"
push "dhcp-option DNS 10.168.1.254"

keepalive 10 60
persist-key
persist-tun

client-to-client

status/usr/local/etc/openvpn/openvpn-status.log
log-append/var/log/openvpn/openvpn.log
verb 3

##################
# Client Configuration #
##################

# ifconfig

Code:
vmx0:
flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1492
options=4e403bb<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,TSO4,TSO6,VLAN_HWTSO,RXCSUM_IPV6,TXCSUM_IPV6,HWSTATS,MEXTPG>
ether 00:14:26:03:09:00
inet XX1.XX3.XX7.XX1 netmask 0xffffff00 broadcast XX1.XX3.XX7.XX5
media: Ethernet autoselect
status: active
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>

vmx1 (trunc-port):
flags=1008943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
options=4a400b9<RXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,VLAN_HWTSO,RXCSUM_IPV6,HWSTATS,MEXTPG>
ether 00:14:26:03:09:01
media: Ethernet autoselect
status: active
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>

bridge0:
flags=1008843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
options=0
ether 58:9c:fc:10:d5:64
id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
maxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200
root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0
member: tap0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
ifmaxaddr 0 port 6 priority 128 path cost 2000000
member: vmx1 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
ifmaxaddr 0 port 2 priority 128 path cost 2000
groups: bridge
nd6 options=9<PERFORMNUD,IFDISABLED>

tap0:
flags=1008943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST,LOWER_UP> metric 0 mtu 1500
options=4080000<LINKSTATE,MEXTPG>
ether 58:9c:fc:10:ff:d3
inet 172.16.50.241 netmask 0xfffffff0 broadcast 172.16.50.255
groups: tap
media: Ethernet 1000baseT
status: active
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
Opened by PID 88029

##########################
# OpenVPN Client Configuration #
##########################

Code:
client
dev tap
proto udp
remote XX3.XX9.XX4.XX0 1194

ca /usr/local/etc/openvpn/keys/ca.crt
cert /usr/local/etc/openvpn/client/client.crt
key /usr/local/etc/openvpn/client/client.key

remote-cert-tls server

cipherAES-256-GCM
data-ciphersAES-256-GCM:AES-128-GCM:CHACHA20-POLY1305

persist-key
persist-tun

log /var/log/openvpn/client-openvpn.log
verb 3

EDIT: Code lines added.
 
The one-way connection you are describing is very typical of FreeBSD's bridge pfil behavior. By default FreeBSD filters traffic on bridge member interfaces using pf or ipfw, which blocks return packets even when outbound traffic passes fine. Check these two sysctl values:

sysctl net.link.bridge.pfil_member
sysctl net.link.bridge.pfil_bridge

If either is 1, your firewall is filtering traffic at the bridge level. For a transparent L2 bridge you usually want both to be 0, or you need specific firewall rules permitting bidirectional traffic on the bridge members:

sysctl net.link.bridge.pfil_member=0
sysctl net.link.bridge.pfil_bridge=0

To make it permanent add to /etc/sysctl.conf:
net.link.bridge.pfil_member=0
net.link.bridge.pfil_bridge=0

Second thing to check is STP convergence. Your bridge shows fwddelay 15, which means after the tunnel comes up the bridge sits in listening and learning states for 30 seconds before forwarding. During that window you can see ARP (because the bridge is learning) but actual traffic is dropped. You can force fast transition on both sides:

ifconfig bridge0 fwddelay 1

Third issue to check is the MTU chain. Your vmx0 (WAN) interface is at MTU 1492, which suggests PPPoE. OpenVPN adds its own encapsulation overhead on top of that. With UDP, a TAP frame of 1500 bytes will be fragmented or dropped. Add this to both server and client OpenVPN configs:

tun-mtu 1400
fragment 1300
mssfix 1260

Or use the simpler:
mtu-disc yes

Check with: ping -s 1400 <lan_host_ip> from inside the VPN client. If large pings fail but small ones succeed, it is definitly MTU.

Finally, verify tcpdump on the client side vmx1 (LAN) interface shows traffic arriving there, not just on tap0. If you see packets on tap0 but not vmx1, the bridge is not forwarding and pfil or STP is the cause.
 
Back
Top