Policy Based Routing allows the network admin to apply different forwarding rules to a packets based on some of its attributes. For example source address, QoS or firewall marks can be used as a packet classification policy.
Policy routing can help in meeting the requirements of differentiated services like QoS, security Policy etc where the traffic from customer paying for a better or more secure service is allowed to use a different network route that the regular traffic.
On Linux Policy Based Routing can be enabled in the following manner
- The first step is to classify the traffic into different categories based of conditions like source address, destination address, QoS or firewall mark etc.
- Then use different routing tables to forward traffic from different categories that was created in the first step
In this post we will setup a Linux based router with policy routing. For the purpose of our experiment, we will implement Policy based routing using source address as the classifier. The following topology describes the setup for our test
- We have 4 networks connecting host1, host2 and server to the router
|Network||Address||Gateway (Router)||Host Address|
|Net1||10.0.10.0/24||10.0.10.1 (router-eth1)||10.0.10.2 (host1-eth0)|
|Net2||10.0.11.0/24||10.0.11.1 (router-eth2)||10.0.11.2 (host2-eth0)|
|Net3||10.0.12.0/24||10.0.12.1 (router-eth3)||10.0.12.2 (server-eth0)|
|Net4||10.0.13.0/24||10.0.13.1 (router-eth4)||10.0.13.2 (server-eth1)|
- The server holds the IP 188.8.131.52/24, which is the destination the hosts are trying to reach.
- The router has two paths to forward the packets arriving from host1 and host2 to destination 184.108.40.206, either using the 10.0.12.0/24 or 10.0.13.0/24 network.
- To begin with the server and the router is configured with static routes to use only one link (router-eth3 <-> server-eth0 i.e. 10.0.12.0/24 network) to forward traffic between router and server
Start the simulated topology using the following command(using the policy_routing_disabled.py file from the repository).
sudo python policy_routing_disabled.py
We will start with a topology with disabled policy routing and learn the steps need to enable policy routing. (if you want a ready made mininet topology with policy routing look at policy_routing_enabled.py file that implements this)
The mininet configuration implements the hosts, server nodes as network namespaces, and the router is implemented by using the Linux host itself.
Once the topology is ready try to ping the IP 220.127.116.11 located on the server from the hosts.
Note: In the mininet CLI, a command can be started on a node by providing the node name followed by the command like in the form “<node_name> <command> <argument1> <argument2> …”
mininet> host1 ping 18.104.22.168 mininet> host2 ping 22.214.171.124
Without the policy routing in place the packets are forwarded using one of the path(10.0.12.0/24 network, net3). You can verify this by running the following command on the router (as the Linux host is acting as the router the following command can be started on another terminal).
$ watch "egrep router-eth.* /proc/net/dev"
Note the interface statistics of router-eth4 does not change when ping packets are transmitted either from host1 or host2 to server.
Lets remove the static route setting on the router and modify the one on server as shown below
mininet> router route del -net 126.96.36.199/24 dev router-eth3 mininet> server ip route del 10.0.11.0/24 via 10.0.12.1 mininet> server ip route add 10.0.11.0/24 via 10.0.13.1
We can now proceed to enable policy routing.
Enabling policy routing
Lets now start configuring the policy routing
- Classify the traffic arriving on the router based on source network to use different routing table. The following commands add classification policy on the router, which in this case is the source network.
mininet> router ip rule add from 10.0.10.0/24 lookup net1_table mininet> router ip rule add from 10.0.11.0/24 lookup net2_table
- Add the routing tables
mininet> router echo "101 net1_table">> /etc/iproute2/rt_tables mininet> router echo "102 net2_table">> /etc/iproute2/rt_tables
- Add routes to the individual table. The following routes add different path to reach destination network 188.8.131.52/24
mininet> router ip route add 184.108.40.206/24 via 10.0.12.2 table net1_table mininet> router ip route add 220.127.116.11/24 via 10.0.13.2 table net2_table
With the above settings in place, the routing rules from net1_table are applied to packets arriving from network 10.0.10.0/24 (net1) and rules from net2_table are applied to packets arriving from network 10.0.11.0/24 (net2).
Verifying the result
Use the following command on the mininet prompt to start a xterm connected to router.
mininet> xterm router
Use the xterm to start a watch command on all interfaces of the router
(router xterm) $ watch "egrep router-eth.* /proc/net/dev"
Now start a ping from host1 to 18.104.22.168 and check the output to verify that the packets are forwarded using eth3 interface on the router
mininet> host1 ping 22.214.171.124
The same steps can be used to verify that if the ping is started from host2 to 10.0.14.1 eth4 interface on the router
Here are the example output.
Send 10 Ping packets from Host1:
Send 10 Ping packets from Host2:
The results show that the traffic from host1 which arrives on the router interface router-eth1 is forwarded using 10.0.12.0/24 network through router interface router-eth3 and traffic from host2 which arrives on the router interface router-eth2 is forwarded using 10.0.13.0/24 network through router interface router-eth4
The following figure shows the change in traffic flow due to policy based routing configuration
The final settings with policy routing enabled is also available as a mininet configuration as policy_routing_enabled.py in the repository.
In this experiment we started with a setup where the router had two paths to the destination server but was using only one to forward traffic. With the help of policy routing we were able to utilize both the path to communicate with the server.
The traffic was distributed based on the source address. i.e. packets coming from net1(10.0.10.0/24) is forwarded over net3(10.0.12.0/24) while that from net2(10.0.11.0/24) is forwarded over net4(10.0.13.0/24).