BGP installs one best path. That is the default and it is deliberate: BGP is a policy protocol, and the best-path algorithm exists to produce exactly one winner. But if you have two circuits to the same provider, one of them sitting idle is a waste of money. BGP multipath lets you install several equally-good paths and load-share across them.
The configuration is a single line. The rules about when BGP will accept a second path are not, and one of them - a next-hop rewrite that nobody documents clearly - can hide a serious misconfiguration from you completely. This article covers eBGP, iBGP and eiBGP multipath on Cisco IOS XE with lab output. For the fundamentals, start at the complete BGP guide.
The default: one best path, one route
In the lab, R1 (AS 65001) has two parallel links to R3 (ISP-A, AS 100), each carrying its own eBGP session. Both sessions offer 6.6.60.0/24 with identical attributes. BGP picks one:
R1#show ip route 6.6.60.0
Routing entry for 6.6.60.0/24
Known via "bgp 65001", distance 20, metric 0
Routing Descriptor Blocks:
* 10.0.13.2, from 10.0.13.2, 00:01:03 ago
Route metric is 0, traffic share count is 1One descriptor block. One next-hop. The second circuit carries nothing but BGP keepalives.
Enabling multipath
router bgp 65001
address-family ipv4
maximum-paths 2That is it for eBGP. Immediately:
R1#show ip bgp 6.6.60.0
BGP routing table entry for 6.6.60.0/24
Paths: (3 available, best #1, table default)
Multipath: eBGP
100 300
10.0.13.2 from 10.0.13.2 (3.3.3.3)
Origin IGP, localpref 100, valid, external, multipath, best
100 300
10.0.113.2 from 10.0.113.2 (3.3.3.3)
Origin IGP, localpref 100, valid, external, multipath(oldest)
200 300
2.2.2.2 (metric 11) from 2.2.2.2 (2.2.2.2)
Origin IGP, metric 0, localpref 100, valid, internalThree things to read here. Multipath: eBGP tells you which flavour is active. Two paths are now flagged multipath. And the third path, learned over iBGP through ISP-B, is not a multipath - it has a different AS-path, so it does not qualify.
The summary view uses an m flag for non-best multipaths:
R1#show ip bgp
Network Next Hop Metric LocPrf Weight Path
*> 6.6.60.0/24 10.0.13.2 0 100 300 i
*m 10.0.113.2 0 100 300 i
* i 2.2.2.2 0 100 0 200 300 iAnd the RIB now has both:
R1#show ip route bgp
B 6.6.60.0/24 [20/0] via 10.0.113.2, 00:01:49
[20/0] via 10.0.13.2, 00:01:49Both circuits are now carrying traffic, load-shared per-flow by CEF.
The rules: what makes two paths equal
BGP will only treat paths as multipath if they are equal on every best-path tiebreaker up to the point where the router would otherwise have to choose. In practice, that means all of the following must match:
bgp bestpath as-path multipath-relax.
Notice what is not on the list: the neighbour's router ID, the peer address, and the neighbour's AS number for the immediate hop. Two sessions to the same physical router over two links, as in this lab, absolutely qualify - and that is the most common real-world multipath deployment there is.
as-path multipath-relax
By default, two paths with AS-paths 100 300 and 200 300 are not multipath, even though they are the same length. BGP insists the paths be identical, on the grounds that they traverse genuinely different networks and might have wildly different characteristics.
router bgp 65001
address-family ipv4
bgp bestpath as-path multipath-relax
maximum-paths 2With multipath-relax, equal length is enough. This is how you load-share across two different upstream providers. It is also how you get asymmetric behaviour, unpredictable latency, and support tickets you cannot reproduce - because the two paths are genuinely different networks. Turn it on deliberately, knowing that.
A hard constraint you cannot relax: the paths must still originate from the same neighbouring AS for the router to consider them at the eBGP multipath stage. multipath-relax loosens the AS-path content check, not the AS-path length check.
iBGP multipath
Same command, different qualification rule. For iBGP paths to be multipath, the IGP metric to each BGP next-hop must be equal.
router bgp 65001
address-family ipv4
maximum-paths ibgp 2This is the design that matters in a data centre or a large campus: two route reflectors, two exit routers, equal IGP cost from your position to both, and you load-share outbound across both exits. If your IGP metrics are not equal - and in a real network with mixed link speeds they usually are not - iBGP multipath quietly does nothing. Check with:
show ip bgp <prefix>and look at the (metric N) value on each iBGP path. If they differ, that is your answer.
eiBGP multipath
Mixing an eBGP path and an iBGP path into a single load-shared set is called eiBGP multipath, and on IOS it is only supported inside a VRF:
router bgp 65001
address-family ipv4 vrf CUSTOMER-A
maximum-paths eibgp 2This exists for exactly one scenario: an MPLS L3VPN PE with a dual-homed customer site, where the site is reachable both directly (eBGP to the CE) and across the MPLS core (iBGP/VPNv4 from the remote PE). It lets the PE load-share between the local link and the core.
Outside a VRF, eiBGP multipath is not available on IOS XE, and for good reason: mixing an external path with an internal one in the global table produces routing that is very hard to reason about. If you find yourself wanting it in the global table, what you actually want is a design change.
The trap: multipath silently applies next-hop-self
This is the finding from the lab that is worth the price of admission, and it is genuinely not well documented.
R1 is an eBGP edge router with an iBGP session to R2. Standard practice is neighbor 2.2.2.2 next-hop-self, so R2 receives eBGP routes with R1's loopback as the next-hop rather than an ISP address it cannot reach.
Remove next-hop-self, and the classic symptom should appear instantly: R2 receives routes with an unresolvable next-hop and never installs them. Except it did not:
! next-hop-self removed from R1, maximum-paths 2 still configured
R2#show ip bgp 100.100.100.0/24
BGP routing table entry for 100.100.100.0/24
Paths: (1 available, best #1, table default)
100
1.1.1.1 (metric 11) from 1.1.1.1 (1.1.1.1)
Origin IGP, metric 0, localpref 200, valid, internal, bestNext-hop 1.1.1.1 - R1's loopback. Exactly what next-hop-self would have produced, except next-hop-self is not configured. The misconfiguration is completely invisible.
Now remove maximum-paths 2 and clear the session:
R2#show ip bgp 100.100.100.0/24
BGP routing table entry for 100.100.100.0/24, version 0
Paths: (1 available, no best path)
100
10.0.13.2 (inaccessible) from 1.1.1.1 (1.1.1.1)
Origin IGP, metric 0, localpref 200, valid, internal
R2#show ip bgp | include 100.100
* i 100.100.100.0/24 10.0.13.2 0 200 0 100 iThere it is: next-hop 10.0.13.2, (inaccessible), no >, never installed in the RIB. The classic failure, revealed only once multipath was removed.
Why this happens: when a prefix is installed as a multipath, there is no single external next-hop to pass along - there are several. IOS resolves this by advertising the route to iBGP peers with itself as the next-hop. Which is sensible, and which means that on any router where eBGP multipath is active, the absence of next-hop-self is masked.
Why you should care: the day someone disables multipath, or the day one of the two circuits fails and the prefix drops back to a single path, every iBGP peer suddenly starts receiving unreachable next-hops and your internal routing falls over. The bug was sitting there the whole time. Configure next-hop-self explicitly on every iBGP session from an eBGP edge router, always, whether or not multipath appears to make it unnecessary.
How traffic is actually shared
Installing two paths in the RIB does not, by itself, split traffic evenly. CEF does the sharing, and by default it hashes per destination flow (source and destination IP). That means:
- A single large TCP transfer uses exactly one path. Multipath will not make one download faster.
- Many flows spread reasonably evenly, assuming diverse addressing.
- A handful of very large flows can land on the same path and leave the other idle. This is normal and is not a bug.
Check what CEF is doing:
show ip cef <prefix> internal
show ip cef exact-route <source> <destination>exact-route is the one you want in a ticket: give it a real source and destination and it tells you exactly which link that flow will take.
You can move to per-packet load sharing with ip load-sharing per-packet on the interface, and you should not. It reorders packets, TCP hates it, and every modern application stack performs worse.
Design guidance
- Two links, one provider: plain
maximum-paths N. Simple, symmetric, no surprises. This is the case worth doing. - Two providers: think hard before reaching for
multipath-relax. Different providers means different latency, different congestion, different failure modes. Load-sharing across them makes your network's behaviour a function of two networks you do not control. Often the better answer is to prefer one and keep the other hot-standby. - Inside your AS:
maximum-paths ibgp N, and make your IGP metrics genuinely equal, or it will not engage. - Always set
next-hop-selfanyway. See above. - Watch your FIB. Every multipath prefix consumes multiple FIB entries. On a platform with a hardware FIB and a full internet table, this is not free.
Key takeaways
maximum-paths Nfor eBGP,maximum-paths ibgp Nfor iBGP,maximum-paths eibgp Nfor mixed - and eiBGP is VRF-only on IOS XE.- Paths must match on weight, local-pref, AS-path, origin, MED, and path type. For iBGP, the IGP metric to the next-hop must also match.
bgp bestpath as-path multipath-relaxloosens AS-path content to just length. Use it consciously, mainly for multi-provider load sharing.- The
mflag inshow ip bgpand themultipathkeyword in the detail view are how you confirm it engaged. - eBGP multipath silently rewrites the next-hop toward iBGP peers, masking a missing
next-hop-self. Configurenext-hop-selfexplicitly regardless. - Load sharing is per-flow by default. One big flow takes one path. That is correct behaviour.
Next: MP-BGP for IPv6 and 6PE, where IPv6 prefixes cross an IPv4-only MPLS core with real label output. The full cluster index lives on the BGP pillar guide.