Skip to main content
RunBook Academy

VyOSII · Routing FundamentalsRouting primitives

Administrative distance — how a router prefers one source over another

Foundation⏱ ~16 minvyosshow ip routeip

What you'll learn

  • Locate administrative distance in the right place — zebra's RIB, not the kernel FIB
  • State the FRR 10 default distance for every routing source VyOS 1.5 can produce
  • Explain the difference between distance and metric, and when each one is consulted
  • Configure a non-default distance for static routes, OSPF and BGP in VyOS 1.5 syntax
  • Diagnose a route-selection incident caused by a wrong distance

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) · 2026-08-19

Not yet marked complete on this device.

Administrative distance is the trust value FRR assigns to a route based on which routing source produced it. When two sources offer a route to the same prefix, FRR installs the one with the lower distance and leaves the other in the RIB, unselected.

Longest-prefix match runs first and is a different question: it picks which prefix answers a destination. Distance only ever compares candidate routes that cover the identical prefix. A /24 static and a /16 OSPF route never compete on distance at all — the /24 is more specific, so it wins on match length before distance is consulted.

The operator who understands distance can predict which route will be installed in any collision. The operator who does not spends hours on “the route I configured is not being used” incidents that come down to one number.

Where administrative distance actually lives

The Linux kernel has no concept of administrative distance. Its routing table has a destination, a next-hop, a scope, a proto byte recording who installed the entry, and a metric (properly, a priority) used to order otherwise-identical entries. There is no field for trust, and no arbitration between routing daemons.

That arbitration is zebra’s job. Every FRR daemon — bgpd, ospfd, staticd, and the rest — offers its routes to zebra. Zebra keeps them all in the RIB, picks a winner per prefix, and pushes only the winner into the kernel FIB over netlink.

flowchart TB
  S1["staticd<br/>0.0.0.0/0 distance 1"] --> RIB
  S2["ospfd<br/>0.0.0.0/0 distance 110"] --> RIB
  S3["bgpd<br/>0.0.0.0/0 distance 20"] --> RIB
  RIB["zebra RIB<br/>all candidates for a prefix"] --> SEL{"lowest distance<br/>for this prefix"}
  SEL --> FIB["kernel FIB<br/>one selected route"]
  SEL -.->|"kept, not selected"| RIB
  FIB --> FWD["forwarding"]

This is why the two views disagree, and why that disagreement is not a bug:

  • show ip route 0.0.0.0/0 shows every candidate with its distance and marks the selected one. This is the view that explains a decision.
  • ip route show 0.0.0.0/0 shows only what zebra installed. This is the view that tells you what the box is forwarding on right now.

The distance table FRR 10 ships

These are zebra’s compiled-in defaults for the sources a VyOS 1.5 router can actually produce:

SourceDistanceWhat produces it on VyOS
Connected0An address on an interface that is up
Local0The host route for the router’s own address
Kernel0A route the kernel installed and zebra learned over netlink — an IPv6 default from a Router Advertisement, for instance
Static1set protocols static route ..., including blackhole and reject routes
eBGP20set protocols bgp neighbor ... where the peer’s remote-as differs from system-as
OSPFv2 / OSPFv3110set protocols ospf ... / set protocols ospfv3 ...
IS-IS115set protocols isis ...
RIP / RIPng120set protocols rip ... / set protocols ripng ...
iBGP200set protocols bgp neighbor ... where the peer’s remote-as equals system-as

Two entries commonly quoted from vendor documentation are worth naming precisely so you do not go looking for them:

  • eBGP and iBGP are one protocol with two distances. Zebra stores a single BGP entry; bgpd tells it 20 or 200 depending on whether the route was learned from an external or an internal peer. There is no separate “eBGP protocol” in show ip route.
  • EIGRP is a Cisco protocol. FRR carries an eigrpd, but VyOS 1.5 does not expose it in the configuration tree, so the classic 90/170 pair never appears on a VyOS box. If a design document quotes those numbers, it is describing a Cisco device in the same network, not this one.

FRR also carries defaults for sources this table omits — Babel, NHRP, LDP, and several daemons VyOS does not surface. Read the number off the box rather than out of memory: show ip route <prefix> prints the distance it actually used, and that number is the one that decided the outcome.

Distance versus metric

They are different comparisons run at different stages, and confusing them is the single most common source of “the numbers say I should win” tickets.

  • Distance ranks sources. Lower is more trusted. Zebra compares distance across every candidate for a prefix, whatever protocol produced it.
  • Metric ranks paths inside one source. Lower is better. OSPF cost, IS-IS metric and RIP hop count are metrics. A protocol has already used its own metric to choose which route it offers to zebra before zebra ever sees it.

