I have a setup where I use a Linux box with netfilter to forward tcp connections between a "client" and a "server. The Linux box has a default gateway defined. However, there are multiple other routers on the same network, and the default gateway router sends ICMP redirects to inform the Linux box which router should be used to reach some destination. In ascii art (somewhat simplified): |----| firewall |---| server | | | |----| routerA |------- | | def.gw | | Linux NAT | ------------| | |----| routerB |---------- | |----| routerC |----+----- | | | | | | | client | This works fine for traffic that originates on the Linux box. If I connect from the Linux NAT box to the client, the default gateway sends an ICMP redirect telling the Linux box to use routerC, and all further traffic then goes via that router. A lookup with "ip route get <client-IP>" also tells me that traffic goes via routerC. If the client connects to a service on the Linux NAT box, the packets sent from the Linux NAT box to the client also obey the routing defined by the ICMP redirect, and go via routerC. But when the connection is initiated by the client for a port that get's NAT'ed and forwarded to the server, then the packets going from the Linux NAT box to the client are sent to the default gateway, completely ignoring the route generated by the ICMP redirect. So: * client sends a SYN to Linux-NAT on port 1984 * Linux-NAT does SNAT+DNAT and forwards packet to server * server sends SYN+ACK to Linux-NAT box * Linux-NAT box does the necessary DNAT/SNAT and forwards SYN+ACK to client using routerA instead of via routerC Even though routerA sends an ICMP redirect telling Linux-NAT to use routerC, all of the packets from Linux-NAT to the client for this connection are sent via routerA. The iptables rules are simple. I use this in a script: /sbin/modprobe iptable_nat /sbin/iptables -t nat -A PREROUTING -p tcp --dport 1984 -j DNAT --to-destination IP.ADDR.OF.SERVER:1984 /sbin/iptables -t nat -A POSTROUTING -p tcp --dport 1984 -j SNAT --to-source IP.ADDR.OF.LINUX-NAT /sbin/sysctl -w net.ipv4.ip_forward=1 for f in /proc/sys/net/ipv4/conf/*/accept_redirects; do echo "1" >$f done giving me: # iptables -t nat -L Chain PREROUTING (policy ACCEPT) target prot opt source destination DNAT tcp -- anywhere anywhere tcp dpt:1984 to:IP.ADDR.OF.SERVER:1984 Chain POSTROUTING (policy ACCEPT) target prot opt source destination SNAT tcp -- anywhere anywhere tcp dpt:1984 to:IP.ADDR.OF.LINUX-NAT Chain OUTPUT (policy ACCEPT) target prot opt source destination # lsmod Module Size Used by Not tainted iptable_nat 15816 1 ip_conntrack 16488 1 [iptable_nat] ip_tables 14784 3 [iptable_nat] I've tried kernels 2.4.18 and 2.4.27. The Linux NAT box is running Debian/testing on an UltraSparc. The 2.4.18 kernel is the default Debian kernel; the 2.4.27 was compiled locally. The configuration is available if you need it. -- Henrik Storner