I am trying 1:1 stateless NAT traffic.  The traffic is coming in via a GRE tunnel and exiting via a VPN.  I have done enough research to understand that traffic entering a linux box off of the GRE tunnel does not hit Conntrack and also will not hit iptables -t nat. iptales SNAT, DNAT or NETMAP all are required to be in the -t nat table.There was a iproute2 stateless nat option, but it was removed in kernel version 2.6.  Before that was removed you could do a ip route add nat 192.168.50.2 via 192.168.60.2When the stateless nat was removed from iproute2, there was an RAWDNAT and RAWSNAT option in Xtables-addons package.  Xtables-addons.  Xtables-addons documentation still offers RAWDNAT and RAWSNAT as options, but they throw errors and Xtables-addons remove RAWSNAT/RAWDNATSo that has now put me into the world of Traffic Control.  Traffic control documentation is very sparse and hard to follow.  Especially for the ingress handling.  So I have broken the problem down and now I am just trying to get a 1:1 simple stateless nat working using tc over my eth0.  I have a box that has an address 192.168.234.5 and a route to 10.40.0.0/16.  I am trying to nat 192.168.234.112 to 10.40.0.112, in both directions.For the inbound packet coming from 10.40.0.112:tc qdisc add dev eth0 ingresstc filter add dev eth0 parent ffff: protocol ip prio 10 \  u32 match ip src 10.40.0.112/32 \  action nat ingress 10.40.0.112/32 192.168.234.112and for outbound packetstc qdisc add dev eth0 root handle 1: htbtc filter add dev eth1 parent 1: protocol ip prio 10 \   u32 match ip dst 192.168.234.112/32 \   action nat egress 192.168.234.112/32 10.40.0.112 Somehow I was actually able to get the above commands to work, but for the life of me I can no longer get them to work.  I found a post on stackoverflow.com that had stated something about the default qdisc in Ubuntu (pfifo_fast) is classless so it does not provide for packet filtering, but I can not longer follow that post.  You would think that tc filter add would provide an error message if you add to a qdisc that does not support filters, but this seems to succeed.So here are the commands that I am running:add the egress qdisc first so the ingress has something to attach totc qdisc add dev eth0 root handle 1: htbtc qdisc add dev eth0 ingressAt this point tc qdisc reportsqdisc htb 1: dev eth0 root refcnt 2 r2q 10 default 0 direct_packets_stat 9 direct_qlen 1000qdisc ingress ffff: dev eth0 parent ffff:fff1 ---------------- qdisc pfifo_fast 0: dev eth1 root refcnt 2 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1Now adding the ingress filter like: tc filter add dev eth0 parent ffff: protocol ip prio 10 \   u32 match ip src 10.40.0.112/32 \   action nat ingress 10.40.0.112/32 192.168.234.112At this point if I ping 10.40.0.112, I would expect the answer to come from 192.168.234.112.  But the filter never gets hit.  Actually I never see the nat action applied to the packet, but the stats for that filter rule go up.I would add the egress filter like:tc filter add dev eth0 parent 1: protocol ip prio 10 \    u32 match ip dst 192.168.234.112/32 \   action nat egress 192.168.234.112/32 10.40.0.112At this point the tc filters look like: root@ubusswan1-VirtualBox:/home/ubusswan1# tc filter show dev eth0filter parent 1: protocol ip pref 10 u32 filter parent 1: protocol ip pref 10 u32 fh 800: ht divisor 1 filter parent 1: protocol ip pref 10 u32 fh 800::800 order 2048 key ht 800 bkt 0 terminal flowid ???   match c0a8ea70/ffffffff at 16    action order 1:  nat egress 192.168.234.112/32 10.40.0.112 passroot@ubusswan1-VirtualBox:/home/ubusswan1# tc filter show dev eth0 rootfilter parent ffff: protocol ip pref 10 u32 filter parent ffff: protocol ip pref 10 u32 fh 800: ht divisor 1 filter parent ffff: protocol ip pref 10 u32 fh 800::800 order 2048 key ht 800 bkt 0 terminal flowid ???   match 0a280070/ffffffff at 12    action order 1:  nat ingress 10.40.0.112/32 192.168.234.112 pass Can you help me understand tc well enough to get this 1:1 nat going?  Also is there a better way to debug tc filters that are not working?
1:1 Stateless NAT kernel version 3.16 or later using TC
linux;nat