Solved PF: TCP not working through NAT

I have a FreeBSD router where NAT is configured using PF, the NAT is working for ICMP and UDP, but not for TCP, whenever a TCP connection is attempted, I can see, from the PC in the LAN, the SYN packet going out and the SYN ACK packet coming in, but the client (web browser, ssh or whatever) keeps asking for the SYN ACK packet to be resent, I don't understand why.

This is the router config:

Code:
# cat /etc/pf.conf
ext_if = "dwc0"
int_if = "ue0"
localnet = $int_if:network
nat on $ext_if from $localnet to any -> ($ext_if)
pass from { lo0, $localnet } to any keep state

# ifconfig 
dwc0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=80008<VLAN_MTU,LINKSTATE>
        ether 02:c2:04:41:b1:cb
        hwaddr 02:c2:04:41:b1:cb
        inet 123.123.209.171 netmask 0xfffffe00 broadcast 123.123.209.255 
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
        options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
        inet 127.0.0.1 netmask 0xff000000 
        groups: lo 
pflog0: flags=141<UP,RUNNING,PROMISC> metric 0 mtu 33184
        groups: pflog 
ue0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=8000b<RXCSUM,TXCSUM,VLAN_MTU,LINKSTATE>
        ether 00:00:10:01:0c:6d
        hwaddr 00:00:10:01:0c:6d
        inet 192.168.9.106 netmask 0xffffff00 broadcast 192.168.9.255 
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active

# netstat -rn
Routing tables

Internet:
Destination        Gateway            Flags     Netif Expire
default            123.123.208.1      UGS        dwc0
127.0.0.1          link#2             UH          lo0
123.123.208.0/23   link#1             U          dwc0
123.123.209.171    link#1             UHS         lo0
192.168.9.0/24     link#4             U           ue0
192.168.9.106      link#4             UHS         lo0

# sysctl -a | grep forwarding
net.inet.ip.forwarding: 1

And this the LAN PC network config:
Code:
# ifconfig 
em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
    options=209b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,WOL_MAGIC>
    ether f0:de:f1:4d:45:58
    hwaddr f0:de:f1:4d:45:58
    inet 192.168.9.108 netmask 0xffffff00 broadcast 192.168.9.255 
    media: Ethernet autoselect (100baseTX <full-duplex>)
    status: active
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
    options=600003<RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6>
    inet 127.0.0.1 netmask 0xff000000 
    groups: lo 

# netstat -rn
Routing tables

Internet:
Destination        Gateway            Flags     Netif Expire
default            192.168.9.106      UGS         em0
127.0.0.1          link#2             UH          lo0
192.168.9.0/24     link#1             U           em0
192.168.9.108      link#1             UHS         lo0

In this screenshot taken from the LAN PC you can see how ICMP and UDP works, but not TCP:

2026-02-19-040318_1556x1028_scrot.png

The .pcapng from Wireshark is in the .zip file.

The problem is happening in all of the other machines in the LAN, so I guess the problem must be in the router.

Everything was working fine until I switched the public and private interfaces of the router because I was seeing strange behaviour in the public interface (now the private one), it kept going up and down several times in a second from time to time for no apparent reason, so I wonder if there could be a hardware problem with it, but now there is nothing strange in the router's logs.

Is there some kind of error counters associated with each network interface? I mean to check if there could be a hardware problem with it.

Of course I have tried different ethernet wires, reboot switches, the ISP cable modem, LAN machines... it makes no difference.
 

Attachments

You have an incorrect TCP checksum in the SYN+ACK packet. I suspect the problem is that you're using a USB ethernet device which lies about its ability to offload TCP checksums.

Disable checksum offload on ue0 and try again.
 
Thank you so much! you were right, just made:
Code:
# ifconfig ue0 -rxcsum -txcsum
And everything works perfect again ^_^
 
Back
Top