BGP Best Path Selection: Walking All Thirteen Steps and Finding the One That Decided
BGP does not pick the fastest path, the shortest path, or the cheapest path. It picks the path that survives a fixed sequence of comparisons, and it stops the moment one comparison produces a winner. That single design decision explains almost every surprising BGP outcome an engineer will encounter: a 100 Gbps transit circuit losing to a 1 Gbps peer because someone set a weight on one router, a customer's traffic leaving through the wrong border because MED was never comparable in the first place, a route that flips destination every time a session resets because the deciding step was "whichever arrived first". None of these are bugs. They are the algorithm doing exactly what it is specified to do.
The algorithm is an ordered list of thirteen comparisons, preceded by a reachability gate. A path whose NEXT_HOP cannot be resolved in the routing table is discarded before any comparison happens. The surviving paths are then compared pairwise: highest WEIGHT, then highest LOCAL_PREF, then locally originated, then shortest AS_PATH, then lowest ORIGIN code, then lowest MED, then eBGP over iBGP, then lowest IGP metric to the next hop, then the multipath determination, then oldest eBGP path, then lowest router ID, then shortest CLUSTER_LIST, then lowest neighbour address. The first comparison that differs decides, and every later comparison is never evaluated. Understanding BGP path selection means knowing which step actually fired — not which attribute looks most interesting in the output.
This article takes the list apart step by step and connects each step to the operational behaviour it produces. Section one establishes the full order, the reachability gate, and the pairwise comparison model that makes step ordering matter more than attribute values. Section two covers the four steps that carry almost all deliberate policy — weight, local preference, local origination, and AS_PATH — including the scoping differences that make weight dangerous and local preference safe. Section three is devoted entirely to MED, because non-comparability, missing-MED handling, and non-deterministic comparison order generate more incidents than the rest of the algorithm combined. Section four covers the endgame: eBGP versus iBGP, IGP metric, multipath, and the tiebreakers that exist only to guarantee a decision. Section five is the verification methodology for a decision you disagree with.

