pengguang001
pengguang001

Reputation: 4205

ip_forward doesn't works for tcp

I have one linux box with 2 interfaces, wlan0 and wlan1. wlan0 connects to an external wlan AP of subnet 192.168.43.x. On wlan1 a softap is running on subnet 192.168.60.x.

I have run following commands to start nat and ip_forward:

iptables -F
iptables -F INPUT
iptables -F OUTPUT
iptables -F FORWARD
iptables -t nat -F
iptables -t mangle -F

iptables -A INPUT -j ACCEPT
iptables -A OUTPUT -j ACCEPT
iptables -A FORWARD -j ACCEPT
iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward

Another pc e6220 is connected to 192.168.60.x softap. I want to forward pc's traffic to external network 192.168.43.x.

network graph:

external AP (192.168.43.1) <~~~> {wlan0(192.168.43.2), <-- forward --> internal AP on wlan1(192.168.60.1)} <~~~> e6220 (192.168.60.46)

After adding route on pc, icmp and udp works fine, both can reach 192.168.43.1, but tcp doesn't work!

userg@e6220:~ $ ping 192.168.43.1
PING 192.168.43.1 (192.168.43.1) 56(84) bytes of data.
64 bytes from 192.168.43.1: icmp_seq=1 ttl=63 time=9.74 ms
64 bytes from 192.168.43.1: icmp_seq=2 ttl=63 time=9.57 ms
^C

user@e6220:~ $ telnet 192.168.43.1
Trying 192.168.43.1...
telnet: Unable to connect to remote host: Network is unreachable

Capture on linux box wlan1:

17:10:57.579994 IP 192.168.60.46.56412 > 192.168.43.1.telnet: Flags [S], seq     1764532258, win 29200, options [mss 1460,sackOK,TS val 2283575078 ecr 0,nop,wscale 7], length 0
17:10:57.580075 IP 192.168.60.1 > 192.168.60.46: ICMP net 192.168.43.1 unreachable, length 68

No packets seen on wlan0.

It's strange kernel says unreachable, but UDP works.

// route -n output
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.43.1    0.0.0.0         UG    0      0        0 wlan0
192.168.43.0    0.0.0.0         255.255.255.0   U     0      0        0 wlan0
192.168.60.0    0.0.0.0         255.255.255.0   U     0      0        0 wlan1

I think this may be kernel-version specific. On Linux 3.4.x both tcp and udp are good. This issue is seen on Linux 3.10.61. I want to know if there's any way to fix it, kernel configuration or iptables command. Thanks!

Upvotes: 1

Views: 1041

Answers (1)

pengguang001
pengguang001

Reputation: 4205

Finally I got the solution.

The routing box is configured with CONFIG_IP_MULTIPLE_TABLES, which is policy routing. The routing rule is:

# ip rule list
0:  from all lookup local 
10000:  from all fwmark 0xc0000/0xd0000 lookup legacy_system 
13000:  from all fwmark 0x10063/0x1ffff lookup local_network 
15000:  from all fwmark 0x0/0x10000 lookup legacy_system 
16000:  from all fwmark 0x0/0x10000 lookup legacy_network 
17000:  from all fwmark 0x0/0x10000 lookup local_network 
23000:  from all fwmark 0x0/0xffff uidrange 0-0 lookup main 
32000:  from all unreachable

So every packet goes to "unreachable". TCP turns good after adding following rules:

# ip rule add iif wlan0 table main
# ip rule add iff wlan1 table main

# ip rule list
0:  from all lookup local 
9998:   from all iif wlan0 lookup main 
9999:   from all iif wlan1 lookup main
10000:  from all fwmark 0xc0000/0xd0000 lookup legacy_system 
13000:  from all fwmark 0x10063/0x1ffff lookup local_network 
15000:  from all fwmark 0x0/0x10000 lookup legacy_system 
16000:  from all fwmark 0x0/0x10000 lookup legacy_network 
17000:  from all fwmark 0x0/0x10000 lookup local_network 
23000:  from all fwmark 0x0/0xffff uidrange 0-0 lookup main 
32000:  from all unreachable

But I still don't know why UDP is good before adding these 2 rules.

Upvotes: 1

Related Questions