Switching and Routing
In this tutorial, we are going to discuss about basis networking concepts like switching, routing and gateways etc.
What is network?
We have two computers A and B, laptops, desktops, VMs on the cloud, wherever. How does system A reach B?
We connect them to a switch, and the switch creates a network containing the two systems. To connect them to a switch we need an interface on each host. Physical or virtual depending on the host to see the interfaces for the host. We use the IP link command.
In this case, we look at the interface named eth0 that we will be using to connect to the switch. Let’s assume it’s a network with the address 192.168.1.0. We then assign the systems with IP addresses on the same network. For this, we use the command ip addr.
$ ip addr add 192.168.1.10/24 dev eth0 $ ip addr add 192.168.1.11/24 dev eth0
Once the links are up, and the IP addresses are assigned, The computers can now communicate with each other through the switch.
The switch can only enable communication within and network which means it can receive packets from a host on the network and deliver it to other systems within the same network.
Say we have another network containing systems C & D at address 192.168.2.0. The Systems have IP address 192.168.2.10 and 2.11 respectively. How does a system in one network reach a system in the other?
How does System B with the IP 192.168.1.11 reach system C with the IP 2.10 on the other network. That’s where a Router comes in.
A Router helps connect two networks together. It is an intelligent device, so think of it as another server with many network ports.
Since it connects to the two separate networks, it gets two IPs assigned. One on each network. In the first network we assign it an IP address 192.168.1.1 and in the second we assign it an IP 192.168.2.1.
Now we have a router connected to the two networks that can enable communication between them.
Now, when system B tries to send a packet to system C, how does it know where the router is on the network to send the packet through the router is just another device on the network. There could be many other such devices. That’s where we configure the systems with a gateway or a route.
If the network was a room, the gateway is a door to the outside world to other networks or to the Internet. The systems need to know where that door is to go through that to see the existing routing configuration on a system run the following command.
$ route Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface
Above command displays the kernels routing table and within that, as you can see there are no routing configurations as of now.
So in this condition your system B will not be able to reach system C it can only reach other systems within the same network in the range 192.168.1.0.
To configure a gateway on system B to reach the systems on network 192.168.2.0, run the ip route add command, and specify that you can reach the 192.168.2.0 network through the door or gateway at 192.168.1.11.
$ ip route add 192.168.1.0/24 via 192.168.2.1
Now running the route command again
$ route Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.2.0 192.168.1.1 255.255.255.0 UG 0 0 0 eth0
Now remember this has to be configured on all the systems. For example, if the system C is to send a packet to system B, then you need to add a route on system C routing table to access network 192.168.1.0 through the router configured with the IP address 192.168.2.1.
Now suppose these systems need access to the Internet. Say they need access to Google at 22.214.171.124 network on the internet. So you connect the router to the internet.
$ ip route add 126.96.36.199/24 via 192.168.2.1
There are so many different sites on different networks on the Internet instead of adding a routing table entry for these same routers IP address for each of those networks you can simply say for any network that you don’t know a route to use this router as the default gateway.
This way any request to any network outside of your existing network goes to this particular router.
So in a simple setup like this, all you need is a single routing table entry with a default gateway set to the routers IP address.
$ ip route add default via 192.168.2.1
Remember instead of the word default you could also say 0.0.0.0. It means any IP destination. Both of these lines mean the same thing. A 0.0.0.0 Entry in the Gateway field indicates that you don’t need a gateway.
$ route Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.2.0 192.168.1.1 255.255.255.0 UG 0 0 0 eth0 default 192.168.2.1 255.255.255.0 UG 0 0 0 eth0 192.168.2.0 0.0.0.0 255.255.255.0 UG 0 0 0 eth0
For example, in this case for system C to access any devices in the 192.168.2.0 network. It doesn’t need a gateway because it is in its own network. But say you have multiple routers in your network one for the Internet another for the internal private network then you will need to have two separate entries for each network.
$ route Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface default 192.168.2.1 255.255.255.0 UG 0 0 0 eth0 192.168.1.0 192.168.2.2 255.255.255.0 UG 0 0 0 eth0
One entry for the internal private network and another entry with the default gateway for all other networks including public networks.
So if you are having issues reaching internet from your systems, This routing table and the default gateway configuration is a good place to start.
Set up a Linux host as a router
Let us now look at how we can set up a Linux host as a router. Let’s start with a simple setup. I have 3 hosts A, B and C. A and B are connected to a network 192.168.1 and B and C to another on 192.168.2.
So host B is connected to both the networks using two interfaces eth0 and eth1. A has IP 192.168.1.5, C has 192.168.2.5 and B has an IP on both the networks. 192.168.1.6 and 192.168.2.6.
Now how do we get A to talk to C? Basically, if I try to ping 192.168.2.5 from A, it would say Network is Unreachable. And by now we know why that is. Host A has no idea how to reach a network at 192.168.2.
We need to tell host A that the door or gateway to network 2 is through host B. And we do that by adding a routing table entry. We add a route to access network 192.168.2 via the gateway 192.168.1.6.
$ ip route add 192.168.2.0/24 via 192.168.1.6
If the packets where to get through to Host C, Host C will have to send back responses to Host A. When Host C tries to reach Host A at 192.168.1 network, it would face the same issue. So we need to let know Host C know that it can reach Host A through Host B which is acting as a router.
So we add a similar entry into Host C’s routing table. This time we say to reach network 192.168.1.0, talk to Host B at 192.168.2.6.
$ ip route add 192.168.1.0/24 via 192.168.2.6
When we try to ping now, we no longer get the Network Unreachable error message that means our routing entries are right but we still don’t get any response back.
By default, in Linux, packets are not forwarded from one interface to the next. For example packets received on eth0 on host B are not forwarded to elsewhere through eth1. This is this way for security reasons.
For example, if you had eth0 connected to your private network and eth1 to a public network, we don’t want anyone from the public network to easily send messages to the private network unless you explicitly allow that.
But in this case since we know that both are private networks and it is safe to enable communication between them. We can allow host B to forward packets from one network to the other whether a host can forward packets between interfaces is governed by a setting in this system at file /proc/sys/net/ipv4/ip.
By default, the value in this file is set to 0 meaning no forward set this to 1 and you should see the pings go through. Now remember simply setting this value does not persist the changes across reboots for that you must modify the same value in the /etc/sysctl.conf file.
$ cat /etc/sysctl.conf Uncomment the line net.ipv4.ip_forward=1
To view the sysctl variables, run the following command
$ sysctl -a
To reload the sysctl configuration, run the following command
$ sysctl --system