What Exactly Does BGP Compare, and In What Order?
How does BGP choose a best path?
BGP evaluates candidate paths for a prefix through an ordered list of comparisons and selects a winner at the first comparison where the paths differ. Before any comparison, each path must pass a reachability gate: its NEXT_HOP must resolve to a valid entry in the routing table, or the path is not a candidate. The order is weight, local preference, locally originated, AS_PATH length, origin code, MED, eBGP over iBGP, IGP metric to next hop, multipath determination, oldest eBGP path, lowest router ID, shortest cluster list, and lowest neighbour address. Because evaluation short-circuits, an attribute below the deciding step has no effect whatsoever on the outcome.
A Deeper Dive into the Comparison Model
The reachability gate is not step zero — it is a filter
A path whose NEXT_HOP is unresolvable is marked as inaccessible and never enters the comparison. This matters most in iBGP, where the next hop of an externally learned prefix is by default the eBGP peer's address — a link that may not be carried in the IGP. The result is a full BGP table where every prefix shows as inaccessible and nothing is installed, which looks like a session problem and is not one.
R5# show ip bgp 203.0.113.0
BGP routing table entry for 203.0.113.0/24, version 0
Paths: (1 available, no best path)
65001
198.51.100.1 (inaccessible) from 10.0.0.1 (10.0.0.1)
Origin IGP, metric 0, localpref 100, valid, internal
! ^ The path is valid but the next hop 198.51.100.1 is not in the RIB.
! No best path is elected. Fix with next-hop-self or carry the link in the IGP.
! The standard fix on the route reflector or border router
router bgp 65000
address-family ipv4 unicast
neighbor 10.0.0.5 next-hop-self
exit-address-family
! Alternative: advertise the eBGP link into the IGP as a passive interface
Pairwise comparison, and why order of arrival can matter
BGP does not sort all candidates and pick a maximum. It compares paths pairwise, keeping a running best. For a strictly ordered comparison this produces the same answer regardless of sequence. MED breaks that property, because MED is only comparable between paths from the same neighbouring AS — a comparison that is not transitive. That is why bgp deterministic-med exists, and why a network without it can elect different best paths on two identically configured routers.
What "best" actually gets you
The best path is the one installed in the RIB, subject to administrative distance, and the only path advertised to peers. That second consequence is often more operationally significant than the first: BGP advertises only its best path, so a suboptimal selection at one router propagates a suboptimal view to every downstream neighbour. Add-path changes this, but it is opt-in and per-session.
| Path source | Administrative distance | Advertised to eBGP peers | Advertised to iBGP peers |
|---|---|---|---|
| eBGP learned | 20 | Yes, if best | Yes, if best |
| iBGP learned | 200 | Yes, if best | No — iBGP does not re-advertise iBGP routes (route reflection is the exception) |
Locally originated (network) |
200 | Yes | Yes |
Aggregate (aggregate-address) |
200 | Yes | Yes |
Reading the output that tells you the decision
The show ip bgp <prefix> output flags exactly one path as best. Everything you need to reconstruct the decision is in the attribute line of each path, but only if you read it in algorithm order rather than left to right.
R1# show ip bgp 203.0.113.0/24
BGP routing table entry for 203.0.113.0/24, version 17
Paths: (2 available, best #2, table default)
Advertised to update-groups: 2
Refresh Epoch 1
65002 65010
192.0.2.6 from 192.0.2.6 (192.0.2.6)
Origin IGP, metric 0, localpref 100, valid, external
rx pathid: 0, tx pathid: 0
Refresh Epoch 1
65001 65010
192.0.2.2 from 192.0.2.2 (192.0.2.2)
Origin IGP, metric 0, localpref 100, valid, external, best
rx pathid: 0, tx pathid: 0
! Both AS_PATHs are length 2, both localpref 100, both external, both
! metric 0 but from DIFFERENT neighbouring ASes so MED is not compared.
! The decision fell through to a tiebreaker - see section four.
How Do the Four Policy Steps Behave in Practice?
Which steps do engineers actually use to steer traffic?
Four: weight, local preference, local origination, and AS_PATH length. Weight is Cisco-proprietary, never advertised, and applies only to the router where it is set — it decides at step 1 and overrides everything, which makes it powerful for a single-router policy and destructive when applied inconsistently. Local preference is carried in iBGP throughout the AS and is the correct tool for expressing an AS-wide preference for outbound traffic. AS_PATH prepending is the only one of the four that influences inbound traffic, because it is the only one other autonomous systems evaluate. Local origination rarely gets used deliberately; it usually appears as a surprise.
A Deeper Dive into Weight, Local Preference, Origination, and AS_PATH
Weight: highest wins, and nobody else knows
Weight is a 16-bit value from 0 to 65535, defaulting to 0 for learned paths and 32768 for paths the local router originates. It is never encoded in an UPDATE, so it does not propagate to any peer, iBGP or eBGP. Setting weight on one router changes that router's decision and nothing else — which is exactly the failure mode. Two border routers with different weights for the same prefix will each prefer their own exit, and traffic will take whichever one the IGP happened to steer it toward.
! Weight per neighbour - blunt, applies to every prefix from that peer
router bgp 65000
neighbor 192.0.2.2 weight 200
!
! Weight per prefix via route-map - the controllable form
route-map PREFER-TRANSIT-A permit 10
match ip address prefix-list CUSTOMER-ROUTES
set weight 300
route-map PREFER-TRANSIT-A permit 20
!
router bgp 65000
address-family ipv4 unicast
neighbor 192.0.2.2 route-map PREFER-TRANSIT-A in
show ip bgp <prefix> on both borders and compare the best marker and the weight column in show ip bgp. Fix: use local preference instead for any policy that must apply AS-wide. Reserve weight for single-router scenarios such as a small stub site with two upstreams on the same box.Local preference: the correct tool for AS-wide outbound policy
LOCAL_PREF is a well-known discretionary attribute with a default of 100. It is carried in iBGP UPDATEs across the entire AS, including across confederation sub-AS boundaries, and it is stripped when advertising to a true eBGP peer. That scoping is precisely what makes it the right instrument: set it once at the ingress point and every router in the AS inherits the preference.
! Prefer transit B for all customer prefixes, AS-wide
route-map SET-LP-TRANSIT-B permit 10
match as-path 10
set local-preference 200
route-map SET-LP-TRANSIT-B permit 20
set local-preference 150
!
ip as-path access-list 10 permit ^65002_
!
router bgp 65000
address-family ipv4 unicast
neighbor 192.0.2.6 route-map SET-LP-TRANSIT-B in
! Change the AS-wide default if 100 is inconvenient
bgp default local-preference 100
| Attribute | Scope | Direction it influences | Default | Correct use |
|---|---|---|---|---|
| WEIGHT | One router only; never advertised | Outbound from that router | 0 learned / 32768 local | Single-router multi-homing, or a targeted local override |
| LOCAL_PREF | Entire AS including confederation sub-ASes | Outbound from the AS | 100 | AS-wide exit preference — the default choice |
| AS_PATH prepend | Propagates to every downstream AS | Inbound to the AS | No prepending | Influencing which upstream sends you traffic |
| MED | One AS hop only; not propagated further by default | Inbound to the AS, from one adjacent AS | 0 or absent | Steering a single neighbouring AS between two shared links |
Locally originated: the step you meet by accident
Step 3 prefers a path the local router originated over one learned from a peer, and within that, a path from network or redistribution over one from aggregate-address. It exists to make a router prefer its own advertisement rather than a copy that has looped back. The accident happens during migrations: a prefix is originated locally with a network statement for testing and then the real path arrives via iBGP. Step 3 fires, the local origination wins, and traffic for that prefix is black-holed at the router that has no actual connectivity to it.
! A network statement only originates if the exact prefix is in the RIB
router bgp 65000
address-family ipv4 unicast
network 203.0.113.0 mask 255.255.255.0
! Common guard: originate only when a real route exists
ip route 203.0.113.0 255.255.255.0 Null0 250
! ^ A floating static to Null0 makes the network statement always originate,
! which is intentional for aggregates and a black hole for anything else.
AS_PATH: length only, and what counts as length
Step 4 compares the number of AS numbers in the path, not their values. Three details change the count. An AS_SET — produced by aggregate-address without summary-only semantics that suppress it — counts as exactly one regardless of how many ASes it contains. Confederation segments (AS_CONFED_SEQUENCE and AS_CONFED_SET) count as zero, which is what makes a confederation invisible to path-length comparison outside it. And bgp bestpath as-path ignore removes step 4 entirely, which is occasionally right in a tightly controlled network and usually a way to hide a policy problem.
! Prepending: influences INBOUND traffic, applied OUTBOUND
route-map PREPEND-TO-TRANSIT-B permit 10
set as-path prepend 65000 65000 65000
!
router bgp 65000
address-family ipv4 unicast
neighbor 192.0.2.6 route-map PREPEND-TO-TRANSIT-B out
! Three prepends is a common ceiling - many providers filter or ignore
! excessive prepending, and it has no effect on an AS that uses local-pref.
Why Does MED Cause More Incidents Than Any Other Step?
What makes MED different from every other comparison?
MED is the only step that is conditionally comparable. Every other attribute is compared between any two paths; MED is compared only between paths whose leftmost AS in the AS_PATH is the same — that is, paths received from the same neighbouring autonomous system. Two paths from different ASes skip step 6 entirely no matter what their MED values are. Because comparability is not transitive, the result of a pairwise comparison sequence can depend on the order in which paths were received, which is why bgp deterministic-med exists. Add the ambiguity around a missing MED and you have three independent ways for the same configuration to produce different results on different routers.
A Deeper Dive into MED Comparability, Determinism, and Defaults
The comparability rule, stated precisely
MED is compared only when the paths come from the same neighbouring AS. On Cisco, this means the first AS in the AS_PATH must match. Paths from AS 65001 and AS 65002 are not MED-comparable even if both carry MED 50 and MED 500. This is deliberate: MED expresses "of my two links to you, prefer this one", and comparing it across ASes would let one provider influence your choice of a different provider.
bgp always-compare-med removes the restriction and compares MED across all paths. It is occasionally correct inside a single administrative domain with multiple sub-ASes; it is almost always wrong facing the internet, because it hands your traffic-engineering decision to whichever upstream sets the lowest number.
! MED comparability controls - understand each before enabling
router bgp 65000
! Compare MED across different neighbouring ASes (rarely correct)
bgp always-compare-med
! Remove order-dependence from MED comparison (almost always correct)
bgp deterministic-med
! Treat an absent MED as 4294967295 instead of 0
bgp bestpath med missing-as-worst
! Compare MED among confederation sub-AS paths
bgp bestpath med confed
Deterministic MED, and the failure it prevents
Without deterministic MED, BGP compares paths in the order they were received, keeping a running best. Suppose three paths arrive: A from AS 65001 with MED 200, B from AS 65002 with MED 150, C from AS 65001 with MED 100. Comparing A against B, MED is skipped (different ASes) and some later step picks a winner. Comparing that winner against C may or may not involve a MED comparison depending on which path survived. The final answer therefore depends on arrival order — and arrival order differs between routers, and changes when a session resets.
Deterministic MED fixes this by grouping paths by neighbouring AS first, choosing the best within each group, and only then comparing group winners. The result is stable and identical on every router. Enable it network-wide, not on individual routers, because a partial deployment produces exactly the inconsistency you are trying to eliminate. IOS and IOS-XE leave it disabled by default; NX-OS enables it by default and exposes bestpath med non-deterministic to turn it off. Verify your platform's state rather than assuming.
! Confirm the actual state on this box before drawing conclusions
R1# show ip bgp | include deterministic|always-compare
R1# show running-config | section router bgp
router bgp 65000
bgp log-neighbor-changes
bgp deterministic-med
! Absent from the running config on IOS means it is OFF.
bgp deterministic-med is configured on one and not the other, so one sorts before comparing and the other does not. Confirm: compare show running-config | section router bgp across all BGP speakers, or check show ip bgp <prefix> on each and note which path carries the best flag. Fix: enable it everywhere in the AS in one change window. This requires a soft reset to take effect on existing paths: clear ip bgp * soft in.The missing MED, and why the default is dangerous
When a path carries no MED attribute at all, Cisco treats it as 0 — the most preferred value. A neighbour that sets MED on one link and omits it on the other will therefore have the omitted link preferred, which is usually the opposite of the intent. bgp bestpath med missing-as-worst reverses this, treating an absent MED as the maximum 32-bit value. RFC 4271 leaves the handling to implementation, so heterogeneous networks genuinely differ here.
| Scenario | Default Cisco behaviour | With missing-as-worst |
Recommended setting |
|---|---|---|---|
| Both paths carry MED, same neighbour AS | Lower MED wins | Lower MED wins | Either — no difference |
| One path has MED 50, the other has none | The path with no MED wins (treated as 0) | The path with MED 50 wins | missing-as-worst, to match operator intent |
| Paths from different neighbouring ASes | MED not compared at all | Still not compared | Leave always-compare-med off |
| Multiple paths, mixed neighbouring ASes | Result may depend on arrival order | Still order-dependent | deterministic-med — this is the fix, not missing-as-worst |
MED propagation scope
MED is a non-transitive optional attribute. A router receiving a MED from an eBGP peer propagates it within its own AS over iBGP, but strips it when advertising onward to a different eBGP peer — unless it explicitly sets one. This one-AS-hop scope is what makes MED a bilateral agreement between two adjacent ASes rather than a global signal.
! Setting MED outbound to influence which of two links a peer uses
route-map MED-PRIMARY permit 10
set metric 50
!
route-map MED-BACKUP permit 10
set metric 200
!
router bgp 65000
address-family ipv4 unicast
neighbor 192.0.2.2 route-map MED-PRIMARY out
neighbor 192.0.2.10 route-map MED-BACKUP out
! Both neighbours must be in the SAME AS for this to be compared at all.
show ip bgp <prefix> and read the leftmost AS of each candidate path. If they differ, MED is not in play and you can skip the entire attribute. Half of all "MED is not working" reports resolve at this question.How Do the Final Steps and Multipath Decide When Policy Does Not?
What happens when every policy attribute is equal?
The algorithm falls through to structural and arbitrary tiebreakers. Step 7 prefers eBGP over confederation-eBGP over iBGP, which encodes a general preference for leaving the AS rather than crossing it. Step 8 prefers the lowest IGP metric to the next hop — this is hot-potato routing, and it means your BGP decision changes whenever your IGP changes. Step 9 determines whether multiple paths qualify for installation. Steps 10 through 13 are pure tiebreakers designed only to guarantee that a decision is reached: oldest eBGP path, lowest router ID or ORIGINATOR_ID, shortest CLUSTER_LIST, and finally lowest neighbour IP address.
A Deeper Dive into the Endgame Steps
Step 7 and confederations
The preference order at step 7 is eBGP, then confederation-external, then iBGP. Confederation-external paths sit between the two because they cross a sub-AS boundary but remain inside the real AS. This is one of two places confederations change the algorithm — the other is AS_PATH length, where confederation segments count as zero.
Step 8 is hot-potato routing, and it couples BGP to your IGP
When two iBGP paths are otherwise equal, the router prefers the one whose next hop is closest according to the IGP. The intent is to hand traffic off to the neighbouring AS as quickly as possible. The consequence is a coupling that surprises people: an OSPF cost change on an internal link, made for internal reasons, can move a large volume of external traffic from one border router to another. bgp bestpath igp-metric ignore disables the step where that coupling is unacceptable.
R3# show ip bgp 203.0.113.0/24
BGP routing table entry for 203.0.113.0/24, version 42
Paths: (2 available, best #1, table default)
65001 65010
10.0.0.1 (metric 30) from 10.0.0.1 (10.0.0.1)
Origin IGP, metric 0, localpref 100, valid, internal, best
65001 65010
10.0.0.2 (metric 50) from 10.0.0.2 (10.0.0.2)
Origin IGP, metric 0, localpref 100, valid, internal
! ^ Identical through step 7. The '(metric 30)' vs '(metric 50)' is the
! IGP cost to each next hop - step 8 decided this.
Multipath: what has to be equal, and what can be relaxed
Multipath installs more than one path in the RIB while still electing a single best path for advertisement. To qualify, candidate paths must match the best path on weight, local preference, AS_PATH length and content, origin, MED, and — for iBGP multipath — IGP metric. The AS_PATH content requirement means two paths of equal length through different ASes do not qualify by default. bgp bestpath as-path multipath-relax relaxes it to length only, which is what most multi-homed enterprises actually want.
! eBGP multipath across two transits with equal-length AS_PATHs
router bgp 65000
address-family ipv4 unicast
maximum-paths 4
! Without this, paths via 65001 and 65002 will not bundle
bgp bestpath as-path multipath-relax
exit-address-family
!
! iBGP multipath is a separate keyword and a separate limit
router bgp 65000
address-family ipv4 unicast
maximum-paths ibgp 4
exit-address-family
R1# show ip bgp 203.0.113.0/24
Paths: (2 available, best #2, table default)
65002 65010
192.0.2.6 from 192.0.2.6 (192.0.2.6)
Origin IGP, localpref 100, valid, external, multipath
65001 65010
192.0.2.2 from 192.0.2.2 (192.0.2.2)
Origin IGP, localpref 100, valid, external, best
!
R1# show ip route 203.0.113.0
Routing entry for 203.0.113.0/24
Known via "bgp 65000", distance 20, metric 0
Routing Descriptor Blocks:
* 192.0.2.2, from 192.0.2.2, 00:03:12 ago
Route metric is 0, traffic share count is 1
192.0.2.6, from 192.0.2.6, 00:03:12 ago
Route metric is 0, traffic share count is 1
Step 10: the oldest path, and why it is not the default any more in many designs
When two paths are both eBGP and everything above is equal, BGP prefers the one it received first. The rationale is stability: the incumbent path stays, so a newly established session does not cause a churn. The cost is non-determinism — "which arrived first" depends on session establishment order, which depends on reload order. bgp bestpath compare-routerid disables step 10 so that selection falls through to the router ID comparison, producing a deterministic and reproducible result across reloads.
! Make eBGP tiebreaking deterministic instead of arrival-order dependent
router bgp 65000
bgp bestpath compare-routerid
! Trade-off: a returning path can now displace the incumbent, causing
! a brief reconvergence that the oldest-path rule was designed to avoid.
Steps 11 to 13: identifiers of last resort
The lowest BGP router ID wins at step 11, with one substitution: if the path carries an ORIGINATOR_ID — added by a route reflector — that value is used instead of the advertising router's ID. Step 12 prefers the shortest CLUSTER_LIST, which favours paths that traversed fewer reflection layers. Step 13 prefers the lowest neighbour IP address, and exists purely so the algorithm cannot fail to terminate.
| Step | Comparison | Deterministic across reloads? | Can it be disabled? | Design note |
|---|---|---|---|---|
| 7 | eBGP > confed-eBGP > iBGP | Yes | No | Encodes hot-potato intent structurally |
| 8 | Lowest IGP metric to next hop | Yes, given a stable IGP | bgp bestpath igp-metric ignore |
Couples BGP selection to IGP cost changes |
| 9 | Multipath qualification | Yes | Off unless maximum-paths set |
Needs multipath-relax for different-AS bundling |
| 10 | Oldest eBGP path | No | bgp bestpath compare-routerid |
Stability versus reproducibility trade-off |
| 11 | Lowest RID / ORIGINATOR_ID | Yes | No | Pin router IDs so this stays stable |
| 12 | Shortest CLUSTER_LIST | Yes | No | Favours fewer reflection hops |
| 13 | Lowest neighbour address | Yes | No | Termination guarantee only |
How Do I Troubleshoot a Best-Path Decision I Disagree With?
What is the fastest way to find the deciding step?
Work the list top-down and stop at the first difference. Dump the prefix with show ip bgp <prefix>, then for each candidate path record weight, local preference, whether it is locally originated, AS_PATH length, origin code, MED plus its leftmost AS, eBGP or iBGP, and the IGP metric to the next hop. The first row where the values differ is the deciding step; everything below it is irrelevant and everything above it is already tied. Four commands cover the data gathering, and the discipline of filling in the table rather than eyeballing the output is what makes the method fast.
A Deeper Dive into a Structured Troubleshooting Method
Command set for evidence gathering
! 1. The candidate paths and their attributes
show ip bgp 203.0.113.0/24
!
! 2. Weight is only in the table view, not the per-prefix detail
show ip bgp | include 203.0.113.0
!
! 3. What the peer actually sent, before your inbound policy
show ip bgp neighbors 192.0.2.2 received-routes
! Requires soft-reconfiguration inbound, or use:
show ip bgp neighbors 192.0.2.2 routes
!
! 4. What you are advertising onward
show ip bgp neighbors 192.0.2.6 advertised-routes
!
! 5. Resolve the next hop - step 8 and the reachability gate both need this
show ip route 10.0.0.1
show ip bgp neighbors X received-routes returns nothing unless neighbor X soft-reconfiguration inbound is configured, because the router does not otherwise store the pre-policy table. That costs memory proportional to the table size — significant on a full internet table. Enable it selectively for a troubleshooting window and remove it afterwards.The comparison worksheet
Fill this in for each candidate path. The first row with different values is the answer, and you can stop.
| Step | What to record | Where to read it | Common trap |
|---|---|---|---|
| Gate | Is the next hop in the RIB? | show ip route <nexthop> |
inaccessible in the prefix detail; missing next-hop-self |
| 1 Weight | Weight value per path | show ip bgp table view, rightmost column |
Not shown in the per-prefix detail output at all |
| 2 Local pref | localpref in the attribute line |
Per-prefix detail | Absent on eBGP-received paths until inbound policy sets it |
| 3 Local origin | Next hop 0.0.0.0, or local |
Per-prefix detail | Leftover network statement from a migration |
| 4 AS_PATH | Number of ASes, AS_SET as 1, confed as 0 | First line of each path | Counting confederation segments as real hops |
| 5 Origin | Origin IGP / EGP / incomplete |
Attribute line | Redistributed routes are incomplete and lose to identical network-originated ones |
| 6 MED | metric value AND leftmost AS |
Attribute line plus AS_PATH | Comparing MED between different neighbouring ASes |
| 7 Type | external / internal / confed-external |
Attribute line | Assuming iBGP can beat eBGP on a better IGP metric |
| 8 IGP metric | (metric N) after the next hop |
Per-prefix detail | Confusing this with the MED, which is also called "metric" |
metric field, when in fact step 8 decided it. Cause: IOS prints the MED as metric N in the attribute line and the IGP cost to the next hop as (metric N) in parentheses immediately after the next-hop address. Confirm: check the position — parenthesised and adjacent to the next hop means IGP cost; after Origin means MED. Fix: nothing to fix in the network; fix the reading. This single ambiguity is responsible for a large share of misdiagnosed BGP tickets.Using conditional debugging safely on a production router
Unfiltered BGP debugging on a router carrying a full table will overwhelm the console and can destabilise the box. Always scope it with an access list or a BGP-specific debug filter, and always confirm the logging destination is the buffer rather than the console before enabling it.
! Scope the debug to one prefix - never run this unfiltered
access-list 55 permit 203.0.113.0 0.0.0.255
!
! Log to the buffer, not the console
no logging console
logging buffered 512000 debugging
!
debug ip bgp updates 55
! Trigger a fresh advertisement without tearing down the session
clear ip bgp 192.0.2.2 soft in
!
show logging | include 203.0.113
undebug all
Soft reset versus hard reset
Changing inbound policy requires re-evaluating routes the peer already sent. A hard reset (clear ip bgp 192.0.2.2) tears down the TCP session and withdraws everything — disruptive and rarely necessary. A soft reset uses the route refresh capability, negotiated by essentially every modern implementation, to ask the peer to resend without dropping the session.
! Confirm route refresh is negotiated before relying on soft reset
R1# show ip bgp neighbors 192.0.2.2 | include Route refresh
Route refresh: advertised and received(new)
!
! Re-apply inbound policy - no session teardown
clear ip bgp 192.0.2.2 soft in
! Re-apply outbound policy - always local, never disruptive
clear ip bgp 192.0.2.2 soft out
! Hard reset - drops the session, withdraws all prefixes
! clear ip bgp 192.0.2.2
best marker on the prefix, and the actual forwarding entry with show ip cef <prefix>. A best-path change that has not reached CEF is not moving any packets, and that gap — usually a next-hop resolution problem — is invisible in the BGP table.Conclusion
The BGP decision process is often described as complicated, and it is not. It is long, which is a different property. Each individual comparison is trivial — a number against a number, a flag against a flag — and the complexity people experience comes entirely from the interaction between the ordering and the scope of each attribute. Weight decides at step 1 but is invisible to every other router. Local preference decides at step 2 and is visible to the whole AS. MED decides at step 6 but only sometimes, and only between certain pairs. Once you hold those three scoping facts alongside the order, the algorithm stops producing surprises, because every surprising outcome turns out to be a step you did not realise had already fired.
The methodology this yields is mechanical and fast. Establish the candidate set by confirming next-hop reachability, because a path that fails the gate is not competing at all. Walk the steps in order and stop at the first difference, resisting the temptation to look at whichever attribute seems most interesting. Match the scope of your chosen instrument to the scope of your intent: weight for one router, local preference for one AS, prepending or communities for someone else's AS, MED only for a single adjacent AS with which you have an actual agreement. And when the decision falls through to step 10 or below, treat that as a finding rather than an answer — the network is choosing because you did not.
Operationally the payoff is a network whose traffic direction you can predict from the configuration rather than discover from a flow report. In the lab the payoff is speed: a task that says "make traffic to this prefix use the second provider, using only local preference" is answered in one route-map and thirty seconds once you know that local preference fires at step 2 and therefore overrides AS_PATH length, origin, MED, and everything after. Build a four-router topology with two upstream ASes, set each attribute in turn, and watch the best marker move. Watching which attributes fail to move it is the more instructive half of the exercise.
Reference Notes
- RFC 4271, Section 9.1 — the BGP Decision Process: Phase 1 degree of preference, Phase 2 route selection, Phase 3 route dissemination.
- RFC 4271, Section 9.1.2.1 — the requirement that a route's NEXT_HOP be resolvable before the route is considered, which is the reachability gate.
- RFC 4271, Section 5.1.5 — LOCAL_PREF as a well-known discretionary attribute included only in UPDATEs sent to internal peers.
- RFC 4271, Section 5.1.4 — MULTI_EXIT_DISC as an optional non-transitive attribute, and the rule restricting comparison to routes from the same neighbouring AS.
- RFC 4271, Section 5.1.1 — ORIGIN values IGP (0), EGP (1), and INCOMPLETE (2), and their ordering.
- RFC 4271, Section 5.1.2 — AS_PATH segment types AS_SET and AS_SEQUENCE; AS_SET contributes 1 to path length.
- RFC 5065, Section 5 — AS_CONFED_SEQUENCE and AS_CONFED_SET are excluded from AS_PATH length comparison.
- RFC 4456, Section 7 — ORIGINATOR_ID substitutes for the originating router's BGP identifier, and CLUSTER_LIST records reflection path.
- RFC 2918 — the Route Refresh capability and the ROUTE-REFRESH message used by soft inbound reset.
- Cisco, "BGP Best Path Selection Algorithm" — the thirteen-step ordering including weight at step 1, the oldest-eBGP-path rule, and the conditions for multipath installation.
- Cisco, "BGP Best Path Selection Algorithm" — default administrative distances of 20 for eBGP and 200 for iBGP and locally originated routes.
- Cisco IOS-XE BGP Configuration Guide (17.x) — syntax and behaviour of
bgp deterministic-med,bgp always-compare-med,bgp bestpath med missing-as-worst,bgp bestpath compare-routerid, andbgp bestpath as-path multipath-relax.