Assuming you have your Linux Core compiled with enabled option MULTIPATH, we are going to create simple lab to demonstrate existence of multiple equal-cost routes in the kernel routing table.
Picture 1 - Testing equal-cost routes
They are two Core boxes presented in our testing topology. Boxes are connected with point-to-point Layer 3 links, residing on separate subnets.
They both have Quagga routing suite installed and OSPF protocol enabled and configured. On router R1, Openvswitch is configured and interface vlan10 is created.
If kernel was successfully compiled with Multipath option in part2, a network 192.168.10.0/24 should be accessible via two possible routes from R2. Two next hop interfaces - 192.168.1.1/30 and 192.168.2.1/30 should be presented in both - Quagga and kernel routing table, pointing to the network 192.168.10.0/24.
Note: Kernel IP routing table is immediately updated by Quagga if change occurs.
The next few steps will help you to configure both routers. It is not need to configure both Quagga and Microcore form scratch, basic configuration such as starting daemons and creating and backup of configuration files had been done for you. You only need to configure R1 and R2 according to topology.
Core Qemu and VirtualBox images with Quagga and Openvswitch installed together with other networking utilities are available here:
1. R2 configuration
a) Configure the hostname and backup the content of /opt/bootlocal.sh file
echo "hostname R2" >> /opt/bootlocal.sh
sudo hostname R2
/usr/bin/filetool.sh -b
b) Start Quagga vtysh shell and configure R2 router
sudo vtysh
Hello, this is Quagga (version 0.99.20).
Copyright 1996-2005 Kunihiro Ishiguro, et al.
Router2# conf t
Router2(config)# interface eth0
Router2(config-if)# description Link to R1
Router2(config-if)# ip address 192.168.1.2/30
Router2(config-if)# no shutdown
Router2(config-if)# interface eth1
Router2(config-if)# description Link to R1
Router2(config-if)# ip address 192.168.2.2/30
Router2(config-if)# no shutdown
Router2(config-if)# router ospf
Router2(config-router)# network 192.168.1.0/30 area 0
Router2(config-router)# network 192.168.2.0/30 area 0
Router2(config-router)# do write
Exit from vtysh shell and save Quagga configuration files from MIcrocore shell.
/usr/bin/filetool.sh -b
2. R1 configuration
a) Configure the hostname and backup content of /opt/bootlocal.sh file
echo "hostname R1" >> /opt/bootlocal.sh
sudo hostname R1
/usr/bin/filetool.sh -b
b) Configure Openvswitch - create interface vlan10
sudo ovs-vsctl add-br br0
sudo ovs-vsctl add-port br0 vlan10 tag=10 -- set interface vlan10 type=internal
Save Openvswitch database.
/usr/bin/filetool.sh -b
c) Start Quagga vtysh shell and configure router
sudo vtysh
Hello, this is Quagga (version 0.99.20).
Copyright 1996-2005 Kunihiro Ishiguro, et al.
Router1# conf t
Router1(config)# interface eth0
Router1(config-if)# description Link to R2
Router2(config-if)# ip address 192.168.1.1/30
Router1(config-if)# no shutdown
Router1(config-if)# interface eth1
Router1(config-if)# description Link to R2
Router1(config-if)# ip address 192.168.2.1/30
Router1(config-if)# no shutdown
Router1(config-if)# interface vlan10
Router1(config-if)# description Virtual interface for vlan10
Router1(config-if)# ip address 192.168.10.1/24
Router1(config-if)# no shutdown
Router1(config-if)# router ospf
Router1(config-router)# network 192.168.1.0/30 area 0
Router1(config-router)# network 192.168.2.0/30 area 0
Router1(config-router)# network 192.168.10.0/24 area 0
Router1(config-router)# do write
Exit from vtysh shell and save Quagga configuration files from Core shell.
/usr/bin/filetool.sh -b
3. Testing
a) Check if 192.168.10.0/24 is established in Quagga routing table on R2
sudo vtysh
Router2# show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF,
I - ISIS, B - BGP, > - selected route, * - FIB route
C>* 127.0.0.0/8 is directly connected, lo
K>* 127.0.0.1/32 is directly connected, lo
O 192.168.1.0/30 [110/10] is directly connected, eth0, 01:54:15
C>* 192.168.1.0/30 is directly connected, eth0
O 192.168.2.0/30 [110/10] is directly connected, eth1, 01:54:15
C>* 192.168.2.0/30 is directly connected, eth1
O>* 192.168.10.0/24 [110/20] via 192.168.1.1, eth0, 01:53:18
* via 192.168.2.1, eth1, 01:53:18
As we can see from Quagga IP routing table, two next hop interfaces eth0 and eth1 are shown to network 192.168.10.0/24.
b) Check if 192.168.10.0/24 is established in a kernel IP routing table on R2
Exit from vtysh shell and check kernel routing table.
tc@Router2:~$ route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
127.0.0.1 * 255.255.255.255 UH 0 0 0 lo
192.168.1.0 * 255.255.255.252 U 0 0 0 eth0
192.168.2.0 * 255.255.255.252 U 0 0 0 eth1
192.168.10.0 192.168.1.1 255.255.255.0 UG 20 0 0 eth0
Command "route" lists only one path to the network 192.168.10.0/24 via next hop interface 192.168.1.1. The newer "ip" command should be used to see multiple equal-cost routes.
tc@Router2:~$ ip route show
127.0.0.1 dev lo scope link
192.168.1.0/30 dev eth0 proto kernel scope link src 192.168.1.2
192.168.2.0/30 dev eth1 proto kernel scope link src 192.168.2.2
192.168.10.0/24 proto zebra metric 20
nexthop via 192.168.1.1 dev eth0 weight 1
nexthop via 192.168.2.1 dev eth1 weight 1
Two next hop interfaces are listed in the output of ip command for network 192.168.10.0/24.
c) Test connectivity with ping command. Use Ctrl-c to break sequence
tc@Router2:~$ ping 192.168.10.1
PING 192.168.10.1 (192.168.10.1): 56 data bytes
64 bytes from 192.168.10.1: seq=0 ttl=64 time=1.581 ms
64 bytes from 192.168.10.1: seq=1 ttl=64 time=1.208 ms
64 bytes from 192.168.10.1: seq=2 ttl=64 time=2.324 ms
--- 192.168.10.1 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 1.208/1.704/2.324 ms
d) Testing if packet loss occurs when primary interface fails
Studying output of "route" command on R2, we notice that packets sent to the network 192.168.10.0/24 are forwarded to next hop IP address 192.168.1.1 via local interface eth0.
Now, start pinging IP address 192.168.10.1 from router R2. During ping, shutdown eth0 interface on R1. Check if series of pings is interrupted or not.
tc@Router2:~$ ping 192.168.10.1
PING 192.168.10.1 (192.168.10.1): 56 data bytes
64 bytes from 192.168.10.1: seq=0 ttl=64 time=1.042 ms
64 bytes from 192.168.10.1: seq=1 ttl=64 time=2.380 ms
64 bytes from 192.168.10.1: seq=2 ttl=64 time=1.216 ms
<output truncated>
--- 192.168.10.1 ping statistics ---
37 packets transmitted, 37 packets received, 0% packet loss
round-trip min/avg/max = 0.587/1.599/4.758 ms
Regarding statistics of ping command, we cannot see any packet loss. The benefit of multiple equal-cost paths is that in case of primary route failure, packets are immediately forwarded via backup available path.
Check the kernel routing table on R2 for changes.
tc@Router2:~$ ip route show
127.0.0.1 dev lo scope link
192.168.1.0/30 dev eth0 proto kernel scope link src 192.168.1.2
192.168.2.0/30 dev eth1 proto kernel scope link src 192.168.2.2
192.168.10.0/24 via 192.168.2.1 dev eth1 proto zebra metric 20
Not surprisingly, the only one path exists to the network 192.168.10.0/24.
END.
Hello.
Some month ago tested the same scenario. And I want to notice that:
The flow of packets is not balanced by kernel between two next-hops and flows only via one of them due to cached route, which we can see using "ip route show cached".
Another one hop will be used only when cache is expired and new packet will pass the rib.
I didn't find any way to configure balancer, for example by packet, or by flow(src ip, dst ip), or somehow else.