documentation:examples:ecmp
                Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| documentation:examples:ecmp [2020/01/26 19:46] – [Testing Load balancing] olivier | documentation:examples:ecmp [2025/01/17 18:53] (current) – [R2 (ECMP router)] olivier | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ====== Equal-cost multi-path routing (ECMP) ====== | ====== Equal-cost multi-path routing (ECMP) ====== | ||
| - | |||
| - | This lab is testing new ECMP routing code. | ||
| ===== Presentation ===== | ===== Presentation ===== | ||
| + | <note warning> | ||
| ==== Network diagram ==== | ==== Network diagram ==== | ||
| Here is the logical and physical view: | Here is the logical and physical view: | ||
| - | {{: | + | {{: | 
| ===== Setting-up the lab ===== | ===== Setting-up the lab ===== | ||
| Line 15: | Line 14: | ||
| ==== Downloading BSD Router Project images ==== | ==== Downloading BSD Router Project images ==== | ||
| - | Download BSDRP serial image (prevent to have to use an X display)  | + | Download BSDRP serial image on Sourceforge  | 
| - | ==== Download Lab scripts ===== | ||
| - | |||
| - | More information on these BSDRP lab scripts available on [[documentation: | ||
| - | |||
| - | Start the lab with 6 routers. | ||
| - | With bhyve under FreeBSD: | ||
| - | < | ||
| - | user:~ # BSDRP-lab-bhyve.sh -i BSDRP.amd64/ | ||
| - | BSD Router Project (http:// | ||
| - | Setting-up a virtual lab with 6 VM(s): | ||
| - | - Working directory: /tmp/BSDRP | ||
| - | - Each VM have 1 core(s) and 256M RAM | ||
| - | - Switch mode: bridge + tap | ||
| - | - 0 LAN(s) between all VM | ||
| - | - Full mesh Ethernet links between each VM | ||
| - | VM 1 have the following NIC: | ||
| - | - vtnet0 connected to VM 2. | ||
| - | - vtnet1 connected to VM 3. | ||
| - | - vtnet2 connected to VM 4. | ||
| - | - vtnet3 connected to VM 5. | ||
| - | - vtnet4 connected to VM 6. | ||
| - | VM 2 have the following NIC: | ||
| - | - vtnet0 connected to VM 1. | ||
| - | - vtnet1 connected to VM 3. | ||
| - | - vtnet2 connected to VM 4. | ||
| - | - vtnet3 connected to VM 5. | ||
| - | - vtnet4 connected to VM 6. | ||
| - | VM 3 have the following NIC: | ||
| - | - vtnet0 connected to VM 1. | ||
| - | - vtnet1 connected to VM 2. | ||
| - | - vtnet2 connected to VM 4. | ||
| - | - vtnet3 connected to VM 5. | ||
| - | - vtnet4 connected to VM 6. | ||
| - | VM 4 have the following NIC: | ||
| - | - vtnet0 connected to VM 1. | ||
| - | - vtnet1 connected to VM 2. | ||
| - | - vtnet2 connected to VM 3. | ||
| - | - vtnet3 connected to VM 5. | ||
| - | - vtnet4 connected to VM 6. | ||
| - | VM 5 have the following NIC: | ||
| - | - vtnet0 connected to VM 1. | ||
| - | - vtnet1 connected to VM 2. | ||
| - | - vtnet2 connected to VM 3. | ||
| - | - vtnet3 connected to VM 4. | ||
| - | - vtnet4 connected to VM 6. | ||
| - | VM 6 have the following NIC: | ||
| - | - vtnet0 connected to VM 1. | ||
| - | - vtnet1 connected to VM 2. | ||
| - | - vtnet2 connected to VM 3. | ||
| - | - vtnet3 connected to VM 4. | ||
| - | - vtnet4 connected to VM 5. | ||
| - | For connecting to VM' | ||
| - | - VM 1 : cu -l /dev/nmdm1B | ||
| - | - VM 2 : cu -l /dev/nmdm2B | ||
| - | - VM 3 : cu -l /dev/nmdm3B | ||
| - | - VM 4 : cu -l /dev/nmdm4B | ||
| - | - VM 5 : cu -l /dev/nmdm5B | ||
| - | - VM 6 : cu -l /dev/nmdm6B | ||
| - | </ | ||
| ===== Static routing setup ===== | ===== Static routing setup ===== | ||
| - | ==== VM 1 (client)  | + | ==== Client  | 
| - | VM1 is configured as a simple host with multiples aliases: | + | A simple host with static routes: | 
| < | < | ||
| - | sysrc hostname=VM1 \ | + | sysrc hostname=client  | 
| - | gateway_enable=NO \ | + | gateway_enable=NO \ | 
| - | ipv6_gateway_enable=NO \ | + | ipv6_gateway_enable=NO \ | 
| - | 	ifconfig_vtnet0="inet 10.0.12.1/ | + |    | 
| - | ifconfig_vtnet0_alias1="inet 10.0.12.11/32" \ | + |    | 
| - | 	ifconfig_vtnet0_alias2="inet 10.0.12.21/ | + |    | 
| - | 	ifconfig_vtnet0_alias3=" | + |    | 
| - | 	ifconfig_vtnet0_alias4=" | + |    | 
| - | 	ifconfig_vtnet0_alias5=" | + |    | 
| - | 	ifconfig_vtnet0_ipv6="inet6 2001: | + | |
| - | 	ifconfig_vtnet0_alias61="inet6 2001: | + | |
| - | 	ifconfig_vtnet0_alias62="inet6 2001:db8:12::21 prefixlen  | + | |
| - | 	ifconfig_vtnet0_alias63=" | + | |
| - | 	ifconfig_vtnet0_alias64=" | + | |
| - | 	ifconfig_vtnet0_alias65=" | + | |
| - | 	defaultrouter=" | + | |
| - | 	ipv6_defaultrouter=" | + | |
| service hostname restart | service hostname restart | ||
| service netif restart | service netif restart | ||
| Line 107: | Line 39: | ||
| </ | </ | ||
| - | ==== VM 2 (ECMP router) ==== | + | ==== R1 (ECMP router) ==== | 
| - | VM 2 is a router with ECMP: 2 static routes toward the same destination but using 2 different next-hop. | + | R1 is a router with ECMP: 2 static routes toward the same destination but using 2 different next-hop. | 
| < | < | ||
| - | sysrc hostname=VM2 \ | + | |
| - | 	ifconfig_vtnet0="inet 10.0.12.2/ | + | sysrc hostname=R1 \ | 
| - | ifconfig_vtnet1="inet 10.0.23.2/24" \ | + | gateway_enable=YES \ | 
| - | ifconfig_vtnet2="inet 10.0.24.2/24" \ | + |   ipv6_gateway_enable=YES  | 
| - | 	ifconfig_vtnet0_ipv6=" | + |    | 
| - | 	ifconfig_vtnet1_ipv6="inet6 2001: | + |    | 
| - | 	ifconfig_vtnet2_ipv6=" | + |    | 
| - | 	static_routes=" | + |    | 
| - | 	route_VM3VM6="-net 10.0.56.0/24 10.0.23.3" | + |    | 
| - | 	route_VM3VM5=" | + |    | 
| - | 	route_VM4VM6="-net 10.0.56.0/24 10.0.24.4" | + |   static_routes=" | 
| - | 	route_VM4VM5=" | + |    | 
| - | 	ipv6_static_routes=" | + |    | 
| - | 	ipv6_route_VM3VM6=" | + |   ipv6_static_routes=" | 
| - | 	ipv6_route_VM3VM5=" | + |    | 
| - | 	ipv6_route_VM4VM6=" | + |    | 
| - | 	ipv6_route_VM4VM5=" | + | |
| service hostname restart | service hostname restart | ||
| service netif restart | service netif restart | ||
| Line 138: | Line 69: | ||
| < | < | ||
| - | [root@VM2]~# netstat -rn4 | grep 10.0.56.0 | + | root@R1:~ # netstat -rn4 | grep 10.0.0.0/16 | 
| - | 10.0.56.0/24 10.0.24.4 UGS vtnet2 | + | 10.0.0.0/16         | 
| - | 10.0.56.0/24       10.0.23.3          UGS       | + | 10.0.0.0/16         | 
| - | [root@VM2]~# | + | |
| - | route to: 10.0.56.0 | + | root@R1:~ # netstat -4onW | 
| - | destination: | + | |
| - | mask: 255.255.255.0 | + | |
| - | gateway: 10.0.24.4 | + | |
| - | fib: 0 | + | |
| - |    | + | |
| - |        | + | |
| - |   | + | |
| - |         | + | |
| - | [root@VM2]~# netstat -4onW | + | |
| Nexthop data | Nexthop data | ||
| Internet: | Internet: | ||
| Idx    | Idx    | ||
| - | 4       v4/ | + | 1       v4/ | 
| - | 6        | + | 2        | 
| - | 2        | + | 3       v4/resolve 127.0.0.1  | 
| - | 1       v4/resolve 127.0.0.1  | + | 4       v4/ | 
| - | 7       v4/ | + | 5        | 
| - | 5        | + | 6        | 
| - | 3       v4/resolve 127.0.0.1  | + | 7       v4/resolve 127.0.0.1  | 
| - | 9            v4/gw 10.0.24.2          10.0.24.4           | + | 8            v4/gw 10.0.231.2          | 
| - | 8            v4/gw 10.0.23.2          10.0.23.3          GS            0    | + | 9            v4/gw 10.0.232.2          | 
| - | Nexthop groups data | + | |
| - | BUF: 192 | + | |
| - | Internet: | + | root@R1:~ # netstat -6onW | 
| - | MpIdx NHIdx Weigh Slots             | + | Nexthop data | 
| - | 1       | + | |
| - |            | + | Internet6: | 
| - |            | + | Idx    | 
| + | 1       v6/resolve ::1                            | ||
| + | 2        | ||
| + | 3        | ||
| + | 4        | ||
| + | 5        | ||
| + | 6        | ||
| + | 7        | ||
| + | 8        | ||
| + | 9        | ||
| + | 10           v6/gw ::1                           :: | ||
| + | 11           v6/gw 2001: | ||
| + | 12           v6/gw 2001: | ||
| </ | </ | ||
| - | ==== VM 3 (router) ==== | + | ==== R2 (ECMP router) ==== | 
| - | VM 3 is a simple  | + | R2 is like R1, a router  | 
| < | < | ||
| - | sysrc hostname=VM3 \ | + | sysrc hostname=R2 \ | 
| - | ifconfig_vtnet1="inet 10.0.23.3/24" \ | + |    | 
| - | ifconfig_vtnet3="inet 10.0.35.3/24" \ | + | ipv6_gateway_enable=YES \ | 
| - | 	ifconfig_vtnet1_ipv6=" | + | ifconfig_igb0="inet 10.0.34.3/24" \ | 
| - | 	ifconfig_vtnet3_ipv6=" | + |    | 
| - | 	static_routes=" | + | ifconfig_igb1="inet 10.0.231.3/24" \ | 
| - | route_VM1="-net 10.0.12.0/24 10.0.23.2" \ | + |    | 
| - | route_VM6="-net 10.0.56.0/24 10.0.35.5" \ | + |    | 
| - | 	ipv6_static_routes=" | + |   ifconfig_igb2_ipv6=" | 
| - | 	ipv6_route_VM1=" | + |   static_routes=" | 
| - | 	ipv6_route_VM6=" | + |    | 
| + |    | ||
| + |   ipv6_static_routes=" | ||
| + |    | ||
| + |    | ||
| service hostname restart | service hostname restart | ||
| service netif restart | service netif restart | ||
| Line 195: | Line 131: | ||
| config save | config save | ||
| </ | </ | ||
| + | ==== Server ==== | ||
| - | ==== VM 4 (router) ==== | + | A simple  | 
| - | + | ||
| - | VM 4 is like VM 3, a simple  | + | |
| < | < | ||
| - | sysrc hostname=VM4 \ | + | sysrc hostname=server  | 
| - | 	ifconfig_vtnet1="inet 10.0.24.4/ | + |    | 
| - | ifconfig_vtnet3="inet 10.0.45.4/24" \ | + |   ipv6_gateway_enable=NO  | 
| - | 	ifconfig_vtnet1_ipv6=" | + |    | 
| - | 	ifconfig_vtnet3_ipv6=" | + |    | 
| - | 	static_routes=" | + |   static_routes=" | 
| - | 	route_VM1="-net 10.0.12.0/24 10.0.24.2" | + |    | 
| - | 	route_VM6=" | + |   ipv6_static_routes=" | 
| - | 	ipv6_static_routes=" | + |    | 
| - | 	ipv6_route_VM1=" | + | |
| - | 	ipv6_route_VM6=" | + | |
| service hostname restart | service hostname restart | ||
| service netif restart | service netif restart | ||
| Line 218: | Line 151: | ||
| </ | </ | ||
| - | ==== VM 5 (ECMP router)  | + | ===== FRR Multipath setup ===== | 
| - | VM 5 is like VM 2, a router with ECMP: 2 static  | + | Replacing  | 
| - | < | + | ==== R1 (ECMP router)  | 
| - | sysrc hostname=VM5 \ | + | |
| - | 	ifconfig_vtnet2="inet 10.0.35.5/ | + | |
| - | 	ifconfig_vtnet3="inet 10.0.45.5/ | + | |
| - | 	ifconfig_vtnet4="inet 10.0.56.5/ | + | |
| - | 	ifconfig_vtnet2_ipv6="inet6 2001: | + | |
| - | 	ifconfig_vtnet3_ipv6="inet6 2001: | + | |
| - | 	ifconfig_vtnet4_ipv6="inet6 2001: | + | |
| - | 	static_routes=" | + | |
| - | 	route_VM3VM1=" | + | |
| - | 	route_VM3VM2=" | + | |
| - | 	route_VM4VM1=" | + | |
| - | 	route_VM4VM2=" | + | |
| - | 	ipv6_static_routes=" | + | |
| - | 	ipv6_route_VM3VM1=" | + | |
| - | 	ipv6_route_VM3VM2=" | + | |
| - | 	ipv6_route_VM4VM1=" | + | |
| - | 	ipv6_route_VM4VM2=" | + | |
| - | service hostname restart | + | |
| - | service netif restart | + | |
| - | service routing restart | + | |
| - | config save | + | |
| - | </ | + | |
| - | ==== VM 6 (server) ==== | + | In place of static routes, OSPF with FRR is used: | 
| - | VM 6, like VM 1 is configured as a simple host with multiple aliases: | + | < | 
| + | sysrc frr_vtysh_boot=" | ||
| + |   frr_enable=" | ||
| + |   frr_daemons=" | ||
| + |   watchfrr_flags=" | ||
| + |   watchfrr_enable=" | ||
| - | <code> | + | cat > / | 
| - | sysrc hostname=VM6 \ | + | frr version 8.4.1 | 
| - | gateway_enable=NO \ | + | frr defaults traditional | 
| - | ipv6_gateway_enable=NO \ | + | hostname  | 
| - | 	ifconfig_vtnet4=" | + | ! | 
| - | 	ifconfig_vtnet4_alias1=" | + | interface igb0 | 
| - | 	ifconfig_vtnet4_alias2=" | + | ip ospf passive | 
| - | 	ifconfig_vtnet4_alias3=" | + | ipv6 ospf6 area 0.0.0.0 | 
| - | 	ifconfig_vtnet4_alias4=" | + | ipv6 ospf6 passive | 
| - | 	ifconfig_vtnet4_alias5=" | + | exit | 
| - | 	ifconfig_vtnet4_ipv6=" | + | ! | 
| - | 	ifconfig_vtnet4_alias61=" | + | interface igb1 | 
| - | 	ifconfig_vtnet4_alias62=" | + | ipv6 ospf6 area 0.0.0.0 | 
| - | 	ifconfig_vtnet4_alias63=" | + | exit | 
| - | 	ifconfig_vtnet4_alias64=" | + | ! | 
| - | 	ifconfig_vtnet4_alias65=" | + | interface igb2 | 
| - | 	defaultrouter=" | + | ipv6 ospf6 area 0.0.0.0 | 
| - | 	ipv6_defaultrouter=" | + | exit | 
| - | service  | + | ! | 
| - | service  | + | router ospf | 
| - | service routing restart | + | ospf router-id 1.1.1.1 | 
| - | config save | + |   | 
| + |  network  | ||
| + |  network  | ||
| + | exit | ||
| + | ! | ||
| + | router ospf6 | ||
| + | exit | ||
| + | ! | ||
| + | EOF | ||
| + | service  | ||
| + | service  | ||
| </ | </ | ||
| - | ==== Testing Load balancing  | + | ==== R2 (ECMP router)  | 
| - | Flows from VM1 to VM6 should be " | + | Same as R1 with OSPF and FRR: | 
| - | Using ping record feature like with this example: | + | |
| < | < | ||
| - | [root@VM1]~# | + | sysrc frr_vtysh_boot=" | 
| - | PING 10.0.56.26 (10.0.56.26) from 10.0.12.21: 56 data bytes | + |   frr_enable=" | 
| - | 64 bytes from 10.0.56.26: icmp_seq=0 ttl=61 time=0.455 ms | + |   frr_daemons=" | 
| - | RR:      | + |   watchfrr_flags="  | 
| - | 10.0.45.4 | + |    | 
| - | 10.0.56.5 | + | |
| - | 10.0.56.26 | + | |
| - | 10.0.45.5 | + | |
| - | 10.0.24.4 | + | |
| - | 10.0.12.2 | + | |
| - | 10.0.12.21 | + | |
| - | --- 10.0.56.26 ping statistics --- | + | cat > / | 
| - | 1 packets transmitted, | + | frr version 8.4.1 | 
| - | round-trip min/ | + | frr defaults traditional | 
| + | hostname R2 | ||
| + | ! | ||
| + | ip route 10.0.0.0/16 10.0.34.4 | ||
| + | ipv6 route 2001: | ||
| + | ! | ||
| + | interface igb0 | ||
| + | ip ospf passive | ||
| + | ipv6 ospf6 area 0.0.0.0 | ||
| + | ipv6 ospf6 passive | ||
| + | exit | ||
| + | ! | ||
| + | interface igb1 | ||
| + | ipv6 ospf6 area 0.0.0.0 | ||
| + | exit | ||
| + | ! | ||
| + | interface igb2 | ||
| + | ipv6 ospf6 area 0.0.0.0 | ||
| + | exit | ||
| + | ! | ||
| + | router ospf | ||
| + | ospf router-id 2.2.2.2 | ||
| + |   | ||
| + |   | ||
| + |   | ||
| + |   | ||
| + | exit | ||
| + | ! | ||
| + | router ospf6 | ||
| + |   | ||
| + | exit | ||
| + | ! | ||
| + | EOF | ||
| + | service frr start | ||
| + | service watchfrr start | ||
| </ | </ | ||
| - | ^ Source ^ Destination ^ Ongoing path selected by VM2 ^ Returning path selected by VM5^ | + | ==== Checking routes installed ==== | 
| - | | 10.0.12.1 | 10.0.35.5 | VM3 | VM4 | | + | |
| - | | 10.0.12.1 | 10.0.45.5 | VM4 | VM4 | | + | |
| - | | 10.0.12.1 | 10.0.56.6 | VM3 | VM4 | | + | |
| - | | 10.0.12.11 | 10.0.56.16 | VM3 | VM4 | | + | |
| - | | 10.0.12.21 | 10.0.56.26 | VM3 | VM4 | | + | |
| - | | 10.0.12.31 | 10.0.56.36 | VM3 | VM4 | | + | |
| - | | 10.0.12.41 | 10.0.56.46 | VM3 | VM4 | | + | |
| - | | 10.0.12.51 | 10.0.56.56 | VM3 | VM4 | | + | |
| - | | 2001: | + | |
| - | | 2001: | + | |
| - | | 2001: | + | |
| - | | 2001: | + | |
| - | | 2001: | + | |
| - | | 2001: | + | |
| - | Notice inet6 bug: Cannot ping itself neither neighbor | + | On R1: | 
| < | < | ||
| - | [root@VM1]~# ifconfig vtnet0 inet6 | + | root@R1:~ # vtysh | 
| - | vtnet0: flags=8943< | + | Hello, this is FRRouting  | 
| - |         options=80028< | + | Copyright 1996-2005 Kunihiro Ishiguro, et al. | 
| - |         inet6 fe80:: | + | |
| - |         inet6 2001: | + | |
| - |         inet6 2001: | + | |
| - |         inet6 2001: | + | |
| - |         inet6 2001: | + | |
| - |         inet6 2001: | + | |
| - |         inet6 2001: | + | |
| - |         nd6 options=21< | + | |
| - | [root@VM1]~# | + | |
| - | PING6(56=40+8+8 bytes) fe80:: | + | |
| - | --- fe80:: | + | R1# sh ip route 10.0.0.0 | 
| - | 1 packets transmitted,  | + | Routing entry for 10.0.0.0/16 | 
| - | [root@VM1]~# | + |   Known via " | 
| - | ping6: illegal number of packets -- 12001:db8:12::2 | + | Last update 00:02:26 ago | 
| - | [root@VM1]~# | + |   * 10.0.231.3, via igb1, weight  | 
| - | PING6(56=40+8+8 bytes) 2001: | + |   * 10.0.232.3, via igb2, weight  | 
| - | --- 2001:db8:12::2 ping6 statistics --- | + | R1# sh ipv6 route 2001:db8:: | 
| - | 1 packets transmitted, 0 packets received, 100.0% packet loss | + | Routing entry for 2001:db8::/32 | 
| + |   Known via " | ||
| + | Last update 00:02:39 ago | ||
| + |   * fe80:: | ||
| + |   * fe80:: | ||
| </ | </ | ||
| - | ==== Testing Fail Over ==== | + | ===== Test Load balancing IP packets ===== | 
| - | VM4 is the preferred hop, so shutdown this VM to check behavior: | + | Flows from the client to the server should be " | 
| + | On server: | ||
| < | < | ||
| - | [root@VM4]~# shutdown  | + | root@server:~ # pkt-gen -i igb1 -f rx | 
| - | Shutdown NOW! | + | |
| </ | </ | ||
| + | On client: | ||
| < | < | ||
| - | [root@VM2]~# netstat  | + | root@client:~ # pkt-gen -i igb1 -f tx -n 8000000 -l 60 -d 10.0.255.1: | 
| - | Nexthop data | + | </ | 
| - | Internet: | + | On R1: | 
| - | Idx    | + | < | 
| - | 4       v4/resolve 10.0.23.2          vtnet1/resolve  | + | systat -ifstat -match igb0, | 
| - | 6       v4/resolve 10.0.24.2           | + | |
| - | 2       v4/resolve 10.0.12.2  | + |                      | 
| - | 1       v4/resolve 127.0.0.1  | + |       | 
| - | 7       v4/resolve 127.0.0.1  | + | |
| - | 5        | + | |
| - | 3        | + | |
| - | 9            v4/gw 10.0.24.2  | + | |
| - | 8            v4/gw 10.0.23.2  | + | |
| - | Nexthop groups data | + | |
| - | BUF: 192 | + | |
| - | Internet: | + |       Interface  | 
| - | MpIdx NHIdx Weigh Slots Gateway Netif Refcnt | + |            igb2  in      0.000 Kp/s          0.000 Kp/s            | 
| - | 1 ---- ---- ---- ---- ---- 1 | + |                  out     9.762 Kp/s          9.777 Kp/s            | 
| - |           9   100      | + | |
| - |            | + |             | 
| + |                  out     9.770 Kp/s          9.771 Kp/s            | ||
| + | |||
| + |             | ||
| + |                  out      | ||
| + | |||
| </ | </ | ||
| + | => We confirm that 20 Kps entering igb0 and are equally split by exiting by igb1 and igb2 | ||
| + | |||
| + | On R2: | ||
| < | < | ||
| - | [root@VM1]~# | + | systat  | 
| - | PING 10.0.56.26 (10.0.56.26) from 10.0.12.21: 56 data bytes | + | |
| - | --- 10.0.56.26 ping statistics --- | + |                     /0   / | 
| - | 1 packets transmitted,  | + |      Load Average  | 
| + | |||
| + |       Interface  | ||
| + |             | ||
| + |                   | ||
| + | |||
| + |             | ||
| + |                   | ||
| + | |||
| + |             | ||
| + |                   | ||
| </ | </ | ||
| + | |||
| + | => R2 has no choice than receiving packets from igb1 and igb2, and forwarding them through igb0. | ||
| + | |||
documentation/examples/ecmp.1580064403.txt.gz · Last modified: 2020/01/26 19:46 by olivier
                
                