We all know that Routers are Layer3 devices and switches are Layer2. So how can a Layer 3 device be used to connect two or more devices at Layer2 ?
In this blog, I will explore the mechanisms that make it possible to use a routing device as a switch.
The test setup
We start with a simple setup with three Linux Network Namespaces connected in series. The middle node acting as a Router and the end nodes acting as the devices that needs a layer 2 connectivity.
Use the following script for setting up the Namespaces and connections.
The script adds the following IP addresses to the device nodes.
In this setup, we have two Layer2 broadcast domain A and B connected using the router.
It doesn’t work, testing what’s is going on
Now we have two devices in the same Subnet connected using a Router instead of a switch. Start a ping form one device node to the other and predictably this does not work. But running tcpdump can give you an insight on to the traffic flow.
node_1 > ping 126.96.36.199 PING 188.8.131.52 (184.108.40.206) 56(84) bytes of data. From 220.127.116.11 icmp_seq=1 Destination Host Unreachable From 18.104.22.168 icmp_seq=2 Destination Host Unreachable From 22.214.171.124 icmp_seq=3 Destination Host Unreachable ^C --- 126.96.36.199 ping statistics --- 5 packets transmitted, 0 received, +3 errors, 100% packet loss, time 4024ms
And following is the tcpdump output
vrouter1 > sudo tcpdump -i vr_if1 -n tcpdump: WARNING: vr_if1: no IPv4 address assigned tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on vr_if1, link-type EN10MB (Ethernet), capture size 65535 bytes ^C 13:29:08.265464 ARP, Request who-has 188.8.131.52 tell 184.108.40.206, length 28 13:29:09.263145 ARP, Request who-has 220.127.116.11 tell 18.104.22.168, length 28 13:29:10.263058 ARP, Request who-has 22.214.171.124 tell 126.96.36.199, length 28 13:29:11.280501 ARP, Request who-has 188.8.131.52 tell 184.108.40.206, length 28 13:29:12.278951 ARP, Request who-has 220.127.116.11 tell 18.104.22.168, length 28
The ARP requests are not resolving.
As the device nodes are part of the same subnet, when we try to ping one of the device node from another, the first device node sends ARP queries to find the Layer2 address for the destination IP. ARP uses Layer2 broadcast to for finding the MAC address of the destination. As our destination is not part of the same Layer2 domain the ARP query broadcast will never reach it and will never be answered.
The missing link that will make it work
We saw in the previous section the problem of unresolved ARP queries.
So how do we rescue this situation?
To make this setup work we will need to enable Proxy ARP on the Router. When Proxy ARP is enabled on the router interfaces, the interface starts responding to the ARP query requests from the device nodes with its own MAC (Layer2) address. In a way, it proxies for a device(with the destination IP) which is actually not present on the Layer2 network.
To enable proxy ARP on the router, use the following commands.
vrouter1 > echo 1 > /proc/sys/net/ipv4/conf/vr_if1/proxy_arp vrouter1 > echo 1 > /proc/sys/net/ipv4/conf/vr_if2/proxy_arp
Taste of success
So now the ARP problem is resolved. The device node gets a reply of its ARP query with a MAC address which actually belongs to the interface of the router. The device now knows what MAC address associated to the destination IP.
But the pings are still failing.
This is because we have solved only half the problem.
What does the Router do with the packet that it received? Once the Layer2 frame arrives on the router, it removes the Layer2 header and looks at the IP address. It obviously does not hold the destination IP.
So, the router does what the router does with any other IP packet, looks up the routing table.
To make the ping work, we will have to add host routes to the destination IP address on the router.
The following commands will achieve our goal.
vrouter1 > ip route add 22.214.171.124/32 dev vr_if1 vrouter1 > ip route add 126.96.36.199/32 dev vr_if2
This is how the routing table on the router looks like
vrouter1 > route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 188.8.131.52 0.0.0.0 255.255.255.255 UH 0 0 0 vr_if1 184.108.40.206 0.0.0.0 255.255.255.255 UH 0 0 0 vr_if2
One more thing to keep in mind. Don’t forget to enable IP forwarding on your router.
vrouter1 > echo 1 > /proc/sys/net/ipv4/ip_forward
Finally, we can test the end to end traffic flow 🙂
node_1 > ping 220.127.116.11 PING 18.104.22.168 (22.214.171.124) 56(84) bytes of data. 64 bytes from 126.96.36.199: icmp_seq=1 ttl=63 time=0.167 ms 64 bytes from 188.8.131.52: icmp_seq=2 ttl=63 time=0.061 ms ^C --- 184.108.40.206 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 0.061/0.114/0.167/0.053 ms