This article explains how to perform unequal cost load balancing using only static routing.
The objective is to statically load balance traffic to optimize bandwidth utilization.
The standard statically configured load balancing configuration is unaware of the bandwidth/link speed. Hence, it distributes the load evenly, which may not be desirable. In the figure shown above, we have three ISPs with speeds of 2Mbps, 4Mbps, and 6Mbps. We need to distribute the load across these three links to optimize bandwidth utilization.
By default, load balancing is disabled on J/SRX platforms. When two or more routes going to the same destination are present, the device will install only one route, usually the one with the best metric. The command to allow equal-cost load balancing is the following:
set policy-options policy-statement POLICY_NAME then load-balance per-packet
However, we can allow equal cost per flow load balance. See KB23417 - Equal-cost multipath support on SRX for flow-based forwarding [juniper.net]. SRX firewalls are stateful devices; they implement a "per-flow" load balance operation instead of a "per-packet" operation.
We will leverage the equal cost load-balance feature to achieve unequal cost load balance. The key is to generate multiple next-hops pointing to the same ISP next-hop in a desired ratio, such that when the device tries to do equal cost load-balancing, it ends up sharing the load in a ratio of the bandwidth. In the following example, we will configure unequal cost load balances for the default routes going to each ISP. This procedure should work for any route, if each route is going to the exact same subnet, having the exact same subnet mask.
Assume that the next hops for each ISPs are as follows:
ISP1 - 2Mbps: default-gateway IP: 10.10.10.1
ISP2 - 4Mbps: default-gateway IP: 172.16.10.1
ISP3 - 6Mbps: default-gateway IP: 192.168.10.1
In this example, we have three ISPs that have speeds of 2Mbps, 4Mbps, and 6Mbps, respectively. We can install two routes for the ISP that has 2Mbps, four routes for the ISP that has 4Mbps, and six routes for the ISP that has 6Mbps. This will allow a 2:4:6 distribution fashion. Since we are using pair numbers in this case, we could choose to compress it in a 1:2:3 fashion that would provide the same effect. However, in this example, for clarity we will be configuring the routes in a 2:4:6 fashion.
Note: IP addresses in the range 10.10.11.0/24, 10.10.12.0/24, 10.10.13.0/24 are not actual IP addresses; they are dummy IP addresses.
Create and install dummy routes going to the next ISP's IP addresses:
set routing-options static route 10.10.11.1/32 next-hop 10.10.10.1 set routing-options static route 10.10.11.2/32 next-hop 10.10.10.1 set routing-options static route 10.10.12.1/32 next-hop 172.16.10.1 set routing-options static route 10.10.12.2/32 next-hop 172.16.10.1 set routing-options static route 10.10.12.3/32 next-hop 172.16.10.1 set routing-options static route 10.10.12.4/32 next-hop 172.16.10.1 set routing-options static route 10.10.13.1/32 next-hop 192.168.10.1 set routing-options static route 10.10.13.2/32 next-hop 192.168.10.1 set routing-options static route 10.10.13.3/32 next-hop 192.168.10.1 set routing-options static route 10.10.13.4/32 next-hop 192.168.10.1 set routing-options static route 10.10.13.5/32 next-hop 192.168.10.1 set routing-options static route 10.10.13.6/32 next-hop 192.168.10.1
Install default static routes that will be going to the dummy IP addresses created in step 1.
set routing-options static route 0.0.0.0/0 next-hop 10.10.11.1 set routing-options static route 0.0.0.0/0 next-hop 10.10.11.2 set routing-options static route 0.0.0.0/0 next-hop 10.10.12.1 set routing-options static route 0.0.0.0/0 next-hop 10.10.12.2 set routing-options static route 0.0.0.0/0 next-hop 10.10.12.3 set routing-options static route 0.0.0.0/0 next-hop 10.10.12.4 set routing-options static route 0.0.0.0/0 next-hop 10.10.13.1 set routing-options static route 0.0.0.0/0 next-hop 10.10.13.2 set routing-options static route 0.0.0.0/0 next-hop 10.10.13.3 set routing-options static route 0.0.0.0/0 next-hop 10.10.13.4 set routing-options static route 0.0.0.0/0 next-hop 10.10.13.5 set routing-options static route 0.0.0.0/0 next-hop 10.10.13.6
By default, the Juniper device will only do a route recursive resolution to find the outgoing interface. Therefore, adding the "resolve" keyword to the default route will allow the Juniper device to perform a second route lookup to find the outgoing interface.
resolve
set routing-options static route 0.0.0.0/0 resolve
Configure equal cost load balancing.
set policy-options policy-statement Load-Balance then load-balance per-packet set routing-options forwarding-table export Load-Balance
Verification
Since we are performing unequal cost load balancing, there are not many tools available to make sure that the packets are being forwarded in an unequal cost load balance fashion. However, you can test as shown here:
root@SRX> show route inet.0: 23 destinations, 23 routes (23 active, 0 holddown, 0 hidden) + = Active Route, - = Last Active, * = Both 0.0.0.0/0 *[Static/5] 00:00:58, metric2 0 > to 10.10.10.1 via ge-0/0/0.0 << Note: The SRX device will > to 10.10.10.1 via ge-0/0/0.0 install the route derived from to 172.16.10.1 via ge-0/0/1.0 the recursive routing lookup to 172.16.10.1 via ge-0/0/1.0 operation that the to 172.16.10.1 via ge-0/0/1.0 networking device will perform to 172.16.10.1 via ge-0/0/1.0 to find the outgoing interface. to 192.168.10.1 via ge-0/0/2.0 to 192.168.10.1 via ge-0/0/2.0 to 192.168.10.1 via ge-0/0/2.0 to 192.168.10.1 via ge-0/0/2.0 to 192.168.10.1 via ge-0/0/2.0 to 192.168.10.1 via ge-0/0/2.0 10.10.10.0/30 *[Direct/0] 21:36:30 > via ge-0/0/0.0 10.10.10.2/32 *[Local/0] 21:36:30 Local via ge-0/0/0.0 10.10.11.1/32 *[Static/5] 00:00:58 > to 10.10.10.1 via ge-0/0/0.0 << Interface towards ISP 1. 10.10.11.2/32 *[Static/5] 00:00:58 > to 10.10.10.1 via ge-0/0/0.0 10.10.12.1/32 *[Static/5] 00:00:58 > to 172.16.10.1 via ge-0/0/1.0 << Interface towards ISP 2. 10.10.12.2/32 *[Static/5] 00:00:58 > to 172.16.10.1 via ge-0/0/1.0 10.10.12.3/32 *[Static/5] 00:00:58 > to 172.16.10.1 via ge-0/0/1.0 10.10.12.4/32 *[Static/5] 00:00:58 > to 172.16.10.1 via ge-0/0/1.0 10.10.13.1/32 *[Static/5] 00:00:58 > to 192.168.10.1 via ge-0/0/2.0 << Interface towards ISP 3. 10.10.13.2/32 *[Static/5] 00:00:58 > to 192.168.10.1 via ge-0/0/2.0 10.10.13.3/32 *[Static/5] 00:00:58 > to 192.168.10.1 via ge-0/0/2.0 10.10.13.4/32 *[Static/5] 00:00:58 > to 192.168.10.1 via ge-0/0/2.0 10.10.13.5/32 *[Static/5] 00:00:58 > to 192.168.10.1 via ge-0/0/2.0 10.10.13.6/32 *[Static/5] 00:00:58 > to 192.168.10.1 via ge-0/0/2.0 root@SRX> show route forwarding-table Routing table: default.inet Internet: Destination Type RtRef Next hop Type Index NhRef Netif default user 0 ulst 262167 2 indr 262150 2 ab:45:27:a0:cd:23 ucst 574 6 ge-0/0/0.0 << Interface towards ISP 1. indr 262156 2 ab:45:27:a0:cd:23 ucst 574 6 ge-0/0/0.0 indr 262157 2 cd:96:14:e8:fd:a3 ucst 580 10 ge-0/0/1.0 << Interface towards ISP 2. indr 262158 2 cd:96:14:e8:fd:a3 ucst 580 10 ge-0/0/1.0 indr 262159 2 cd:96:14:e8:fd:a3 ucst 580 10 ge-0/0/1.0 indr 262160 2 cd:96:14:e8:fd:a3 ucst 580 10 ge-0/0/1.0 indr 262161 2 de:96:14:ea:60:3 ucst 575 14 ge-0/0/2.0 << Interface towards ISP 1. indr 262162 2 de:96:14:ea:60:3 ucst 575 14 ge-0/0/2.0 indr 262163 2 de:96:14:ea:60:3 ucst 575 14 ge-0/0/2.0 indr 262164 2 de:96:14:ea:60:3 ucst 575 14 ge-0/0/2.0 indr 262165 2 de:96:14:ea:60:3 ucst 575 14 ge-0/0/2.0 indr 262166 2 de:96:14:ea:60:3 ucst 575 14 ge-0/0/2.0 root@SRX>show security flow session source-prefix 192.168.4.2 Session ID: 2754, Policy name: INSIDE_TO_ISP_1_POLICY/9, State: Active, Timeout: 296, Valid In: 192.168.4.2/49354 --> 91.216.63.240/80;tcp, If: reth5.4, Pkts: 2, Bytes: 92 Out: 91.216.63.240/80 --> 10.10.10.2/3427;tcp, If: ge-0/0/0.0, Pkts: 1, Bytes: 52 Session ID: 2802, Policy name: INSIDE_TO_ISP_1_POLICY/9, State: Active, Timeout: 1624, Valid In: 192.168.4.2/49226 --> 54.192.194.142/443;tcp, If: reth5.4, Pkts: 13, Bytes: 1228 Out: 54.192.194.142/443 --> 10.10.10.2/2349;tcp, If: ge-0/0/0.0, Pkts: 13, Bytes: 8156 Session ID: 2916, Policy name: INSIDE_TO_ISP_2_POLICY/13, State: Active, Timeout: 1800, Valid *See note below
Session ID: 2916, Policy name: INSIDE_TO_ISP_2_POLICY/13, State: Active, Timeout: 1800, Valid
In: 192.168.4.2 /49268 --> 216.53.231.164/443;tcp, If: reth5.4, Pkts: 17, Bytes: 1384Out: 216.58.219.164/443 --> 172.16.10.2/29294;tcp, If: ge-0/0/1.0 , Pkts: 15, Bytes: 5028
*Note: Traffic coming from the same source IP address should be going out from the different ISP's outbound interfaces. Also, there should be more flows going out from the ISP that we have assigned more ratio to (the one that has more bandwidth). In this case, there should be more flows exiting interface ge-0/0/2.0, which is the outside interface corresponding to ISP3.
Session ID: 2939, Policy name: INSIDE_TO_ISP_3_POLICY/15, State: Active, Timeout: 1800, Valid In: 192.168.4.2/49337 --> 31.13.73.36/443;tcp, If: reth5.4, Pkts: 117, Bytes: 6675 Out: 31.13.73.36/443 --> 192.168.10.2/31513;tcp, If: ge-0/0/2.0, Pkts: 121, Bytes: 132803 Session ID: 2944, Policy name: INSIDE_TO_ISP_2_POLICY/13, State: Active, Timeout: 300, Valid In: 192.168.4.2/49374 --> 146.255.100.192/80;tcp, If: reth5.4, Pkts: 87, Bytes: 5452 Out: 146.255.100.192/80 --> 172.16.10.2/17248;tcp, If: ge-0/0/1.0, Pkts: 85, Bytes: 123775 Session ID: 2945, Policy name: INSIDE_TO_ISP_3_POLICY/15, State: Active, Timeout: 1800, Valid In: 192.168.4.2/49238 --> 216.58.219.138/443;tcp, If: reth5.4, Pkts: 150, Bytes: 74339 Out: 216.58.219.138/443 --> 192.168.10.2/7934;tcp, If: ge-0/0/2.0, Pkts: 114, Bytes: 66879 Session ID: 2954, Policy name: INSIDE_TO_ISP_3_POLICY/15, State: Active, Timeout: 1784, Valid In: 192.168.4.2/49243 --> 216.58.219.65/443;tcp, If: reth5.4, Pkts: 189, Bytes: 15038 Out: 216.58.219.65/443 --> 192.168.10.2/15151;tcp, If: ge-0/0/2.0, Pkts: 198, Bytes: 180257 Session ID: 2955, Policy name: INSIDE_TO_ISP_1_POLICY/9, State: Active, Timeout: 2, Valid In: 192.168.4.2/58755 --> 8.8.4.4/53;udp, If: reth5.4, Pkts: 1, Bytes: 60 Out: 8.8.4.4/53 --> 10.10.10.2/32603;udp, If: ge-0/0/0.0, Pkts: 1, Bytes: 129 Session ID: 2963, Policy name: INSIDE_TO_ISP_2_POLICY/13, State: Active, Timeout: 2, Valid In: 192.168.4.2/55217 --> 36.23.123.4/443;tcp, If: reth5.4, Pkts: 134, Bytes: 11114 Out: 36.23.123.4/443 --> 172.16.10.2/14903;tcp, If: ge-0/0/1.0, Pkts: 134, Bytes: 10201 Session ID: 3078, Policy name: INSIDE_TO_ISP_3_POLICY/15, State: Active, Timeout: 1800, Valid In: 192.168.4.2/49340 --> 201.191.202.34/443;tcp, If: reth5.4, Pkts: 216, Bytes: 16246 Out: 201.191.202.34/443 --> 192.168.10.2/15831;tcp, If: ge-0/0/2.0, Pkts: 187, Bytes: 251875 Session ID: 3172, Policy name: INSIDE_TO_ISP_3_POLICY/15, State: Active, Timeout: 300, Valid In: 192.168.4.2/49504 --> 23.14.180.21/80;tcp, If: reth5.4, Pkts: 5, Bytes: 721 Out: 23.14.180.21/80 --> 192.168.10.2/19707;tcp, If: ge-0/0/2.0, Pkts: 4, Bytes: 2356
ge-0/0/1.0