Zebra compares metric only between two candidates that tie on distance. Since a tie on distance almost always means “two routes from the same protocol”, the metric comparison is nearly always within-protocol — which is exactly what it was designed for.

The practical consequence: an OSPF cost of 10 does not beat a static route, no matter how low you push it. Distance decides first, the static’s 1 beats OSPF’s 110, and the cost is never read.

Configuring a non-default distance

Static routes

set protocols static route 10.0.0.0/24 next-hop 192.0.2.1 distance 50
set protocols static route 0.0.0.0/0 next-hop 198.51.100.1 distance 200
set protocols static route 198.18.0.0/15 blackhole distance 254

The valid range is 1 to 255. There is no distance 0 for a static route, which is why a static can never displace a connected route.

The second line is the floating-static idiom: a distance of 200 is worse than OSPF’s 110 and worse than eBGP’s 20, so the route sits in the RIB unselected while any dynamic default exists, and becomes the selected default the moment the dynamic one is withdrawn.

OSPF

set protocols ospf distance global 110
set protocols ospf distance ospf intra-area 110
set protocols ospf distance ospf inter-area 110
set protocols ospf distance ospf external 110

distance global sets one value for every OSPF route. The distance ospf sub-tree sets them per route class, and takes precedence over distance global for the classes it names. Raising external alone is the one variant with a routine use: it makes routes OSPF learned by redistribution lose to something else without touching OSPF’s view of its own area topology.

BGP

In VyOS 1.5, BGP distance is an address-family property, not a top-level one:

set protocols bgp system-as 65000
set protocols bgp address-family ipv4-unicast distance global external 20
set protocols bgp address-family ipv4-unicast distance global internal 200
set protocols bgp address-family ipv4-unicast distance global local 200
set protocols bgp address-family ipv4-unicast distance prefix 10.50.0.0/16 distance 250

external, internal and local correspond to routes from eBGP peers, routes from iBGP peers, and locally-originated routes. The distance prefix form overrides all three for one prefix, which is the surgical option when a single prefix is arriving from the wrong place.

The DHCP-learned default route

A WAN interface running DHCP installs a default route whose distance VyOS lets you set directly:

set interfaces ethernet eth0 address dhcp
set interfaces ethernet eth0 dhcp-options default-route-distance 210
set interfaces ethernet eth0 dhcp-options no-default-route

The default value is 210 — deliberately worse than every IGP and every ordinary static, so that a default learned from an ISP’s DHCP server never silently outranks a default the operator or the IGP chose. no-default-route suppresses the learned default entirely, which is what you want on an interface that is DHCP-addressed for management but must not become a path out.

Check the value on your own image with tab completion before designing around it; the point to internalise is the direction, which is that this route is meant to lose.

Reading the decision

The operational-mode commands that matter:

show ip route
show ip route 0.0.0.0/0
show ip route static
show ip route ospf
show ip route bgp
show ip route summary

show ip route <prefix> is the one that answers “why”. It prints one “Routing entry” block per candidate, each with the distance FRR used, and marks the selected one.

Read-only / SafeTwo candidates for one prefix; the lower distance is selected
vyos@vyos:~$ show ip route 0.0.0.0/0
Routing entry for 0.0.0.0/0
Known via "static", distance 1, metric 0, best
* 192.0.2.1, via eth0, weight 1

Routing entry for 0.0.0.0/0
Known via "ospf", distance 110, metric 10
  10.0.0.2, via eth1, weight 1

Illustrative output

Read it as three facts. The Known via string is the source. The distance is the number that was compared. The best marker and the * on the next-hop say which candidate zebra selected and installed; the block without them is a route the router is holding in reserve, not a route it is using.

The kernel side confirms the outcome and nothing more:

ip route show 0.0.0.0/0
ip route get 10.0.5.50

ip route get is worth the habit: it asks the kernel to run a real lookup for one destination and report the entry it would use, including the source address it would pick. That last part catches a class of multi-WAN problem that a table dump does not.

Failure modes

The floating static is winning while the primary is healthy

The backup path is carrying production traffic. show ip route shows the static marked best and the dynamic route present but unselected.

The distance direction has been inverted: the static was given a number lower than the dynamic route’s, so it is more trusted, so it wins. A floating route must be given a distance worse than everything it is backing up.

Fix: raise the static’s distance above the primary’s — 200 or higher against an OSPF or eBGP default. Verify with show ip route 0.0.0.0/0 that the static block has lost its best marker while the primary is up.

The floating static never activates

The reverse symptom, and usually not a distance problem at all. If the primary route is still in the RIB, the backup is correctly staying out of the FIB — the question is why the primary has not been withdrawn.

