Hello,
I am trying to do something very simple, but it appears it is not so simple to implement after all…
I have a router x86_64 with the latest OpenWrt 22.03.
I have 2 WAN accesses: one through classical physical ethernet (DHCP, etc.), the other through a GRE tunnel.
To simplify, lets call IfA the interface carrying the connection through physical ethernet, with public ip IPA, and IfB the interface carrying the connection through the tunnel, with public ip IPB.
All works fine; my default route is through the tunnel IfB, and I can specifically choose from which WAN I want to go using routing rules if needed.
Now, I want to be able to ping IPA from IfB, and have the packets go through IfB, like this:
Echo Request to IPA -> IfB -> WAN -> IfA | Echo Request to IPB -> IfA -> WAN -> IfB
And the opposite:
Echo Request to IPB -> IfA -> WAN -> IfB | Echo Request to IPA -> IfB -> WAN -> IfA
I made the following routing changes:
root@OpenWrt:~# ip ru
0: from IPA to IPB lookup 1000
0: from IPB to IPA lookup 2000
10: from all lookup local
root@OpenWrt:~# ip r show table 1000
default IfA-GW dev IfA proto static src IPA
root@OpenWrt:~# ip r show table 2000
default dev IfB proto static scope link src IPB mtu 1476
This allows to bypass the loopback and force the packets to go through WAN.
Then in firewall config, I added this:
config rule
option name 'Test1'
list proto 'all'
list src_ip 'IPA'
list dest_ip 'IPB'
option target 'ACCEPT'
option dest '*'
config rule
option name 'Test2'
list proto 'all'
list src_ip 'IPA'
list dest_ip 'IPB'
option target 'ACCEPT'
option src '*'
config rule
option name 'Test3'
list proto 'all'
list src_ip 'IPB'
list dest_ip 'IPA'
option target 'ACCEPT'
option dest '*'
config rule
option name 'Test4'
list proto 'all'
list src_ip 'IPB'
list dest_ip 'IPA'
option target 'ACCEPT'
option src '*'
config rule
option name 'Test5'
list proto 'all'
option src '*'
list src_ip 'IPA'
option dest '*'
list dest_ip 'IPB'
option target 'ACCEPT'
config rule
option name 'Test6'
list proto 'all'
option src '*'
list src_ip 'IPB'
option dest '*'
list dest_ip 'IPA'
option target 'ACCEPT'
config rule
option name 'Test7'
list proto 'all'
list src_ip 'IPA'
list dest_ip 'IPB'
option target 'ACCEPT'
config rule
option name 'Test8'
list proto 'all'
list dest_ip 'IPA'
list src_ip 'IPB'
option target 'ACCEPT'
This should cover all the scenarios to allow any traffic between IPA and IPB whatever the direction.
Now, here is what happens when I ping IPA from IfB:
root@OpenWrt:~# ping -I IfB IPA
PING IPA (IPA) from IPB IfB: 56(84) bytes of data.
^C
--- IPA ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2054ms
BUT a simultaneous tcpdump show this:
root@OpenWrt:~# tcpdump -i IfB -enn net IPA/32
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on IfB, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes
13:49:34.414150 Out ethertype IPv4 (0x0800), length 100: IPB > IPA: ICMP echo request, id 63335, seq 1, length 64
13:49:34.429451 In ethertype IPv4 (0x0800), length 100: IPA > IPB: ICMP echo reply, id 63335, seq 1, length 64
13:49:35.438756 Out ethertype IPv4 (0x0800), length 100: IPB > IPA: ICMP echo request, id 63335, seq 2, length 64
13:49:35.454228 In ethertype IPv4 (0x0800), length 100: IPA > IPB: ICMP echo reply, id 63335, seq 2, length 64
13:49:36.468736 Out ethertype IPv4 (0x0800), length 100: IPB > IPA: ICMP echo request, id 63335, seq 3, length 64
13:49:36.484763 In ethertype IPv4 (0x0800), length 100: IPA > IPB: ICMP echo reply, id 63335, seq 3, length 64
^C
6 packets captured
6 packets received by filter
0 packets dropped by kernel
And a tcpdump -i IfA -enn net IPB/32 shows also the requests and replies from IfA POV.
Problem 1: it appears that the packets are taking the correct route, bypassing the local loopback, are arriving, the reply is issued and sent back then received, but… the ping process does not see the replies
__
Now in the other direction, here is what happens when I ping IPB from IfA:
root@OpenWrt:~# ping -I IfA IPB
PING IPB (IPB) from IPA IfA: 56(84) bytes of data.
^C
--- IPB ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2080ms
And the tcpdump:
root@OpenWrt:~# tcpdump -i IfB -enn net IPA/32
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on gre4-mw_tunnel, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes
13:57:56.156728 In ethertype IPv4 (0x0800), length 100: IPA > IPB: ICMP echo request, id 2588, seq 1, length 64
13:57:57.156366 In ethertype IPv4 (0x0800), length 100: IPA > IPB: ICMP echo request, id 2588, seq 2, length 64
13:57:58.236551 In ethertype IPv4 (0x0800), length 100: IPA > IPB: ICMP echo request, id 2588, seq 3, length 64
^C
3 packets captured
3 packets received by filter
0 packets dropped by kernel
And same if I do a tcpdump -i IfA -enn net IPB/32 I only see echo requests.
Problem 2: the echo requests packets are taking the correct route, bypassing the local loopback, are arriving, but no reply is even issued this time…
__
Any idea of what is going on?
Any suggestion for a better way to implement what I am trying to do?
I tried with ip netns a veth bridged to IfA, but since it needs to be forwarded on the main namespace, I have the exact same problem with loopback that without namespaces… I could put the IfB tunnel in its own netspace, but OpenWrt and mostly LuCi is not designed for that and that would make this simple thing very complicated at the end.
Thank you for reading and for your help.