Skip to main content
RunBook Academy

VyOSXXX · BGP Route ReflectorsMultipath

Multipath-relax — `bestpath as-path multipath-relax`, the identical-AS_PATH default, and eBGP/iBGP multipath

Advanced⏱ ~22 minshow ip bgpshow ip routeshow bgp ipv4 neighborsvtysh

What you'll learn

  • State the default requirement that candidate paths for multipath carry an identical AS_PATH
  • Configure `set protocols bgp parameters bestpath as-path multipath-relax` on VyOS 1.5 LTS
  • Explain what multipath-relax does not fix, including a prepended path
  • Configure `maximum-paths ebgp` and `maximum-paths ibgp` under the address family
  • Read `show ip bgp <prefix>` and identify the multipath candidates
  • Diagnose a prefix that has several usable paths and only one FIB next-hop

Prerequisites

Verified against VyOS 1.5.x LTS (circinus) · VyOS 1.4.x (sagitta) — legacy · FRRouting 10.x (VyOS 1.5) · Linux kernel 6.6 LTS (VyOS 1.5 base) · strongSwan 5.9.x (IPsec) · WireGuard 1.0.x (kernel module + userspace tooling)

Not yet marked complete on this device.

BGP is a single-path protocol by design. It runs its best-path comparison, picks one winner, and installs that one next-hop. Multipath is the operator’s instruction to install several — and it has two gates, both of which have to be opened, in the right order, for anything to change in the FIB.

The first gate is eligibility: which paths does BGP consider equal enough to install alongside the best one. The second is maximum-paths, which caps how many of the eligible ones actually go in. Most “multipath is not working” tickets are the first gate, and most of those are one specific misunderstanding about the AS_PATH, which is where this lesson starts.

The default is identical, not equal-length

The usual summary — “multipath needs equal-length AS_PATHs” — is not strict enough. By default FRR requires the candidate paths to carry the same AS_PATH: same length and same contents. Two paths of length 1 that traverse different neighbouring ASNs are not multipath candidates by default, even though every metric about them is equal.

flowchart TD
  P1["Path 1: AS_PATH = 64512"]
  P2["Path 2: AS_PATH = 64513"]
  P3["Path 3: AS_PATH = 64512"]
  P1 --> Q{"Compare AS_PATH"}
  P2 --> Q
  P3 --> Q
  Q -->|"identical contents<br/>(paths 1 and 3)"| M1["Multipath candidates by default"]
  Q -->|"same length, different ASN<br/>(path 2)"| M2["Not a candidate<br/>until multipath-relax"]

bestpath as-path multipath-relax changes the comparison from “same AS_PATH” to “same AS_PATH length”. That is the whole of what it does:

configure
set protocols bgp system-as 65001
set protocols bgp parameters bestpath as-path multipath-relax
commit
save

The knob sits under parameters, at the BGP instance level, and applies to every prefix the instance evaluates.

Where eligibility is decided

Multipath eligibility is not a separate algorithm. It is the same best-path comparison, run to the end, with the paths that tie against the winner collected instead of discarded:

  1. The best-path comparison runs over all valid paths for the prefix and produces one winner.
  2. Every other path is compared against that winner. To be a multipath candidate it must tie on weight, local preference, AS_PATH length, origin, MED (where the paths are MED-comparable) and the IGP metric to the next-hop.
  3. The AS_PATH is compared for identity, unless bestpath as-path multipath-relax reduced that to length.
  4. The peer type must match — eBGP paths group with eBGP paths and iBGP with iBGP — unless bestpath peer-type multipath-relax is set.
  5. Whatever survives is capped by maximum-paths for the relevant peer type, and the survivors are installed.

The best-path algorithm itself is covered in vyos-xxvii-01-best-path-algorithm. What matters here is that multipath is a tie-collection pass over that algorithm’s result — so any attribute that breaks the tie also removes the path from consideration, and the fix is always to equalise the attribute rather than to configure around it.

flowchart TD
  A["All valid paths for the prefix"]
  A --> B["Best-path comparison picks one winner"]
  B --> C{"Ties with the winner on weight,<br/>local-pref, AS_PATH length,<br/>origin, MED, IGP metric?"}
  C -->|no| X["Not a candidate"]
  C -->|yes| D{"AS_PATH identical,<br/>or multipath-relax set?"}
  D -->|no| X
  D -->|yes| E{"Same peer type,<br/>or peer-type multipath-relax?"}
  E -->|no| X
  E -->|yes| F["Candidate"]
  F --> G["maximum-paths ebgp / ibgp caps the set"]
  G --> FIB["Installed as ECMP next-hops"]