Diagnostic order:

  1. show ip route <prefix> — is the primary still there? Then the protocol has not withdrawn it, and the backup is behaving correctly.
  2. Is the failure one the protocol can see? A dark fibre drops the link and OSPF withdraws in seconds. A far-side failure that leaves the local link up does not, until the protocol’s dead interval expires.
  3. If sub-second failover is the requirement, distance is not the mechanism. Attach BFD to the primary — set protocols static route 0.0.0.0/0 next-hop 192.0.2.1 bfd for a static primary, or BFD on the OSPF or BGP session — so the withdrawal happens on a timer you control.

A static route is ignored where a connected route exists

A connected route is distance 0 and a static cannot go below 1, so the static will never be selected for a prefix the connected route already covers exactly. show ip route shows it present and not best.

This is not a bug to work around; it is the router refusing to believe a typed statement over an observed link. If the traffic really must leave by a different path, the answer is a more specific prefix (longest-prefix match runs before distance and will win), or policy routing, not a distance edit.

Two equal-distance statics are load-sharing when one was meant as backup

Two set protocols static route statements for the same prefix, both at the default distance 1, produce an ECMP pair rather than a primary and a standby. Flows hash across both, and half of them go out the path that was never meant to carry traffic.

There is no metric to separate them (see the callout above). Give the standby an explicit higher distance — that is the whole fix, and it is the reason the distance leaf exists on a per-next-hop basis.

A prefix is arriving over iBGP when it should come from the IGP

iBGP is 200 and every IGP is below it, so this usually means the IGP is not offering the prefix rather than that BGP is beating it. Check show ip route <prefix> for an OSPF or IS-IS candidate at all before reaching for a distance override; if there is none, the fault is in the IGP’s advertisement, and lowering BGP’s internal distance would only hide it.

Validation

The sequence for “the wrong route won”:

  1. Confirm the prefix. ip route get <destination> — establish which prefix is actually matching, because a longest-prefix-match surprise looks exactly like a distance surprise from the outside.
  2. List the candidates. show ip route <prefix> — every routing entry, every distance, and the best marker.
  3. Name the winner’s source. The Known via string, not a guess from the next-hop address.
  4. Compare against the table above. If the distance printed is not the documented default, something in the configuration overrode it; show configuration commands | match distance finds it.
  5. Check the kernel agrees. ip route show <prefix> should show the candidate that show ip route marked best. A disagreement is a zebra-to-kernel installation failure, which is a different and more serious problem than a selection surprise.
  6. Decide whether the expectation or the configuration was wrong. Both are common. A route that lost to a lower distance behaved correctly, whatever the change ticket said it should do.

Cross-course references

  • Part II’s lesson on longest-prefix match covers the comparison that runs before distance, and the failure where an operator blames distance for an LPM outcome.
  • Part XII’s lessons on static routes cover the full attribute set on set protocols static route, including BFD and blackhole routes.
  • Part XXXVI’s ECMP lessons cover what happens when candidates tie on distance instead of one winning.
  • Part XXXIX’s multi-WAN lessons cover distance as an active-passive control and the three mechanisms it is one of.

Quiz

Knowledge check · 4 questions

  1. Q1. The backup ISP link is carrying production traffic even though the primary is healthy. Explain what selected it, and fix the configuration.

    R1 learns a default route from the core over OSPF: `set protocols ospf default-information originate always` R1 also has a floating static default pointing at a cheap backup circuit: `set protocols static route 0.0.0.0/0 next-hop 198.51.100.1 distance 100` The static was intended as a backup. Monitoring shows the OSPF adjacency up and the core reachable, but egress traffic is leaving over the backup circuit and the ISP is billing overage.

  2. Q2. A static route and an OSPF route both cover 10.20.0.0/16. The static is at the default distance. The OSPF route has a cost of 20. Which does zebra install, and why?

  3. Q3. A static route can never displace a connected route for the same prefix on VyOS 1.5.

  4. Q4. A backup static default is permanently beating the DHCP-learned default from the primary ISP. Explain the two distances involved and correct the design.

    eth0 is the primary ISP handoff and is DHCP-addressed: `set interfaces ethernet eth0 address dhcp` The operator adds a backup default through a second ISP on eth1: `set protocols static route 0.0.0.0/0 next-hop 198.51.100.1` After the commit, all egress traffic leaves via eth1. The DHCP lease on eth0 is current and the primary ISP is up.

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

Production discipline

Administrative distance is one number per routing source, compared once per prefix, in one process. Learn the defaults, read the real number off show ip route rather than recalling it, and treat every override as something that needs a written reason attached to it. Distance is not a tuning knob — it is the router’s statement about which of its informants it believes, and changing it changes that belief everywhere at once.