eBGP multipath and iBGP multipath

The two are configured separately, under the address family, and each has its own limit:

configure
set protocols bgp system-as 65001
set protocols bgp address-family ipv4-unicast maximum-paths ebgp 4
set protocols bgp address-family ipv4-unicast maximum-paths ibgp 4
commit
save

eBGP multipath is the common case: several parallel sessions to the same upstream, or to two upstreams you want to load-share across. Four links to one Tier-1 give four paths with an identical AS_PATH, and multipath works without relaxing anything. Two links to two different Tier-1s give two paths of equal length and different content, and that is precisely the case multipath-relax exists for.

iBGP multipath is for paths learned from iBGP peers — typically several route reflectors, or a full mesh where two internal routers both have external reachability for the prefix. It carries one extra requirement that catches people: the IGP metric to each BGP next-hop must be equal. Two RRs reflecting the same prefix with different IGP costs to their next-hops produce one installed path however high maximum-paths ibgp is set.

Both default to 1, which is another way of saying BGP does not do multipath unless you ask.

The configuration walk

Four parallel eBGP sessions to a single upstream, ASN 64512:

configure
set protocols bgp system-as 65001
set protocols bgp address-family ipv4-unicast maximum-paths ebgp 4

set protocols bgp neighbor 192.0.2.2 remote-as '64512'
set protocols bgp neighbor 192.0.2.2 address-family ipv4-unicast
set protocols bgp neighbor 198.51.100.1 remote-as '64512'
set protocols bgp neighbor 198.51.100.1 address-family ipv4-unicast
set protocols bgp neighbor 203.0.113.5 remote-as '64512'
set protocols bgp neighbor 203.0.113.5 address-family ipv4-unicast
set protocols bgp neighbor 192.0.2.10 remote-as '64512'
set protocols bgp neighbor 192.0.2.10 address-family ipv4-unicast

commit
save

No multipath-relax here, and none is needed: all four sessions terminate on the same ASN, so a prefix originated behind it arrives with the same AS_PATH on all four.

Change one of those peers to a different upstream ASN and the picture changes:

configure
set protocols bgp neighbor 203.0.113.5 remote-as '64513'
set protocols bgp parameters bestpath as-path multipath-relax
commit
save

Now the AS_PATH contents differ while the length matches, and multipath-relax is what makes the fourth path eligible.

Reading the result

The BGP table is where eligibility is visible. Look for the multipath flag on each path:

Read-only / Safe
$ show ip bgp 198.51.100.0/24
BGP routing table entry for 198.51.100.0/24, version 42
Paths: (4 available, best #1, table default)
Advertised to non peer-group peers:
10.255.0.9
64512
  192.0.2.2 from 192.0.2.2 (10.255.0.1)
    Origin IGP, metric 0, localpref 100, valid, external, multipath, best (Router ID)
    Last update: Fri Aug 15 09:14:23 2026
64512
  198.51.100.1 from 198.51.100.1 (10.255.0.2)
    Origin IGP, metric 0, localpref 100, valid, external, multipath
    Last update: Fri Aug 15 09:14:25 2026
64512
  203.0.113.5 from 203.0.113.5 (10.255.0.3)
    Origin IGP, metric 0, localpref 100, valid, external, multipath
    Last update: Fri Aug 15 09:14:27 2026
64512
  192.0.2.10 from 192.0.2.10 (10.255.0.4)
    Origin IGP, metric 0, localpref 100, valid, external
    Last update: Fri Aug 15 09:14:29 2026

Illustrative output

Three paths carry multipath and one does not — that fourth path is valid and usable, and BGP has decided it is not equal to the best path. The absence of the flag is the diagnosis; the reason is whichever attribute on that path differs from the winner, and the same output lists them all for comparison.

The FIB is where installation is visible:

Read-only / Safe
$ show ip route 198.51.100.0/24
Routing entry for 198.51.100.0/24
Known via "bgp", distance 20, metric 0, best
Last update 00:04:11 ago
* 192.0.2.2, via eth1, weight 1
* 198.51.100.1, via eth2, weight 1
* 203.0.113.5, via eth3, weight 1

Illustrative output

Both outputs above are illustrative — the exact layout varies between FRR releases, and what you should be reading for is the multipath flag in the first and the number of starred next-hops in the second, not the character-for-character shape.

The pair is the whole diagnostic. Multipath flags present and one next-hop in the FIB means maximum-paths is too low. Multipath flags absent means the eligibility comparison rejected the paths, and the attribute that differs is on screen. There is no third case, which is why these two commands answer the question faster than anything else.

After the change, push it

Changing multipath configuration does not re-evaluate routes already in the table. BGP re-runs policy and selection on receipt, not on configuration change, so a correct configuration can sit above a stale FIB indefinitely:

reset bgp ipv4 192.0.2.2 soft in

The soft form re-runs inbound processing without dropping the adjacency. Do this for each peer offering the prefix, then re-read show ip bgp and show ip route. An operator who commits, reads an unchanged routing table, and concludes the knob did not work is one soft reset away from the right answer.

How it fails

  • Paths are eligible and only one is installed. maximum-paths ebgp or maximum-paths ibgp is still at its default of 1. The BGP table shows multipath flags; the FIB shows one next-hop. This is the cheapest failure to spot and the most common.
  • Nothing is flagged multipath and every attribute looks equal. The AS_PATHs differ in content. Two upstreams of equal distance are still two different ASNs. bestpath as-path multipath-relax is the fix.
  • One path is prepended. Its AS_PATH is longer, so it loses the best-path comparison outright. No multipath knob reaches it — remove the prepend or rewrite the AS_PATH on import.
  • iBGP paths do not multipath despite equal BGP attributes. The IGP metric to the two next-hops differs. Equalise the IGP cost; there is no knob that ignores it for iBGP multipath.
  • An eBGP and an iBGP path never combine. By design. bestpath peer-type multipath-relax is the deliberate override, with the topology consequences that implies.
  • Everything is configured and the table is unchanged. No soft reset was issued after the commit.
  • Multipath is installed and traffic is not spreading. That is the FIB hash, not BGP. Under the default layer-3 hash policy, all traffic between one address pair takes one next-hop regardless of how many exist.

Rollback

Multipath configuration is ordinary VyOS configuration, and backing it out is a forward change:

  • compare before commit, and check that the maximum-paths values are under the address family rather than at the top of the BGP tree.
  • commit-confirm 5 for a change on live peering sessions, because narrowing multipath moves traffic onto fewer links and can congest them immediately.
  • To revert, delete protocols bgp address-family ipv4-unicast maximum-paths ebgp and commit. delete protocols bgp parameters bestpath as-path multipath-relax removes the relaxation.
  • A soft reset is needed after the revert as well, or the FIB keeps next-hops the current configuration would no longer select.

rollback N exists but currently requires a reboot to take effect, so it is a recovery tool for a router you have lost, not a way to back out a multipath change.

Production discipline

Cross-course references

The Linux course’s XIX-Linux-NetFoundations covers the FIB. The OPNsense course’s XXX-OPNsense-DynamicRouting covers the equivalent FRR-managed multipath on the firewall side. vyos-xxvi-04-med and vyos-xxvii-01-best-path-algorithm cover the comparison this lesson collects ties from; vyos-xxx-04-confederations covers the alternative scaling mechanism, and vyos-xxxvi-02-ecmp-config covers what the kernel does with the next-hops once BGP has installed them.

Quiz

Knowledge check · 4 questions

  1. Q1. Without `bestpath as-path multipath-relax`, what relationship must candidate paths have for BGP to install them as multipath?

  2. Q2. Once BGP installs several next-hops for a prefix, the decision about which of them a given packet uses is made by the kernel FIB hash, not by BGP.

  3. Q3. Four eBGP sessions offer the same prefix. Three carry an AS_PATH of length 1 via ASN 64512, 64513 and 64514; the fourth carries length 2 because that upstream prepends. The operator wants all four carrying traffic. What actually works?

    R1 (system-as 65001) has four eBGP sessions. Three upstreams — 64512, 64513 and 64514 — advertise 198.51.100.0/24 with an AS_PATH of length 1. The fourth, 64515, prepends and advertises it with an AS_PATH of length 2. `maximum-paths ebgp 4` is configured. `show ip bgp 198.51.100.0/24` shows one path flagged best and multipath, and none of the others flagged at all. `show ip route 198.51.100.0/24` shows a single next-hop.

  4. Q4. `maximum-paths ibgp 4` is configured and two route reflectors both reflect the prefix, yet only one next-hop is installed. The iBGP sessions are Established and both paths are in the table. What is the missing requirement?

    R1 has iBGP sessions to two route reflectors in different clusters. Both reflect 198.51.100.0/24, and `show ip bgp 198.51.100.0/24` shows two internal paths with equal weight, equal local preference, equal AS_PATH and equal MED. `set protocols bgp address-family ipv4-unicast maximum-paths ibgp 4` is committed. Only one path carries the multipath flag, and `show ip route 198.51.100.0/24` shows a single next-hop. The two BGP next-hops are reachable through different IGP costs — 10 and 20.

Passing score: 75%. Answers are checked in this browser.