BGP Foundations Part 3: Building and Breaking Every Best-Path Tie

Build and break BGP best-path ties in a seven-router lab, testing Weight, Local Preference, AS_PATH, Origin, MED, eBGP vs. iBGP, IGP cost, multipath, route reflection, and the final tie-breakers that determine which route wins.
89 min read

On this page

In the previous Learning Byte, we followed BGP routes across multiple autonomous systems and saw how AS_PATH can influence which route is selected. We also ended with a more interesting question: what happens when AS_PATH alone cannot determine the winner?

That question leads us into BGP best-path selection.

BGP does not rely on a single metric to choose a route. Instead, it evaluates competing paths using an ordered set of decision criteria until one of them produces a winner. Weight, Local Preference, locally originated routes, AS_PATH, Origin, MED, eBGP versus iBGP, IGP cost to the next hop, and several later tie-breakers can all influence which path becomes best.

Rather than simply memorizing that list, this post will put the decision process into the lab.

We built a topology specifically for this purpose and will deliberately manipulate individual decision criteria one at a time, observe how the BGP table changes, and use the router’s own output to determine exactly why one path wins over another.

Along the way, we’ll also spend time with the protocols surrounding BGP. The lab uses eBGP between autonomous systems, a full iBGP mesh inside AS65000, and OSPF Area 0 as the internal underlay providing reachability between the iBGP loopbacks.

The goal is not just to memorize the best-path algorithm. By the end of the lab, we should be able to look at competing BGP routes, work through the selection process in order, identify the first attribute that differs, and explain why the router made the decision it did.

What We’ll Cover

In this post, we’ll use one topology and one destination prefix to:

  • build multiple valid BGP paths to the same destination
  • work through Cisco’s best-path process in order and identify the first criterion that breaks each tie
  • manipulate the major BGP policy attributes and verify how the selected path changes
  • see how eBGP, iBGP, next-hop reachability, OSPF cost, and later tie-breakers affect the decision
  • develop a repeatable CLI workflow for explaining why BGP selected a particular path

Lab Topology

For this post, we decided to step things up and build a larger topology than the previous BGP labs.

So far, Netlab and Containerlab have handled the seven-router Cisco IOL environment surprisingly well, which gives us a good opportunity to test a more realistic mix of eBGP, iBGP, and OSPF without making the lab unnecessarily difficult to reproduce.

The topology is built around three autonomous systems:

  • AS65100 — R1
  • AS65000 — R2, R3, R4, R5, and R6
  • AS65200 — R7

R1 connects to AS65000 through R2 and R4 using eBGP, while R7 connects through R5 and R6.

Inside AS65000, the routers run OSPF Area 0 across the physical internal links. The same routers also form a full iBGP mesh using their loopback interfaces, with OSPF providing the reachability needed for those loopback-based sessions.

This gives us multiple paths through the topology and enough flexibility to manipulate BGP attributes without rebuilding the lab every time we move to a new best-path criterion.

Topology.yml

---
provider: clab

defaults:
  device: iol
  devices:
    iol:
      clab:
        image: vrnetlab/cisco_iol:17.12.01

ospf:
  area: 0.0.0.0

nodes:

  # ============================================================
  # AS65100 - External
  # ============================================================

  r1:
    module: [ bgp ]
    bgp:
      as: 65100
    loopback:
      ipv4: 10.1.1.1/32

  # ============================================================
  # AS65000 - Internal
  # OSPF Area 0 + iBGP full mesh using loopbacks
  # ============================================================

  r2:
    module: [ ospf, bgp ]
    bgp:
      as: 65000
    loopback:
      ipv4: 10.2.2.2/32

  r3:
    module: [ ospf, bgp ]
    bgp:
      as: 65000
    loopback:
      ipv4: 10.3.3.3/32

  r4:
    module: [ ospf, bgp ]
    bgp:
      as: 65000
    loopback:
      ipv4: 10.4.4.4/32

  r5:
    module: [ ospf, bgp ]
    bgp:
      as: 65000
    loopback:
      ipv4: 10.5.5.5/32

  r6:
    module: [ ospf, bgp ]
    bgp:
      as: 65000
    loopback:
      ipv4: 10.6.6.6/32

  # ============================================================
  # AS65200 - External
  # ============================================================

  r7:
    module: [ bgp ]
    bgp:
      as: 65200
    loopback:
      ipv4: 10.7.7.7/32

links:

  # ============================================================
  # eBGP - AS65100 <-> AS65000
  # ============================================================

  - name: R1-R2
    r1:
      ipv4: 10.12.12.1/30
    r2:
      ipv4: 10.12.12.2/30

  - name: R1-R4
    r1:
      ipv4: 10.14.14.1/30
    r4:
      ipv4: 10.14.14.2/30

  # ============================================================
  # OSPF Area 0 - AS65000 Internal Links
  # ============================================================

  - name: R2-R3
    r2:
      ipv4: 10.23.23.1/30
    r3:
      ipv4: 10.23.23.2/30

  - name: R3-R4
    r3:
      ipv4: 10.34.34.1/30
    r4:
      ipv4: 10.34.34.2/30

  - name: R2-R6
    r2:
      ipv4: 10.26.26.1/30
    r6:
      ipv4: 10.26.26.2/30

  - name: R4-R5
    r4:
      ipv4: 10.45.45.1/30
    r5:
      ipv4: 10.45.45.2/30

  - name: R5-R6
    r5:
      ipv4: 10.56.56.1/30
    r6:
      ipv4: 10.56.56.2/30

  # ============================================================
  # eBGP - AS65000 <-> AS65200
  # ============================================================

  - name: R6-R7
    r6:
      ipv4: 10.67.67.1/30
    r7:
      ipv4: 10.67.67.2/30

  - name: R5-R7
    r5:
      ipv4: 10.57.57.1/30
    r7:
      ipv4: 10.57.57.2/30

Build the Baseline

Before we start changing BGP attributes, we need to prove that the underlying topology is working as expected.

There are really three control-plane pieces operating in this lab.

Inside AS65000, OSPF Area 0 provides reachability between the internal routers and their loopback addresses. Those loopbacks are then used to establish a full-mesh of iBGP sessions between R2, R3, R4, R5, and R6.

At the edges, eBGP connects AS65000 to the two external autonomous systems.

Verify OSPF First

OSPF is not directly selecting the BGP route, but it provides the underlying reachability that makes our loopback-based iBGP sessions possible. Later in the lab, we’ll also see that the IGP cost to a BGP next hop can become part of BGP’s own best-path decision when all earlier criteria remain tied.

For example, R2 is physically connected to R3 and R6:

r2#show ip ospf neighbor         

Neighbor ID     Pri   State           Dead Time   Address         Interface
10.6.6.6          0   FULL/  -        00:00:34    10.26.26.2      Ethernet0/3
10.3.3.3          0   FULL/  -        00:00:33    10.23.23.2      Ethernet0/2

The same pattern exists throughout AS65000:

R2 -> R3, R6
R3 -> R2, R4
R4 -> R3, R5
R5 -> R4, R6
R6 -> R2, R5

More importantly, R2 should have routes to the loopbacks of the other four internal BGP routers.

r2#show ip route ospf

O        10.3.3.3/32 [110/11] via 10.23.23.2, 00:23:12, Ethernet0/2
O        10.4.4.4/32 [110/21] via 10.23.23.2, 00:23:12, Ethernet0/2
O        10.5.5.5/32 [110/21] via 10.26.26.2, 00:23:10, Ethernet0/3
O        10.6.6.6/32 [110/11] via 10.26.26.2, 00:23:12, Ethernet0/3
O        10.34.34.0/30 [110/20] via 10.23.23.2, 00:23:12, Ethernet0/2
O        10.45.45.0/30 [110/30] via 10.26.26.2, 00:23:10, Ethernet0/3
                       [110/30] via 10.23.23.2, 00:23:12, Ethernet0/2
O        10.56.56.0/30 [110/20] via 10.26.26.2, 00:23:12, Ethernet0/3

For example, R2 needs a route to 10.5.5.5/32 before it can establish a loopback-based BGP session with R5.

We can verify that directly:

r2#show ip route 10.5.5.5

Routing entry for 10.5.5.5/32
  Known via "ospf 1", distance 110, metric 21, type intra area
  Last update from 10.26.26.2 on Ethernet0/3, 00:24:34 ago
  Routing Descriptor Blocks:
  * 10.26.26.2, from 10.5.5.5, 00:24:34 ago, via Ethernet0/3
      Route metric is 21, traffic share count is 1

and, if we want to prove the actual source-to-destination reachability:

r2#ping 10.5.5.5 source 10.2.2.2

Sending 5, 100-byte ICMP Echos to 10.5.5.5, timeout is 2 seconds:
Packet sent with a source address of 10.2.2.2 
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 1/1/1 ms

That last test matters more than a simple ping from an arbitrary interface. Our iBGP sessions are built between the loopbacks, so we want to verify that the exact addresses participating in those sessions can reach one another.

OSPF gets us to the BGP neighbor. BGP exchanges reachability information once that neighbor relationship exists.

Keeping those roles separate will become important later when we reach the IGP-cost-to-the-BGP-next-hop portion of the best-path algorithm.

Verify the iBGP Full Mesh

Once the loopbacks are reachable, we can verify that the iBGP sessions built on top of them are established.

We’ll start from R2:

r2#show ip bgp summary 

Neighbor        V           AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
10.3.3.3        4        65000       5       6       10    0    0 00:00:29        1
10.4.4.4        4        65000       6       6       10    0    0 00:00:30        3
10.5.5.5        4        65000       6       6       10    0    0 00:00:27        3
10.6.6.6        4        65000       6       6       10    0    0 00:00:26        3
10.12.12.1      4        65100      10      10       10    0    0 00:00:26        2

The output shows four iBGP neighbors in AS65000:

10.3.3.3
10.4.4.4
10.5.5.5
10.6.6.6

R2 also has one eBGP neighbor, 10.12.12.1, toward R1 in AS65100.

That gives R2 five established BGP sessions in total.

The State/PfxRcd column is useful here. Once a Cisco IOS BGP session reaches the Established state, this field displays the number of prefixes received from that neighbor rather than the word Established.

In the output above, every neighbor has a numeric value in State/PfxRcd, confirming that all five BGP sessions on R2 are established. The value also shows how many prefixes R2 is currently receiving from each neighbor.

This confirms that the internal control plane is working as intended: OSPF provides reachability to the loopbacks, and the iBGP sessions successfully form on top of that reachability.

Why a Full Mesh?

R2, R3, R4, R5, and R6 form a full iBGP mesh.

The reason is an important iBGP rule: a route learned from one iBGP neighbor is not normally advertised to another iBGP neighbor. RFC 4271 defines this behavior, and Cisco documents the same rule for its implementations.

Consider a simple example from our topology.

R2 can learn a prefix from R1 through eBGP and advertise that route to R3 through iBGP. Once R3 learns the route from R2, however, R3 does not advertise that same iBGP-learned route onward to R4.

Without another mechanism, R4 would need its own iBGP session with R2 to learn that path.

That is why our five internal BGP routers peer directly with one another. With n iBGP speakers, a traditional full mesh requires:

n(n - 1)
--------
   2

For our five routers:

5(5 - 1) / 2 = 10 iBGP sessions

This works well for a small lab, but the number of sessions grows quickly as more routers are added. Larger BGP deployments commonly use route reflectors to avoid requiring every router to peer directly with every other router. Cisco documents route reflection specifically as a way to remove the full-mesh requirement.

For this lab, we’ll keep the full mesh. It gives every internal BGP router direct visibility to the other BGP speakers while keeping route-reflector behavior out of the picture, allowing us to focus on best-path selection.

Verify the eBGP Edges

With the iBGP full mesh established, we can verify the external BGP sessions that connect AS65000 to the rest of the topology.

At the top of the lab, R1 in AS65100 peers with both R2 and R4:

r1#show ip bgp summary 

Neighbor        V           AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
10.12.12.2      4        65000      41      41       10    0    0 00:28:57        7
10.14.14.2      4        65000      40      41       10    0    0 00:28:56        7

Both sessions are established. Because these are eBGP relationships, R1 uses the directly connected interface addresses on the R1–R2 and R1–R4 links rather than loopback addresses.

At the bottom of the topology, R7 in AS65200 peers with R6 and R5:

r7#show ip bgp summary 

Neighbor        V           AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
10.57.57.1      4        65000      46      47       10    0    0 00:35:27        7
10.67.67.1      4        65000      47      47       10    0    0 00:35:27        7

These sessions are also established, completing the four eBGP relationships at the edges of the topology.

At this point, the baseline control plane is fully verified:

  • OSPF provides internal reachability inside AS65000.
  • iBGP distributes BGP information between the internal routers.
  • eBGP connects AS65000 to AS65100 and AS65200.

We now have a stable starting point for the rest of the lab.

The next question is no longer whether BGP is working.

It is:

When multiple valid paths exist to the same destination, how does BGP decide which one becomes best?

Before Best Path: What Makes a Path Valid?

Before BGP can decide which path is best, the path first has to be eligible to participate in the decision.

Cisco describes the process as comparing valid paths to the same destination. A path that is not valid never makes it far enough to compete on Weight, Local Preference, AS_PATH, or any of the later decision criteria.

One of the most important requirements is that the BGP next hop must be reachable.

For example, suppose R3 receives a route to: 192.0.2.0/24

with a BGP next hop of: 10.2.2.2

R3 must have a route that resolves 10.2.2.2 before that path can be used.

This is where the underlying IGP becomes important again. In our topology, OSPF provides reachability to the loopbacks used as BGP next hops.

A useful way to think about the process is:

Route received
     ↓
Is the path valid?
     ↓
Candidate for best-path selection
     ↓
BGP compares the candidates
     ↓
One path becomes best

RFC 4271 makes the same general distinction: a route can be considered ineligible before later route selection occurs. The RFC also notes that its decision process is conceptual, which is why the exact best-path sequence we work through in this lab should be understood as Cisco’s implementation of BGP path selection.

This distinction is useful in troubleshooting. If a path is missing from consideration, immediately changing Local Preference or AS_PATH may accomplish nothing. First determine whether the route is actually a valid candidate.

For this lab, we’ll establish valid competing paths first and then deliberately break one tie at a time.

Give BGP Something to Choose Between

So far, we’ve verified that the control plane works, but we haven’t yet given BGP an interesting decision to make.

Best-path selection occurs when BGP has multiple valid paths to the same destination.

For the rest of the lab, we’ll use a single test prefix: 192.0.2.0/24

Keeping the destination constant will let us change one decision criterion at a time and observe exactly why the selected path changes.

The workflow for each experiment will be: Predict → Inspect → Change One Thing → Verify → Explain

Before manipulating anything, however, we need to build the initial competing paths and see what BGP chooses on its own.

Originate the Test Prefix

R1 already has 192.0.2.0/24 as a connected route:

r1#show ip route

C        192.0.2.0/24 is directly connected, Ethernet0/1
L        192.0.2.1/32 is directly connected, Ethernet0/1

Its BGP configuration also contains a matching network statement:

r1#show running-config | section router bgp

router bgp 65100
...
 address-family ipv4
  network 192.0.2.0

Because the exact /24 exists in R1’s routing table, BGP can originate it into AS65100.

We can verify that directly:

r1#show ip bgp 192.0.2.0

BGP routing table entry for 192.0.2.0/24, version 6
Paths: (1 available, best #1, table default)
  Advertised to update-groups:
     1         
  Refresh Epoch 1
  Local
    0.0.0.0 from 0.0.0.0 (10.1.1.1)
      Origin IGP, metric 0, localpref 100, weight 32768, valid, sourced, local, best
      rx pathid: 0, tx pathid: 0x0
      Updated on Sep 21 2026 14:38:22 UTC

There are several useful details in this output.

0.0.0.0 tells us the route was originated locally on R1. Cisco also assigns a default Weight of 32768 to locally originated routes, compared with the default Weight of 0 for routes learned from another BGP neighbor.

The route also has an Origin of IGP. In this context, that does not mean OSPF originated the route. The i Origin code indicates that the prefix entered BGP using a network statement.

Finally, the path is marked: valid, sourced, local, best

So R1 has a single valid path to 192.0.2.0/24, and that locally originated path is its BGP best path.

R1 advertises the 192.0.2.0/24 prefix to both of its AS65000 neighbors: R2 and R4.

r1#show ip bgp neighbors 10.12.12.2 advertised-routes 

     Network          Next Hop            Metric LocPrf Weight Path
 *>   192.0.2.0        0.0.0.0                  0         32768 i
 
r1#show ip bgp neighbors 10.14.14.2 advertised-routes    

     Network          Next Hop            Metric LocPrf Weight Path
 *>   192.0.2.0        0.0.0.0                  0         32768 i

The important point here is that R1 is advertising the same prefix through both eBGP sessions.

One attribute from the output above will not follow the route to the neighbors: Weight. Weight is local to the Cisco router and is not carried in BGP updates. When we inspect the route on R2 and R4, their locally assigned Weight should therefore be 0.

Next, check the route on both edge routers:

r2#show ip bgp 192.0.2.0

BGP routing table entry for 192.0.2.0/24, version 6
Paths: (2 available, best #2, table default)
  Advertised to update-groups:
     1         
  Refresh Epoch 1
  65100
    10.4.4.4 (metric 21) from 10.4.4.4 (10.4.4.4)
      Origin IGP, metric 0, localpref 100, valid, internal
      rx pathid: 0, tx pathid: 0
      Updated on Sep 21 2026 14:38:35 UTC
  Refresh Epoch 1
  65100
    10.12.12.1 from 10.12.12.1 (10.1.1.1)
      Origin IGP, metric 0, localpref 100, valid, external, best
      rx pathid: 0, tx pathid: 0x0
      Updated on Sep 21 2026 14:38:35 UTC
      
r2#show ip route 192.0.2.0
Routing entry for 192.0.2.0/24
  Known via "bgp 65000", distance 20, metric 0
  Tag 65100, type external
  Last update from 10.12.12.1 21:06:35 ago
  Routing Descriptor Blocks:
  * 10.12.12.1, from 10.12.12.1, 21:06:35 ago
      opaque_ptr 0x7EF6F4E21008 
      Route metric is 0, traffic share count is 1
      AS Hops 1
      Route tag 65100
      MPLS label: none
r4#show ip bgp 192.0.2.0
                  
BGP routing table entry for 192.0.2.0/24, version 6
Paths: (2 available, best #2, table default)
  Advertised to update-groups:
     1         
  Refresh Epoch 1
  65100
    10.2.2.2 (metric 21) from 10.2.2.2 (10.2.2.2)
      Origin IGP, metric 0, localpref 100, valid, internal
      rx pathid: 0, tx pathid: 0
      Updated on Sep 21 2026 14:38:35 UTC
  Refresh Epoch 1
  65100
    10.14.14.1 from 10.14.14.1 (10.1.1.1)
      Origin IGP, metric 0, localpref 100, valid, external, best
      rx pathid: 0, tx pathid: 0x0
      Updated on Sep 21 2026 14:38:35 UTC
      
r4#show ip route 192.0.2.0

Routing entry for 192.0.2.0/24
  Known via "bgp 65000", distance 20, metric 0
  Tag 65100, type external
  Last update from 10.14.14.1 21:07:08 ago
  Routing Descriptor Blocks:
  * 10.14.14.1, from 10.14.14.1, 21:07:08 ago
      opaque_ptr 0x759679D89348 
      Route metric is 0, traffic share count is 1
      AS Hops 1
      Route tag 65100
      MPLS label: none

Follow the Prefix into AS65000

R1 advertises 192.0.2.0/24 to both R2 and R4. Each edge router learns one path directly from R1 through eBGP and another path through iBGP from the opposite edge router.

On R2:

r2#show ip bgp 192.0.2.0

BGP routing table entry for 192.0.2.0/24, version 6
Paths: (2 available, best #2, table default)
  Advertised to update-groups:
     1         
  Refresh Epoch 1
  65100
    10.4.4.4 (metric 21) from 10.4.4.4 (10.4.4.4)
      Origin IGP, metric 0, localpref 100, valid, internal
      rx pathid: 0, tx pathid: 0
      Updated on Sep 21 2026 14:38:35 UTC
  Refresh Epoch 1
  65100
    10.12.12.1 from 10.12.12.1 (10.1.1.1)
      Origin IGP, metric 0, localpref 100, valid, external, best
      rx pathid: 0, tx pathid: 0x0
      Updated on Sep 21 2026 14:38:35 UTC

R2 has two valid paths to the same prefix:

  • an iBGP path learned from R4
  • an eBGP path learned directly from R1

The important part is that several earlier decision criteria are tied.

Both paths have:

Local Preference: 100
AS_PATH:          65100
Origin:           IGP
MED:              0

The first meaningful difference is how the routes were learned.

The path through 10.12.12.1 is marked: external, best

while the path through R4 is marked: internal

When the earlier criteria remain tied, Cisco prefers an eBGP-learned path over an iBGP-learned path.

The (metric 21) shown beside the iBGP next hop 10.4.4.4 is the IGP cost R2 uses to reach that BGP next hop. That value does not decide this comparison because eBGP versus iBGP is evaluated earlier in the best-path process.

The routing table confirms which path actually won:

r2#show ip route 192.0.2.0
   
Routing entry for 192.0.2.0/24
  Known via "bgp 65000", distance 20, metric 0
  Tag 65100, type external
  Last update from 10.12.12.1 21:26:12 ago
  Routing Descriptor Blocks:
  * 10.12.12.1, from 10.12.12.1, 21:26:12 ago
      opaque_ptr 0x7EF6F4E21008 
      Route metric is 0, traffic share count is 1
      AS Hops 1
      Route tag 65100
      MPLS label: none

R2 installs the directly learned eBGP route through R1.

R4 sees the same behavior from the opposite side:

r4#show ip bgp 192.0.2.0

BGP routing table entry for 192.0.2.0/24, version 6
Paths: (2 available, best #2, table default)
  Advertised to update-groups:
     1         
  Refresh Epoch 1
  65100
    10.2.2.2 (metric 21) from 10.2.2.2 (10.2.2.2)
      Origin IGP, metric 0, localpref 100, valid, internal
      rx pathid: 0, tx pathid: 0
      Updated on Sep 21 2026 14:38:35 UTC
  Refresh Epoch 1
  65100
    10.14.14.1 from 10.14.14.1 (10.1.1.1)
      Origin IGP, metric 0, localpref 100, valid, external, best
      rx pathid: 0, tx pathid: 0x0
      Updated on Sep 21 2026 14:38:35 UTC

R4 also prefers its directly learned eBGP path from R1 over the copy learned through iBGP from R2.

BGP Best Path vs. Administrative Distance

The distance 20 shown in the routing table is the administrative distance of the selected eBGP route.

That is separate from the reason BGP chose the path.

BGP first selected the eBGP path through its own best-path process. The selected route was then installed in the IP routing table with an administrative distance of 20.

This distinction matters because eBGP does not win over iBGP because its administrative distance is lower. The eBGP-versus-iBGP preference is part of BGP’s own best-path decision process.

We have now verified the test prefix from origination on R1 through propagation into AS65000 and seen BGP make a real best-path decision on R2 and R4.

From this point forward, we’ll work through Cisco’s best-path process in order. For each criterion, we’ll start with the current baseline, make one controlled change, observe how the selected path changes, and then reset the lab before moving to the next criterion.

The key idea is simple: BGP stops as soon as one criterion produces a winner. To understand why a path was selected, we need to work from the top of the decision process downward and find the first value that differs.

We’ll begin with the first Cisco-specific decision criterion: Weight.

Weight

Weight is a Cisco-specific BGP value used to influence path selection on a single router. Higher Weight is preferred. The value is local to the router and is not propagated in BGP updates. Routes learned from BGP peers have a default Weight of 0, while locally originated routes use 32768.

Because Weight is evaluated before Local Preference and the later best-path criteria, a higher Weight can make a path win immediately on that router.

Question: Can we make R3 prefer one path to 192.0.2.0/24 using Weight without affecting path selection on the rest of AS65000?

Baseline: R3 currently has two valid iBGP paths to the prefix:

r3#show ip bgp 192.0.2.0

BGP routing table entry for 192.0.2.0/24, version 8
Paths: (2 available, best #1, table default)
  Not advertised to any peer
  Refresh Epoch 1
  65100
    10.2.2.2 (metric 11) from 10.2.2.2 (10.2.2.2)
      Origin IGP, metric 0, localpref 100, valid, internal, best
      rx pathid: 0, tx pathid: 0x0
      Updated on Sep 21 2026 14:38:35 UTC
  Refresh Epoch 1
  65100
    10.4.4.4 (metric 11) from 10.4.4.4 (10.4.4.4)
      Origin IGP, metric 0, localpref 100, valid, internal
      rx pathid: 0, tx pathid: 0
      Updated on Sep 21 2026 14:38:35 UTC

The two paths are tied on the major criteria visible here:

                           Via R2        Via R4
BGP next hop             10.2.2.2     10.4.4.4
Weight                         0             0
Local Preference             100           100
AS_PATH                    65100         65100
Origin                       IGP           IGP
MED                            0             0
IGP cost to next hop          11            11

R3 currently selects the path through R2.

Cisco IOS can also tell us why the other path lost:

r3#show ip bgp 192.0.2.0 best-path-reason
  ...
  65100
    10.2.2.2 (metric 11) from 10.2.2.2 (10.2.2.2)
      ...
      Best Path Evaluation: Overall best path
  ...   
  65100
    10.4.4.4 (metric 11) from 10.4.4.4 (10.4.4.4)
      ...    
      Best Path Evaluation: Higher router ID

The path through R4 loses because its advertising BGP router has the higher router ID. When the earlier criteria remain tied, Cisco eventually prefers the path learned from the router with the lower BGP router ID. In this case, R2 uses 10.2.2.2 and R4 uses 10.4.4.4, so the path through R2 wins.

That tells us something important before we change anything: the baseline decision currently falls very far down the best-path process.

Predict: If we assign a higher Weight to the path received from R4, Cisco should stop at the first best-path criterion and select that path instead. Because Weight is local to R3, the change should not alter path selection on the other routers.

Change:

ip prefix-list WEIGHT-TEST permit 192.0.2.0/24

route-map SET-WEIGHT permit 10
 match ip address prefix-list WEIGHT-TEST
 set weight 500

route-map SET-WEIGHT permit 20

router bgp 65000
 address-family ipv4
  neighbor 10.4.4.4 route-map SET-WEIGHT in

Reprocess the routes received from R4:

R3# clear ip bgp 10.4.4.4 soft in

Verify:

R3# show ip bgp 192.0.2.0

BGP routing table entry for 192.0.2.0/24, version 15
Paths: (2 available, best #2, table default)

  65100
    10.2.2.2 (metric 11) from 10.2.2.2 (10.2.2.2)
      Origin IGP, metric 0, localpref 100, valid, internal

  65100
    10.4.4.4 (metric 11) from 10.4.4.4 (10.4.4.4)
      Origin IGP, metric 0, localpref 100, weight 500, valid, internal, best

Cisco now identifies Weight as the deciding factor:

R3# show ip bgp 192.0.2.0 best-path-reason

...
10.2.2.2 (metric 11) from 10.2.2.2 (10.2.2.2)
  ...
  Best Path Evaluation: Lower weight

10.4.4.4 (metric 11) from 10.4.4.4 (10.4.4.4)
  ...
  Best Path Evaluation: Overall best path

The routing table follows the new BGP best path:

R3# show ip route 192.0.2.0

Routing entry for 192.0.2.0/24
  Known via "bgp 65000", distance 200, metric 0
  Tag 65100, type internal
  Last update from 10.4.4.4

Data-plane verification: We can also verify that traffic is now following the newly selected path.

Because R1 already has reachability back to R3’s loopback through BGP, we’ll source the traceroute from 10.3.3.3:

IOS
R3# traceroute 192.0.2.1 source 10.3.3.3
Type escape sequence to abort.
Tracing the route to r1 (192.0.2.1)
VRF info: (vrf in name/id, vrf out name/id)
  1 r4 (10.34.34.2) 1 msec 1 msec 1 msec
  2 r1 (10.14.14.1) 1 msec *  2 msec

The forwarding path now follows: R3 → R4 → R1

The only attribute we changed was Weight. The path through R4 now wins before BGP ever reaches the later tie-breakers that previously selected R2.

Because Weight is local to R3 and is not advertised to other BGP routers, this change affects only R3’s own path selection.

Sourcing the traceroute from the loopback is important here. Without an explicit source, IOS may use the outgoing interface address, and R1 may not have a return route to that internal transit subnet.

Reset:

IOS
router bgp 65000
 address-family ipv4
  no neighbor 10.4.4.4 route-map SET-WEIGHT in
 exit-address-family

no route-map SET-WEIGHT
no ip prefix-list WEIGHT-TEST
IOS
clear ip bgp 10.4.4.4 soft in

After the reset, R3 returns to the original baseline and again selects the path through R2.

Local Preference

Local Preference is a well-known BGP attribute used to influence the preferred exit point from an autonomous system. Higher Local Preference is preferred. The default value on Cisco IOS is 100, and the attribute is propagated between iBGP peers inside the AS rather than advertised to external BGP neighbors. Cisco evaluates Local Preference immediately after Weight in the best-path process.

Question: Can we make AS65000 prefer R4 as the exit toward 192.0.2.0/24, even on routers that already have another valid path?

Baseline: R2 and R4 each prefer their directly learned eBGP path from R1, while R3 receives two iBGP paths and currently prefers R2.

We changed the route as it entered AS65000 through R4 by setting Local Preference to 200:

IOS
ip prefix-list LOCAL-PREF-TEST permit 192.0.2.0/24

route-map SET-LOCAL-PREF permit 10
 match ip address prefix-list LOCAL-PREF-TEST
 set local-preference 200

route-map SET-LOCAL-PREF permit 20

router bgp 65000
 address-family ipv4
  neighbor 10.14.14.1 route-map SET-LOCAL-PREF in

Then reprocessed the routes received from R1:

IOS
R4# clear ip bgp 10.14.14.1 soft in

R4 now assigns Local Preference 200 to the prefix:

IOS
R4# show ip bgp 192.0.2.0

BGP routing table entry for 192.0.2.0/24, version 11
Paths: (1 available, best #1, table default)

  65100
    10.14.14.1 from 10.14.14.1 (10.1.1.1)
      Origin IGP, metric 0, localpref 200, valid, external, best

R3 receives that higher Local Preference through iBGP and now prefers the path through R4:

IOS
R3# show ip bgp 192.0.2.0

BGP routing table entry for 192.0.2.0/24, version 13
Paths: (1 available, best #1, table default)

  65100
    10.4.4.4 (metric 11) from 10.4.4.4 (10.4.4.4)
      Origin IGP, metric 0, localpref 200, valid, internal, best

The more interesting result appears on R2.

R2 still has its directly learned eBGP path from R1 with Local Preference 100, but it also receives the R4 path through iBGP with Local Preference 200:

IOS
R2# show ip bgp 192.0.2.0 best-path-reason

BGP routing table entry for 192.0.2.0/24, version 11
Paths: (2 available, best #1, table default)

  65100
    10.4.4.4 (metric 21) from 10.4.4.4 (10.4.4.4)
      Origin IGP, metric 0, localpref 200, valid, internal, best
      Best Path Evaluation: Overall best path

  65100
    10.12.12.1 from 10.12.12.1 (10.1.1.1)
      Origin IGP, metric 0, localpref 100, valid, external
      Best Path Evaluation: Lower local preference

R2 therefore prefers the iBGP path through R4 even though it has a direct eBGP path to R1.

This demonstrates the ordering of the best-path process: Local Preference is evaluated before the eBGP-versus-iBGP criterion. Once 200 beats 100, BGP has already found a winner and does not need to continue farther down the decision process.

The routing table reflects that decision:

IOS
R2# show ip route 192.0.2.0

Routing entry for 192.0.2.0/24
  Known via "bgp 65000", distance 200, metric 0
  Tag 65100, type internal
  Last update from 10.4.4.4

We can also verify the forwarding path:

IOS
R2# traceroute 192.0.2.1 source 10.2.2.2
Type escape sequence to abort.
Tracing the route to r1 (192.0.2.1)

  1 r3 (10.23.23.2) 1 msec 0 msec 1 msec
  2 r4 (10.34.34.2) 0 msec 0 msec 0 msec
  3 r1 (10.14.14.1) 0 msec * 0 msec

Traffic now follows: R2 → R3 → R4 → R1, instead of using R2’s direct eBGP connection to R1.

There is also an important control-plane side effect. After R2 selects the Local Preference 200 path learned from R4 through iBGP, it can no longer advertise that path onward to its other iBGP peers under normal iBGP rules. Its original eBGP path is no longer the best path either, so R2 stops advertising that path as well.

That is why R3 and R4 temporarily show only one available path to 192.0.2.0/24 during this experiment.

Reset:

IOS
router bgp 65000
 address-family ipv4
  no neighbor 10.14.14.1 route-map SET-LOCAL-PREF in
 exit-address-family

no route-map SET-LOCAL-PREF
no ip prefix-list LOCAL-PREF-TEST
IOS
clear ip bgp 10.14.14.1 soft in

After the reset, Local Preference returns to 100, R2 and R4 again prefer their directly learned eBGP paths, and R3 once again sees both iBGP paths.

Locally Originated

After Weight and Local Preference, Cisco next prefers a route that was originated locally on the router. A route can be locally originated through mechanisms such as a BGP network statement, redistribution, or aggregation.

For this test, R4 will compare:

IOS
                           Local R4       Via R1
Weight                        32768        32768
Local Preference                100          100
Locally originated              Yes           No
AS_PATH                       empty        65100

To make the comparison valid, we deliberately set the R1-learned path to the same Weight as the local path. Otherwise, the default local Weight of 32768 would decide the contest before BGP reached the locally originated criterion.

Question: If Weight and Local Preference are tied, will R4 prefer a path it originated itself over an otherwise valid path learned from R1?

On R4, we first created an exact route to the test prefix and originated it into BGP:

IOS
configure terminal

ip route 192.0.2.0 255.255.255.0 Null0

router bgp 65000
 address-family ipv4
  network 192.0.2.0 mask 255.255.255.0
 exit-address-family

end

Then we tied the Weight of the R1-learned path:

IOS
configure terminal

ip prefix-list LOCAL-ORIGIN-TEST permit 192.0.2.0/24

route-map TIE-WEIGHT permit 10
 match ip address prefix-list LOCAL-ORIGIN-TEST
 set weight 32768

route-map TIE-WEIGHT permit 20

router bgp 65000
 address-family ipv4
  neighbor 10.14.14.1 route-map TIE-WEIGHT in
 exit-address-family

end

clear ip bgp 10.14.14.1 soft in

R4 now sees two paths:

IOS
R4# show ip bgp 192.0.2.0

BGP routing table entry for 192.0.2.0/24, version 17
Paths: (2 available, best #1, table default)

  Local
    0.0.0.0 from 0.0.0.0 (10.4.4.4)
      Origin IGP, metric 0, localpref 100, weight 32768, valid, sourced, local, best

  65100
    10.14.14.1 from 10.14.14.1 (10.1.1.1)
      Origin IGP, metric 0, localpref 100, weight 32768, valid, external

The Weight and Local Preference values are tied, but the locally originated route wins.

Cisco confirms the deciding factor:

IOS
R4# show ip bgp 192.0.2.0 best-path-reason

...
Local
  0.0.0.0 from 0.0.0.0 (10.4.4.4)
    ...
    Best Path Evaluation: Overall best path

65100
  10.14.14.1 from 10.14.14.1 (10.1.1.1)
    ...
    Best Path Evaluation: Not sourced

The R1-learned path loses because it was not locally sourced.

This is important because the local path also has a shorter AS_PATH, but Cisco never needs to reach AS_PATH length. The decision is already made at the locally originated criterion.

Reset:

IOS
configure terminal

router bgp 65000
 address-family ipv4
  no network 192.0.2.0 mask 255.255.255.0
  no neighbor 10.14.14.1 route-map TIE-WEIGHT in
 exit-address-family

no route-map TIE-WEIGHT
no ip prefix-list LOCAL-ORIGIN-TEST
no ip route 192.0.2.0 255.255.255.0 Null0

end

clear ip bgp 10.14.14.1 soft in

After the reset, R4 again prefers the directly learned eBGP path from R1.

AIGP

AIGP, or Accumulated IGP Metric, is an optional BGP attribute designed to carry an accumulated interior cost across BGP domains. Its purpose is to let BGP consider an end-to-end metric that more closely reflects the underlying IGP cost across multiple routing domains.

When AIGP is enabled and not explicitly ignored, Cisco inserts the AIGP comparison into the best-path process after the locally originated check and before AS_PATH length. Lower accumulated cost is preferred.

AIGP is most relevant in larger provider-style or multi-domain designs where BGP needs visibility into accumulated internal path cost. It is not commonly encountered in simpler enterprise BGP deployments, and enabling it can change decisions that would otherwise have been made by AS_PATH or later criteria.

We will not configure or test AIGP in this lab. Our topology is focused on the more commonly encountered BGP policy controls and tie-breakers, so we will leave AIGP absent and continue to the next active criterion: AS_PATH.

AS_PATH

AS_PATH records the autonomous systems a route has traversed and is one of BGP’s primary loop-prevention mechanisms. When the earlier best-path criteria remain tied, Cisco prefers the path with the shorter AS_PATH.

AS_PATH can also be manipulated with AS_PATH prepending. Prepending adds additional copies of an AS number to an advertisement, making that path appear longer and therefore less attractive to remote BGP routers when the earlier criteria are equal. This is commonly used to influence inbound traffic toward an AS.

Question: Can we make the R1→R2 path less attractive by lengthening its AS_PATH and cause AS65000 to prefer R4 instead?

Baseline: R1 normally advertises 192.0.2.0/24 toward both R2 and R4 with the same AS_PATH: 65100

R3 therefore receives two equal-length paths and, with the earlier criteria tied, eventually prefers R2 based on a later tie-breaker.

For this experiment, we prepend two additional copies of AS65100 only on the advertisement from R1 toward R2.

Apply on R1:

IOS
configure terminal

ip prefix-list ASPATH-TEST permit 192.0.2.0/24

route-map PREPEND-ASPATH permit 10
 match ip address prefix-list ASPATH-TEST
 set as-path prepend 65100 65100

route-map PREPEND-ASPATH permit 20

router bgp 65100
 address-family ipv4
  neighbor 10.12.12.2 route-map PREPEND-ASPATH out
 exit-address-family

end

clear ip bgp 10.12.12.2 soft out

R1 now advertises different AS_PATH lengths toward the two AS65000 edge routers:

IOS
R1# show ip bgp neighbors 10.12.12.2 advertised-routes 192.0.2.0/24

Advertised Attributes
  AS-Path: 65100 65100 65100

Toward R4, the path remains unchanged:

IOS
R1# show ip bgp neighbors 10.14.14.2 advertised-routes 192.0.2.0/24

Advertised Attributes
  AS-Path: 65100

The two advertisements are now:

Toward R2: 65100 65100 65100
Toward R4: 65100

On R2, both paths are still available:

IOS
R2# show ip bgp 192.0.2.0 best-path-reason

BGP routing table entry for 192.0.2.0/24, version 18
Paths: (2 available, best #1, table default)

  65100
    10.4.4.4 (metric 21) from 10.4.4.4 (10.4.4.4)
      Origin IGP, metric 0, localpref 100, valid, internal, best
      Best Path Evaluation: Overall best path

  65100 65100 65100
    10.12.12.1 from 10.12.12.1 (10.1.1.1)
      Origin IGP, metric 0, localpref 100, valid, external
      Best Path Evaluation: Longer AS path

The result is particularly useful because R2 still has a direct eBGP connection to R1, but that path loses to the iBGP-learned route through R4.

The shorter AS_PATH wins before BGP ever reaches the eBGP-versus-iBGP criterion:

Via R4:      65100
Direct R1:   65100 65100 65100

R2 therefore installs the path through R4.

The forwarding path confirms the change:

IOS
R2# traceroute 192.0.2.1 source 10.2.2.2
Type escape sequence to abort.
Tracing the route to r1 (192.0.2.1)

  1 r3 (10.23.23.2) 1 msec 0 msec 1 msec
  2 r4 (10.34.34.2) 1 msec 0 msec 1 msec
  3 r1 (10.14.14.1) 0 msec * 1 msec

Traffic now follows: R2 → R3 → R4 → R1, even though R2 has a direct link to R1.

This highlights an important distinction: AS_PATH length refers to the number of autonomous systems represented in the path, not physical hop count, latency, or geographic distance. A physically longer forwarding path can still become the BGP best path if its AS_PATH is shorter.

There is also a control-plane side effect. Once R2 prefers the shorter path learned from R4 through iBGP, its direct R1 path is no longer best. R2 cannot re-advertise the winning iBGP-learned route to its other iBGP peers, so R3 temporarily sees only the path advertised by R4.

Reset on R1:

IOS
configure terminal

router bgp 65100
 address-family ipv4
  no neighbor 10.12.12.2 route-map PREPEND-ASPATH out
 exit-address-family

no route-map PREPEND-ASPATH
no ip prefix-list ASPATH-TEST

end

clear ip bgp 10.12.12.2 soft out

After the reset, R2 again receives the direct R1 advertisement with AS_PATH 65100 and returns to its original eBGP best path.

Origin

The BGP Origin attribute describes how a prefix was introduced into BGP at the originating AS. It is a mandatory BGP path attribute and can have one of three values

i  = IGP
e  = EGP
?  = Incomplete

The preference order is:

IGP (i) → EGP (e) → Incomplete (?)

With IGP preferred over EGP, and EGP preferred over Incomplete. Cisco evaluates Origin after AS_PATH and before MED.

One important distinction is that an Origin of IGP does not mean the route was learned through OSPF, IS-IS, or another interior gateway protocol. In BGP, the Origin code describes how the prefix entered BGP. A route introduced with a BGP network statement normally receives an Origin of IGP, while a route redistributed into BGP normally receives an Origin of Incomplete. The EGP value refers to the historical Exterior Gateway Protocol and is rarely encountered in modern networks.

Unlike Local Preference or AS_PATH prepending, Origin is not typically the first attribute engineers reach for when implementing traffic policy. More often, differences in Origin appear because two routes were injected into BGP in different ways. Those differences can still affect best-path selection when the earlier criteria remain tied.

Question: If two paths have equal Weight, Local Preference, and AS_PATH length, can a difference in Origin cause R2 to prefer an iBGP path over its direct eBGP path?

Our baseline advertisements from R1 both use Origin IGP because 192.0.2.0/24 is originated with a BGP network statement.

For this experiment, we’ll leave the advertisement toward R4 unchanged and modify only the advertisement toward R2:

R1 → R2
AS_PATH: 65100
Origin:   Incomplete (?)

R1 → R4
AS_PATH: 65100
Origin:   IGP (i)

Apply on R1:

IOS
configure terminal

ip prefix-list ORIGIN-TEST permit 192.0.2.0/24

route-map SET-ORIGIN-INCOMPLETE permit 10
 match ip address prefix-list ORIGIN-TEST
 set origin incomplete

route-map SET-ORIGIN-INCOMPLETE permit 20

router bgp 65100
 address-family ipv4
  neighbor 10.12.12.2 route-map SET-ORIGIN-INCOMPLETE out
 exit-address-family

end

clear ip bgp 10.12.12.2 soft out

R1 confirms that the same prefix is now being advertised with different Origin values:

IOS
R1# show ip bgp neighbors 10.12.12.2 advertised-routes 192.0.2.0/24

Advertised Attributes
  Local Preference: 0
  Metric: 0
  Origin: incomplete
  AS-Path: 65100
  Nexthop: 10.12.12.1

Toward R4, the original Origin remains unchanged:

IOS
R1# show ip bgp neighbors 10.14.14.2 advertised-routes 192.0.2.0/24

Advertised Attributes
  Local Preference: 0
  Metric: 0
  Origin: IGP
  AS-Path: 65100
  Nexthop: 10.14.14.1

R2 now has two paths with the same AS_PATH length, but different Origin values:

IOS
R2# show ip bgp 192.0.2.0

BGP routing table entry for 192.0.2.0/24, version 20
Paths: (2 available, best #1, table default)

  65100
    10.4.4.4 (metric 21) from 10.4.4.4 (10.4.4.4)
      Origin IGP, metric 0, localpref 100, valid, internal, best

  65100
    10.12.12.1 from 10.12.12.1 (10.1.1.1)
      Origin incomplete, metric 0, localpref 100, valid, external

Cisco identifies Origin as the deciding factor:

IOS
R2# show ip bgp 192.0.2.0 best-path-reason

...
65100
  10.4.4.4 (metric 21) from 10.4.4.4 (10.4.4.4)
    Origin IGP, metric 0, localpref 100, valid, internal, best
    Best Path Evaluation: Overall best path

65100
  10.12.12.1 from 10.12.12.1 (10.1.1.1)
    Origin incomplete, metric 0, localpref 100, valid, external
    Best Path Evaluation: Less favorable origin

R2 therefore prefers the iBGP path through R4 even though it still has a direct eBGP connection to R1.

This again demonstrates the importance of best-path ordering. Origin is evaluated before the eBGP-versus-iBGP criterion, so the better Origin code wins before Cisco ever considers how the two routes were learned.

The routing table reflects that decision:

IOS
R2# show ip route 192.0.2.0

Routing entry for 192.0.2.0/24
  Known via "bgp 65000", distance 200, metric 0
  Tag 65100, type internal
  Last update from 10.4.4.4

And the data plane follows the new best path:

IOS
R2# traceroute 192.0.2.1 source 10.2.2.2

  1 r3 (10.23.23.2) 0 msec 0 msec 0 msec
  2 r4 (10.34.34.2) 0 msec 0 msec 1 msec
  3 r1 (10.14.14.1) 0 msec * 1 msec

Traffic now follows: R2 → R3 → R4 → R1, rather than using the direct R2→R1 link.

The practical takeaway is not that Origin should become a primary traffic-engineering tool. Instead, engineers should understand that different route-origination methods can create different Origin attributes, and those differences can unexpectedly influence best-path selection when stronger policy attributes are equal.

Reset on R1:

IOS
configure terminal

router bgp 65100
 address-family ipv4
  no neighbor 10.12.12.2 route-map SET-ORIGIN-INCOMPLETE out
 exit-address-family

no route-map SET-ORIGIN-INCOMPLETE
no ip prefix-list ORIGIN-TEST

end

clear ip bgp 10.12.12.2 soft out

After the reset, both advertisements again use Origin IGP, and R2 returns to its directly learned eBGP path.

MED

MED, or Multi-Exit Discriminator, is an optional, non-transitive BGP attribute used to signal a preferred entry point into an autonomous system when multiple links exist between neighboring ASes. Lower MED is preferred.

Unlike Local Preference, which an AS uses internally to choose its preferred exit, MED is typically advertised to a neighboring AS to influence which entry point that neighbor uses when sending traffic toward you.

A useful way to think about the distinction is:

Local Preference:
Which exit should my AS use?

MED:
Which entrance would I prefer my neighboring AS to use?

By default, Cisco compares MED only when the competing paths come from the same neighboring AS. If the neighboring AS differs, MED is normally skipped unless bgp always-compare-med is configured.

Our topology is well suited for MED because both candidate paths originate from AS65100:

        R1
      AS65100
      /     \
     /       \
   R2         R4
      AS65000

Question: Can AS65100 signal that AS65000 should prefer R4 rather than R2 as the entry point toward 192.0.2.0/24?

At baseline, R1 advertises the prefix through both eBGP sessions with MED 0.

For this experiment, we make the R2-facing advertisement less attractive:

R1 → R2
MED 200

R1 → R4
MED 0

Apply on R1:

IOS
configure terminal

ip prefix-list MED-TEST permit 192.0.2.0/24

route-map SET-MED-200 permit 10
 match ip address prefix-list MED-TEST
 set metric 200

route-map SET-MED-200 permit 20

router bgp 65100
 address-family ipv4
  neighbor 10.12.12.2 route-map SET-MED-200 out
 exit-address-family

end

clear ip bgp 10.12.12.2 soft out

R1 now advertises different MED values toward the two AS65000 edge routers:

IOS
R1# show ip bgp neighbors 10.12.12.2 advertised-routes 192.0.2.0/24

Advertised Attributes
  Local Preference: 0
  Metric: 200
  Origin: IGP
  AS-Path: 65100
  Nexthop: 10.12.12.1

Toward R4:

IOS
R1# show ip bgp neighbors 10.14.14.2 advertised-routes 192.0.2.0/24

Advertised Attributes
  Local Preference: 0
  Metric: 0
  Origin: IGP
  AS-Path: 65100
  Nexthop: 10.14.14.1

R2 now compares:

Via R4:
AS_PATH 65100
Origin IGP
MED 0
internal

Direct via R1:
AS_PATH 65100
Origin IGP
MED 200
external

Cisco identifies MED as the deciding factor:

IOS
R2# show ip bgp 192.0.2.0 best-path-reason

...
65100
  10.4.4.4 (metric 21) from 10.4.4.4 (10.4.4.4)
    Origin IGP, metric 0, localpref 100, valid, internal, best
    Best Path Evaluation: Overall best path

65100
  10.12.12.1 from 10.12.12.1 (10.1.1.1)
    Origin IGP, metric 200, localpref 100, valid, external
    Best Path Evaluation: Higher MED

R2 therefore prefers the iBGP path through R4 even though it has a direct eBGP connection to R1.

Again, the ordering matters. MED is evaluated before the eBGP-versus-iBGP criterion, so 0 beats 200 before Cisco considers whether the route was learned externally or internally.

The routing table reflects the decision:

IOS
R2# show ip route 192.0.2.0

Routing entry for 192.0.2.0/24
  Known via "bgp 65000", distance 200, metric 0
  Tag 65100, type internal
  Last update from 10.4.4.4

And the data plane follows the new best path:

IOS
R2# traceroute 192.0.2.1 source 10.2.2.2

  1 r3 (10.23.23.2)
  2 r4 (10.34.34.2)
  3 r1 (10.14.14.1)

Traffic now follows: R2 → R3 → R4 → R1, rather than using the direct R2→R1 link.

This is a practical MED use case: AS65100 is not forcing AS65000 to use R4, but it is advertising a preference. AS65000 can still override that preference with stronger policy attributes such as Weight or Local Preference.

MED Comparison Behavior

Two Cisco commands are worth distinguishing because they address different MED behaviors.

bgp always-compare-med allows MED to be compared across paths learned from different neighboring autonomous systems. Without it, MED is normally compared only when the neighboring AS is the same.

bgp deterministic-med, on the other hand, groups paths learned from the same neighboring AS so that MED comparison is deterministic rather than potentially depending on the order in which updates were received. It does not simply mean “compare MED everywhere.”

In our lab, both paths originate from AS65100, so the default MED comparison behavior is sufficient.

There is also a control-plane side effect. Once R2 prefers the path learned from R4 through iBGP, R2 no longer advertises its direct R1 path as best. Because the winning route itself was learned through iBGP, R2 cannot re-advertise it to another iBGP peer under normal iBGP rules. As a result, R3 temporarily sees only the path through R4.

Reset on R1:

IOS
configure terminal

router bgp 65100
 address-family ipv4
  no neighbor 10.12.12.2 route-map SET-MED-200 out
 exit-address-family

no route-map SET-MED-200
no ip prefix-list MED-TEST

end

clear ip bgp 10.12.12.2 soft out

After the reset, both advertisements again carry MED 0, and R2 returns to its directly learned eBGP path.

eBGP over iBGP

When the earlier best-path criteria remain tied, Cisco prefers a route learned through eBGP over one learned through iBGP.

Our baseline on R2 already gives us a clean example. Both paths to 192.0.2.0/24 have the same Weight, Local Preference, AS_PATH, Origin, and MED. The difference is how each route was learned:

Via R4:
iBGP

Direct via R1:
eBGP

Question: If all earlier best-path criteria are tied, will R2 prefer its directly learned eBGP path over the same prefix learned through iBGP?

R2 currently sees both paths:

IOS
R2# show ip bgp 192.0.2.0

BGP routing table entry for 192.0.2.0/24, version 23
Paths: (2 available, best #2, table default)

  65100
    10.4.4.4 (metric 21) from 10.4.4.4 (10.4.4.4)
      Origin IGP, metric 0, localpref 100, valid, internal

  65100
    10.12.12.1 from 10.12.12.1 (10.1.1.1)
      Origin IGP, metric 0, localpref 100, valid, external, best

Cisco identifies the eBGP-versus-iBGP comparison as the deciding factor:

IOS
R2# show ip bgp 192.0.2.0 best-path-reason

...
65100
  10.4.4.4 (metric 21) from 10.4.4.4 (10.4.4.4)
    Origin IGP, metric 0, localpref 100, valid, internal
    Best Path Evaluation: Same MED but path is internal while bestpath is external

65100
  10.12.12.1 from 10.12.12.1 (10.1.1.1)
    Origin IGP, metric 0, localpref 100, valid, external, best
    Best Path Evaluation: Overall best path

The direct path from R1 wins because it was learned through eBGP.

The routing table reflects that decision:

IOS
R2# show ip route 192.0.2.0

Routing entry for 192.0.2.0/24
  Known via "bgp 65000", distance 20, metric 0
  Tag 65100, type external
  Last update from 10.12.12.1

And the data plane follows the direct path:

IOS
R2# traceroute 192.0.2.1 source 10.2.2.2

Tracing the route to r1 (192.0.2.1)

  1 r1 (10.12.12.1) 0 msec * 1 msec

Traffic follows: R2 → R1

This result is useful in context with the previous experiments. Local Preference, AS_PATH, Origin, and MED all caused R2 to prefer an iBGP path over its direct eBGP path because each of those criteria is evaluated earlier.

Here, those earlier values are tied, so BGP finally reaches the eBGP-versus-iBGP comparison and prefers the external path.

BGP Best Path vs. Administrative Distance

It is important not to confuse this behavior with administrative distance.

Cisco IOS uses a default administrative distance of:

eBGP: 20
iBGP: 200

But these values are not why the eBGP path wins inside the BGP table.

BGP first compares its candidate paths using the best-path process and selects the eBGP route because the eBGP-versus-iBGP criterion is reached.

Only after BGP selects its best path does that route compete for installation in the routing table. Administrative distance is used when the router compares routes learned from different routing sources or protocols.

In other words:

BGP best-path selection
        ↓
BGP chooses the eBGP path
        ↓
Selected route is considered for the RIB
        ↓
Administrative distance becomes relevant

So the fact that the installed route shows: distance 20, is a consequence of the selected route being eBGP, not the reason it beat the iBGP candidate.

IGP Metric to the BGP Next Hop

When all earlier best-path criteria remain tied, Cisco compares the IGP metric to the BGP next hop and prefers the path with the lower internal cost.

This is where the relationship between BGP and the IGP underlay becomes especially important. BGP does not simply look at which exit router is physically closer. It resolves each BGP next hop through the routing table and compares the resulting IGP cost.

In production, engineers may adjust IGP metrics to influence how traffic moves through the internal network. Common reasons include preferring higher-capacity or lower-latency links, steering traffic away from constrained or undesirable paths, influencing which edge router becomes the closest BGP exit, or preparing traffic for maintenance.

These changes should be made carefully. Modifying an OSPF or IS-IS metric affects the IGP topology itself, not just BGP, so the change can influence other routes and traffic throughout the network. If the goal is purely BGP policy, attributes such as Local Preference are often a more targeted tool.

Question: If two BGP paths are otherwise equal, can we make R3 choose a different exit simply by changing the OSPF cost to one of the BGP next hops?

At baseline, R3 has two iBGP paths to 192.0.2.0/24:

IOS
R3# show ip bgp 192.0.2.0

BGP routing table entry for 192.0.2.0/24, version 30
Paths: (2 available, best #1, table default)

  65100
    10.2.2.2 (metric 11) from 10.2.2.2 (10.2.2.2)
      Origin IGP, metric 0, localpref 100, valid, internal, best

  65100
    10.4.4.4 (metric 11) from 10.4.4.4 (10.4.4.4)
      Origin IGP, metric 0, localpref 100, valid, internal

The IGP cost to both BGP next hops is currently 11.

We can verify that directly:

IOS
R3# show ip route 10.2.2.2

Routing entry for 10.2.2.2/32
  Known via "ospf 1", distance 110, metric 11, type intra area
  Last update from 10.23.23.1 on Ethernet0/1
IOS
R3# show ip route 10.4.4.4

Routing entry for 10.4.4.4/32
  Known via "ospf 1", distance 110, metric 11, type intra area
  Last update from 10.34.34.2 on Ethernet0/2

Because the IGP costs are equal, BGP continues farther down the best-path process and eventually selects the path through R2 based on a later tie-breaker:

IOS
R3# show ip bgp 192.0.2.0 best-path-reason

...
10.2.2.2 (metric 11) from 10.2.2.2 (10.2.2.2)
  ...
  Best Path Evaluation: Overall best path

10.4.4.4 (metric 11) from 10.4.4.4 (10.4.4.4)
  ...
  Best Path Evaluation: Higher router ID

The data plane follows that decision:

IOS
R3# traceroute 192.0.2.1 source 10.3.3.3

  1 r2 (10.23.23.1) 0 msec 1 msec 0 msec
  2 r1 (10.12.12.1) 0 msec * 1 msec

Traffic currently follows: R3 → R2 → R1

For the experiment, we increase the OSPF cost of R3’s direct link toward R2.

Apply on R3:

IOS
configure terminal

interface Ethernet0/1
 ip ospf cost 50

end

The interface cost changes as expected:

IOS
R3# show ip ospf interface brief

Interface    PID   Area            IP Address/Mask    Cost  State Nbrs F/C
Lo0          1     0.0.0.0         10.3.3.3/32        1     LOOP  0/0
Et0/2        1     0.0.0.0         10.34.34.1/30      10    P2P   1/1
Et0/1        1     0.0.0.0         10.23.23.2/30      50    P2P   1/1

However, OSPF does not simply make the cost to R2’s loopback 51.

Instead, SPF recalculates the topology and finds a cheaper alternate path to 10.2.2.2 through the other side of AS65000:

IOS
R3# show ip route 10.2.2.2

Routing entry for 10.2.2.2/32
  Known via "ospf 1", distance 110, metric 41, type intra area
  Last update from 10.34.34.2 on Ethernet0/2
  Routing Descriptor Blocks:
  * 10.34.34.2, from 10.2.2.2, via Ethernet0/2
      Route metric is 41

The cost to R4 remains unchanged:

IOS
R3# show ip route 10.4.4.4

Routing entry for 10.4.4.4/32
  Known via "ospf 1", distance 110, metric 11, type intra area
  Last update from 10.34.34.2 on Ethernet0/2

R3 now sees:

Via R2:
IGP metric 41

Via R4:
IGP metric 11

That difference is enough for BGP to make its decision:

IOS
R3# show ip bgp 192.0.2.0

BGP routing table entry for 192.0.2.0/24, version 32
Paths: (2 available, best #2, table default)

  65100
    10.2.2.2 (metric 41) from 10.2.2.2 (10.2.2.2)
      Origin IGP, metric 0, localpref 100, valid, internal

  65100
    10.4.4.4 (metric 11) from 10.4.4.4 (10.4.4.4)
      Origin IGP, metric 0, localpref 100, valid, internal, best

Cisco explicitly identifies the IGP metric as the deciding factor:

IOS
R3# show ip bgp 192.0.2.0 best-path-reason

...
10.2.2.2 (metric 41) from 10.2.2.2 (10.2.2.2)
  ...
  Best Path Evaluation: Higher IGP metric

10.4.4.4 (metric 11) from 10.4.4.4 (10.4.4.4)
  ...
  Best Path Evaluation: Overall best path

The routing table now installs the path through R4:

IOS
R3# show ip route 192.0.2.0

Routing entry for 192.0.2.0/24
  Known via "bgp 65000", distance 200, metric 0
  Tag 65100, type internal
  Last update from 10.4.4.4

And the forwarding path changes with it:

IOS
R3# traceroute 192.0.2.1 source 10.3.3.3

  1 r4 (10.34.34.2) 1 msec 1 msec 0 msec
  2 r1 (10.14.14.1) 1 msec * 1 msec

Traffic now follows: R3 → R4 → R1

This is a practical example of hot-potato routing. Once the higher-priority BGP attributes are tied, R3 prefers the exit with the lower internal cost and gets the traffic out of AS65000 through the closest BGP next hop.

The important detail is that BGP does not care about the OSPF cost configured on one particular interface. It compares the resolved IGP metric to the BGP next hop after the IGP has calculated its shortest path.

In this case, raising the direct R3→R2 link cost caused OSPF to find an alternate path to R2 with a total cost of 41, while R4 remained reachable at a cost of 11. That change in the underlay was enough to change BGP’s best path.

Reset on R3:

IOS
configure terminal

interface Ethernet0/1
 no ip ospf cost 50

end

After the reset, OSPF again calculates a cost of 11 to both R2 and R4. With the IGP metric tied, BGP falls through to the later router-ID tie-breaker and again prefers R2.

BGP Multipath

Up to this point, every experiment has focused on a single question: which path wins?

Multipath changes that question slightly.

Cisco can install multiple sufficiently equal BGP paths into the routing table for load sharing, but this does not replace normal BGP best-path selection. BGP still chooses one canonical best path for control-plane purposes. Additional paths can then be installed alongside it for forwarding if they meet the platform’s multipath requirements.

That distinction matters.

BGP still needs one best path because normal route advertisement is based on a selected path, not simply every route present in the RIB. The selected best path also becomes the reference against which additional paths are evaluated for multipath eligibility. Features such as BGP Add-Path can advertise multiple paths, but that is separate from ordinary multipath forwarding.

A useful mental model is:

Best-path selection:
Which single path is BGP's canonical winner?

Multipath eligibility:
Are any additional paths equal enough to also
be installed for forwarding?

So maximum-paths changes what can be installed in the RIB and FIB. It does not mean BGP stops choosing a best path.

Question: If R3 has two equally attractive iBGP paths to 192.0.2.0/24, can we install both for forwarding while still retaining one formal BGP best path?

At baseline, R3 has two iBGP paths that remain equal through the IGP-metric comparison:

IOS
R3# show ip bgp 192.0.2.0

BGP routing table entry for 192.0.2.0/24, version 34
Paths: (2 available, best #1, table default)
  Not advertised to any peer
  Refresh Epoch 3
  65100
    10.2.2.2 (metric 11) from 10.2.2.2 (10.2.2.2)
      Origin IGP, metric 0, localpref 100, valid, internal, best
      rx pathid: 0, tx pathid: 0x0
      Updated on Oct 4 2026 16:53:00 UTC
  Refresh Epoch 5
  65100
    10.4.4.4 (metric 11) from 10.4.4.4 (10.4.4.4)
      Origin IGP, metric 0, localpref 100, valid, internal
      rx pathid: 0, tx pathid: 0
      Updated on Oct 3 2026 18:16:08 UTC

Both paths have the same:

Weight:             0
Local Preference:   100
AS_PATH:            65100
Origin:              IGP
MED:                 0
Path type:           iBGP
IGP metric:          11

Without multipath enabled, BGP continues farther down the decision process and eventually selects the path through R2 because of the lower router ID:

IOS
R3# show ip bgp 192.0.2.0 best-path-reason

BGP routing table entry for 192.0.2.0/24, version 34
Paths: (2 available, best #1, table default)
  Not advertised to any peer
  Refresh Epoch 3
  65100
    10.2.2.2 (metric 11) from 10.2.2.2 (10.2.2.2)
      Origin IGP, metric 0, localpref 100, valid, internal, best
      rx pathid: 0, tx pathid: 0x0
      Updated on Oct 4 2026 16:53:00 UTC
      Best Path Evaluation: Overall best path
  Refresh Epoch 5
  65100
    10.4.4.4 (metric 11) from 10.4.4.4 (10.4.4.4)
      Origin IGP, metric 0, localpref 100, valid, internal
      rx pathid: 0, tx pathid: 0
      Updated on Oct 3 2026 18:16:08 UTC
      Best Path Evaluation: Higher router ID

Only the path through R2 is installed in the routing table:

IOS
R3# show ip route 192.0.2.0

Routing entry for 192.0.2.0/24
  Known via "bgp 65000", distance 200, metric 0
  Tag 65100, type internal
  Last update from 10.2.2.2 00:00:21 ago
  Routing Descriptor Blocks:
  * 10.2.2.2, from 10.2.2.2, 00:00:21 ago
      Route metric is 0, traffic share count is 1
      AS Hops 1
      Route tag 65100
      MPLS label: none

For this experiment, we allow R3 to install up to two eligible iBGP paths.

Apply on R3:

IOS
configure terminal

router bgp 65000
 address-family ipv4
  maximum-paths ibgp 2
 exit-address-family

end

No BGP session reset is required. R3 recalculates the existing paths and identifies both as eligible multipaths:

IOS
R3# show ip bgp 192.0.2.0

BGP routing table entry for 192.0.2.0/24, version 37
Paths: (2 available, best #1, table default)
Multipath: iBGP
  Not advertised to any peer
  Refresh Epoch 3
  65100
    10.2.2.2 (metric 11) from 10.2.2.2 (10.2.2.2)
      Origin IGP, metric 0, localpref 100, valid, internal, multipath, best
      rx pathid: 0, tx pathid: 0x0
      Updated on Oct 4 2026 16:53:00 UTC
  Refresh Epoch 5
  65100
    10.4.4.4 (metric 11) from 10.4.4.4 (10.4.4.4)
      Origin IGP, metric 0, localpref 100, valid, internal, multipath(oldest)
      rx pathid: 0, tx pathid: 0
      Updated on Oct 3 2026 18:16:08 UTC

Both paths are now marked as multipaths, but only the path through R2 is marked best.

R2 path:
multipath, best

R4 path:
multipath(oldest)

This is the key distinction.

R2 remains the canonical BGP best path, while R4 is an additional path that is equal enough to qualify for multipath forwarding.

The best-path decision itself has not changed:

IOS
R3# show ip bgp 192.0.2.0 best-path-reason

BGP routing table entry for 192.0.2.0/24, version 37
Paths: (2 available, best #1, table default)
Multipath: iBGP
  Not advertised to any peer
  Refresh Epoch 3
  65100
    10.2.2.2 (metric 11) from 10.2.2.2 (10.2.2.2)
      Origin IGP, metric 0, localpref 100, valid, internal, multipath, best
      rx pathid: 0, tx pathid: 0x0
      Updated on Oct 4 2026 16:53:00 UTC
      Best Path Evaluation: Overall best path
  Refresh Epoch 5
  65100
    10.4.4.4 (metric 11) from 10.4.4.4 (10.4.4.4)
      Origin IGP, metric 0, localpref 100, valid, internal, multipath(oldest)
      rx pathid: 0, tx pathid: 0
      Updated on Oct 3 2026 18:16:08 UTC
      Best Path Evaluation: Higher router ID

At first this can look contradictory.

R4 is marked multipath, yet Cisco still reports: Best Path Evaluation: Higher router ID

Both statements are correct because they answer different questions.

Best-path selection:
Which path is the single BGP winner?

Multipath eligibility:
Can another sufficiently equal path also be used for forwarding?

R4 still loses the single-best-path comparison because R2 has the lower router ID. However, R4 remains sufficiently equal through the multipath eligibility checks to also be installed for forwarding.

The result is:

Control plane:
R2 remains the canonical BGP best path

Forwarding plane:
R2 and R4 are both usable

The routing table confirms that both BGP next hops are now installed:

IOS
R3# show ip route 192.0.2.0

Routing entry for 192.0.2.0/24
  Known via "bgp 65000", distance 200, metric 0
  Tag 65100, type internal
  Last update from 10.4.4.4 00:01:02 ago
  Routing Descriptor Blocks:
    10.4.4.4, from 10.4.4.4, 00:01:02 ago
      Route metric is 0, traffic share count is 1
      AS Hops 1
      Route tag 65100
      MPLS label: none
  * 10.2.2.2, from 10.2.2.2, 00:01:02 ago
      Route metric is 0, traffic share count is 1
      AS Hops 1
      Route tag 65100
      MPLS label: none

Both paths have a traffic share count of 1, meaning they are installed as equal forwarding choices.

The forwarding table gives us even stronger verification:

IOS
R3# show ip cef 192.0.2.1

192.0.2.0/24
  nexthop 10.23.23.1 Ethernet0/1
  nexthop 10.34.34.2 Ethernet0/2

The addresses shown by CEF differ from the BGP next hops:

BGP next hops:
10.2.2.2
10.4.4.4

CEF next hops:
10.23.23.1
10.34.34.2

That is expected.

Our iBGP sessions use router loopbacks, so the BGP next hops must themselves be resolved through the IGP before packets can actually be forwarded.

R3 resolves:

BGP next hop 10.2.2.2
        ↓
OSPF resolution
        ↓
10.23.23.1 via Ethernet0/1

and:

BGP next hop 10.4.4.4
        ↓
OSPF resolution
        ↓
10.34.34.2 via Ethernet0/2

CEF therefore contains the directly reachable forwarding adjacencies rather than the remote loopback addresses themselves.

The process now looks like this:

BGP best-path process
        ↓
R2 selected as canonical best path
        ↓
R4 also qualifies for multipath
        ↓
Both BGP next hops installed in the RIB
        ↓
Recursive OSPF next-hop resolution
        ↓
Both forwarding adjacencies installed in CEF

We can also verify the behavior directly in the data plane with a sourced traceroute:

IOS
R3# traceroute 192.0.2.1 source 10.3.3.3

Type escape sequence to abort.
Tracing the route to r1 (192.0.2.1)
VRF info: (vrf in name/id, vrf out name/id)
  1 r2 (10.23.23.1) 1 msec
    r4 (10.34.34.2) 1 msec
    r2 (10.23.23.1) 1 msec
  2 r1 (10.14.14.1) 1 msec
    r1 (10.12.12.1) 0 msec *

This time the traceroute probes visibly exercise both paths.

At the first hop, traffic leaves R3 through both R2 and R4:

             ┌→ R2
R3 ──────────┤
             └→ R4

Those paths then reach R1 through their respective external links:

             ┌→ R2 → R1
R3 ──────────┤
             └→ R4 → R1

This gives us three layers of verification:

BGP table:
Both paths marked multipath

RIB:
Both BGP next hops installed

CEF and traceroute:
Both forwarding paths are available and being used

The traceroute happens to show both paths clearly in this experiment, but it is still important not to rely on traceroute alone to prove ECMP. Equal-cost forwarding is generally hash-based, so a particular flow or sequence of probes may continue using only one available path.

The RIB and CEF outputs are the stronger evidence that both forwarding paths have actually been installed.

There is also an important operational detail in the scope of the configuration.

We configured:

maximum-paths ibgp 2

Under the entire IPv4 address family. The setting is not specific to 192.0.2.0/24.

R3 therefore installs multiple paths for other eligible iBGP prefixes as well:

IOS
R3# show ip route bgp

B        10.1.1.1/32 [200/0] via 10.4.4.4
                     [200/0] via 10.2.2.2

B        10.7.7.7/32 [200/0] via 10.6.6.6
                     [200/0] via 10.5.5.5

B     192.0.2.0/24 [200/0] via 10.4.4.4
                   [200/0] via 10.2.2.2

B     198.51.100.0/24 [200/0] via 10.6.6.6
                      [200/0] via 10.5.5.5

That matters operationally. Enabling BGP multipath changes how the router can install all eligible paths within that address family, not just the prefix used for this experiment.

The important takeaway is that multipath is not another winner-versus-loser best-path criterion.

BGP still selects one canonical best path. Multipath answers a separate question:

Which path is best?
        ↓
R2

Are any additional paths sufficiently equal
to also be installed for forwarding?
        ↓
Yes — R4

That is why we can simultaneously see:

R2:
multipath, best

R4:
multipath(oldest)
Best Path Evaluation: Higher router ID

R4 lost the final best-path tie-breaker, but it did not lose multipath eligibility.

Reset on R3:

IOS
configure terminal

router bgp 65000
 address-family ipv4
  no maximum-paths ibgp 2
 exit-address-family

end

After the reset, R3 again installs only the single BGP best path to 192.0.2.0/24, with the path through R2 winning on the later router-ID comparison.

Oldest eBGP Path

Once the earlier best-path criteria remain tied, Cisco can prefer the oldest eBGP path.

This is not a traffic-engineering attribute like Local Preference or MED. It is a late stability-oriented tie-breaker designed to avoid unnecessary best-path changes between otherwise equivalent external routes.

A useful way to think about it is:

Two eBGP paths are otherwise equal
        ↓
One has been stable longer
        ↓
Prefer the older path

The logic is simple: if BGP already has a stable external path and an equivalent path appears later, there is little benefit in immediately switching to the newer route just because an even later tie-breaker might favor it.

Question: If two eBGP paths are equal through the earlier best-path criteria, will Cisco keep the path that has been stable longer?

R1 already gives us a clean example using 198.51.100.0/24.

At baseline, R1 receives two external paths through AS65000:

IOS
R1# show ip bgp 198.51.100.0

BGP routing table entry for 198.51.100.0/24, version 10
Paths: (2 available, best #2, table default)

  65000 65200
    10.12.12.2 from 10.12.12.2 (10.2.2.2)
      Origin IGP, localpref 100, valid, external

  65000 65200
    10.14.14.2 from 10.14.14.2 (10.4.4.4)
      Origin IGP, localpref 100, valid, external, best

The paths are tied on the earlier criteria that matter here:

Via R2:
AS_PATH:          65000 65200
Origin:           IGP
Local Preference: 100
Path type:        eBGP

Via R4:
AS_PATH:          65000 65200
Origin:           IGP
Local Preference: 100
Path type:        eBGP

Cisco tells us exactly why the R2 path loses:

IOS
R1# show ip bgp 198.51.100.0 best-path-reason

...
65000 65200
  10.12.12.2 from 10.12.12.2 (10.2.2.2)
    Origin IGP, localpref 100, valid, external
    Best Path Evaluation: Path is younger

65000 65200
  10.14.14.2 from 10.14.14.2 (10.4.4.4)
    Origin IGP, localpref 100, valid, external, best
    Best Path Evaluation: Overall best path

At this point, the path through R4 is older and therefore remains the best path.

The routing table reflects that decision:

IOS
R1# show ip route 198.51.100.0

Routing entry for 198.51.100.0/24
  Known via "bgp 65100", distance 20, metric 0
  Tag 65000, type external
  Last update from 10.14.14.2 2d08h ago

Routing Descriptor Blocks:
* 10.14.14.2, from 10.14.14.2

To prove that path age is actually deciding the winner, we can deliberately make the current best path younger without changing any BGP policy attribute.

On R1, reset only the eBGP session toward R4:

IOS
clear ip bgp 10.14.14.2

This is a hard reset, so the R1↔R4 BGP session briefly drops and then re-establishes.

We are doing this only to manipulate path age in the lab. Resetting BGP sessions is not a normal production traffic-engineering method.

After the session returns, the neighbor uptime makes the change obvious:

IOS
R1# show ip bgp summary

Neighbor        V           AS   Up/Down   State/PfxRcd
10.12.12.2      4        65000   2d08h            7
10.14.14.2      4        65000   00:01:06         7

The R2 session has remained established for more than two days, while the R4 session has only been back for about a minute.

The BGP table now flips:

IOS
R1# show ip bgp 198.51.100.0

BGP routing table entry for 198.51.100.0/24, version 12
Paths: (2 available, best #2, table default)

  65000 65200
    10.14.14.2 from 10.14.14.2 (10.4.4.4)
      Origin IGP, localpref 100, valid, external
      Updated on Oct 5 2026 00:05:33 UTC

  65000 65200
    10.12.12.2 from 10.12.12.2 (10.2.2.2)
      Origin IGP, localpref 100, valid, external, best
      Updated on Oct 2 2026 15:35:43 UTC

Now the R4 path is younger, and Cisco explicitly says so:

IOS
R1# show ip bgp 198.51.100.0 best-path-reason

...
65000 65200
  10.14.14.2 from 10.14.14.2 (10.4.4.4)
    Origin IGP, localpref 100, valid, external
    Best Path Evaluation: Path is younger

65000 65200
  10.12.12.2 from 10.12.12.2 (10.2.2.2)
    Origin IGP, localpref 100, valid, external, best
    Best Path Evaluation: Overall best path

The routing table also moves to R2:

IOS
R1# show ip route 198.51.100.0

Routing entry for 198.51.100.0/24
  Known via "bgp 65100", distance 20, metric 0
  Tag 65000, type external
  Last update from 10.12.12.2 00:01:08 ago

Routing Descriptor Blocks:
* 10.12.12.2, from 10.12.12.2

The before-and-after result is clean:

Before reset:

R4 path = older
R2 path = younger
        ↓
R4 wins
After reset:

R2 path = older
R4 path = younger
        ↓
R2 wins

Nothing about Weight, Local Preference, AS_PATH, Origin, MED, or path type changed. The only thing we deliberately changed was the age of the R4 path.

That proves the oldest-eBGP-path criterion directly.

It also demonstrates why this criterion exists. Imagine an external route that has been stable for hours or days. If another path appears with exactly the same meaningful routing attributes, BGP has little reason to churn traffic onto the newcomer. Keeping the older path favors stability unless a stronger criterion provides a reason to change.

This is why path age should be viewed as a stability tie-breaker, not as a normal traffic-engineering tool.

Router ID

If the earlier best-path criteria still cannot break the tie, Cisco prefers the path advertised by the BGP speaker with the lowest BGP router ID.

This is a late tie-breaker rather than a normal traffic-engineering mechanism. By the time BGP reaches router ID, the competing paths have already tied on the more meaningful policy and topology criteria.

Our existing R3 baseline demonstrates it naturally.

R3 receives two iBGP paths to 192.0.2.0/24:

Via R2:
BGP next hop: 10.2.2.2
Router ID:    10.2.2.2

Via R4:
BGP next hop: 10.4.4.4
Router ID:    10.4.4.4

The paths are tied through the earlier criteria, including the IGP metric:

IOS
R3# show ip bgp 192.0.2.0

65100
  10.2.2.2 (metric 11) from 10.2.2.2 (10.2.2.2)
    Origin IGP, metric 0, localpref 100, valid, internal, best

65100
  10.4.4.4 (metric 11) from 10.4.4.4 (10.4.4.4)
    Origin IGP, metric 0, localpref 100, valid, internal

Cisco identifies the router ID comparison directly:

IOS
R3# show ip bgp 192.0.2.0 best-path-reason

...
10.2.2.2 (metric 11) from 10.2.2.2 (10.2.2.2)
  ...
  Best Path Evaluation: Overall best path

10.4.4.4 (metric 11) from 10.4.4.4 (10.4.4.4)
  ...
  Best Path Evaluation: Higher router ID

R2 wins because:

10.2.2.2 < 10.4.4.4

So the path learned from R2 becomes the best path.

The important takeaway is that router ID is a deterministic late-stage tie-breaker. Engineers generally would not manipulate BGP router IDs to steer traffic. If traffic policy needs to change, earlier attributes such as Local Preference, AS_PATH, MED, or even the IGP metric are much more appropriate tools.

Originator ID and Cluster List

The final best-path tie-breakers become more interesting once route reflection is involved.

Our main AS65000 topology uses a full iBGP mesh, so route-reflector-specific attributes never appear there. For these tests, we built a small dedicated micro-lab with two route reflectors, two clients, and an observer router.

The roles are:

C1, C2:
Route-reflector clients

RR1, RR2:
Route reflectors

OBS:
Router where we compare reflected copies
of the same prefix

All routers are in AS65000, and OSPF provides loopback reachability between them.

Route-reflector micro-lab topology. C1 and C2 act as route-reflector clients, RR1 and RR2 act as route reflectors, and OBS is used to compare multiple reflected copies of the same prefix.

Lab Topology

The micro-lab is built with the following topology.yml:

YML
provider: clab

defaults:
  device: iol
  devices:
    iol:
      clab:
        image: vrnetlab/cisco_iol:17.12.01

ospf:
  area: 0.0.0.0

nodes:

  c1:
    module: [ ospf ]
    loopback:
      ipv4: 10.0.0.1/32

  c2:
    module: [ ospf ]
    loopback:
      ipv4: 10.0.0.2/32

  rr1:
    module: [ ospf ]
    loopback:
      ipv4: 10.0.0.11/32

  rr2:
    module: [ ospf ]
    loopback:
      ipv4: 10.0.0.12/32

  obs:
    module: [ ospf ]
    loopback:
      ipv4: 10.0.0.100/32

links:

  - name: C1-RR1
    c1: { ipv4: 10.1.11.1/30 }
    rr1: { ipv4: 10.1.11.2/30 }

  - name: C1-RR2
    c1: { ipv4: 10.1.12.1/30 }
    rr2: { ipv4: 10.1.12.2/30 }

  - name: C2-RR1
    c2: { ipv4: 10.2.11.1/30 }
    rr1: { ipv4: 10.2.11.2/30 }

  - name: C2-RR2
    c2: { ipv4: 10.2.12.1/30 }
    rr2: { ipv4: 10.2.12.2/30 }

  - name: RR1-RR2
    rr1: { ipv4: 10.11.12.1/30 }
    rr2: { ipv4: 10.11.12.2/30 }

  - name: OBS-RR1
    obs: { ipv4: 10.100.11.1/30 }
    rr1: { ipv4: 10.100.11.2/30 }

  - name: OBS-RR2
    obs: { ipv4: 10.100.12.1/30 }
    rr2: { ipv4: 10.100.12.2/30 }

Netlab is intentionally used only to build the interfaces, loopbacks, and OSPF underlay. BGP is configured manually so we have complete control over which sessions exist, which routers are route-reflector clients, and how each reflected copy of the test prefix is created.

The loopbacks are:

C1    10.0.0.1
C2    10.0.0.2

RR1   10.0.0.11
RR2   10.0.0.12

OBS   10.0.0.100

The test prefix for this micro-lab is:

203.0.113.0/24

Before configuring BGP, we verify that the OSPF underlay provides reachability between all loopbacks.

From OBS:

IOS
OBS# show ip ospf neighbor

Neighbor ID     Pri   State       Address         Interface
10.0.0.12         0   FULL/-      10.100.12.2     Ethernet0/2
10.0.0.11         0   FULL/-      10.100.11.2     Ethernet0/1

OBS also has equal-cost OSPF reachability to both clients:

IOS
O 10.0.0.1/32 [110/21] via 10.100.12.2
               [110/21] via 10.100.11.2

O 10.0.0.2/32 [110/21] via 10.100.12.2
               [110/21] via 10.100.11.2

That equal IGP cost is important because it prevents the IGP-metric criterion from breaking the tie before we reach Originator ID or Cluster List.

Originator ID

When a route reflector reflects an iBGP route, it adds an ORIGINATOR_ID attribute that identifies the router that originally introduced the route into the route-reflector topology.

This is important for two reasons. First, it helps prevent routing loops by allowing the original router to recognize a reflected copy of its own route. Second, when Cisco reaches the late router-ID comparison during best-path selection, the Originator ID is used for reflected routes.

For the first experiment, both clients originate the same prefix:

203.0.113.0/24

The control-plane flow is:

C1 → RR1 → OBS

C2 → RR2 → OBS

C1 originates one copy of the prefix and C2 originates another. RR1 and RR2 reflect those routes toward OBS.

The BGP configuration is intentionally manual so we can control exactly which routers are clients of which reflectors.

C1:

IOS
configure terminal

ip route 203.0.113.0 255.255.255.0 Null0

router bgp 65000
 bgp router-id 10.0.0.1
 no bgp default ipv4-unicast

 neighbor 10.0.0.11 remote-as 65000
 neighbor 10.0.0.11 update-source Loopback0

 address-family ipv4
  network 203.0.113.0 mask 255.255.255.0
  neighbor 10.0.0.11 activate
 exit-address-family

end

RR1:

IOS
configure terminal

router bgp 65000
 bgp router-id 10.0.0.11
 no bgp default ipv4-unicast

 neighbor 10.0.0.1 remote-as 65000
 neighbor 10.0.0.1 update-source Loopback0

 neighbor 10.0.0.100 remote-as 65000
 neighbor 10.0.0.100 update-source Loopback0

 address-family ipv4
  neighbor 10.0.0.1 activate
  neighbor 10.0.0.1 route-reflector-client

  neighbor 10.0.0.100 activate
  neighbor 10.0.0.100 route-reflector-client
 exit-address-family

end

C2:

IOS
configure terminal

ip route 203.0.113.0 255.255.255.0 Null0

router bgp 65000
 bgp router-id 10.0.0.2
 no bgp default ipv4-unicast

 neighbor 10.0.0.12 remote-as 65000
 neighbor 10.0.0.12 update-source Loopback0

 address-family ipv4
  network 203.0.113.0 mask 255.255.255.0
  neighbor 10.0.0.12 activate
 exit-address-family

end

RR2:

IOS
configure terminal

router bgp 65000
 bgp router-id 10.0.0.12
 no bgp default ipv4-unicast

 neighbor 10.0.0.2 remote-as 65000
 neighbor 10.0.0.2 update-source Loopback0

 neighbor 10.0.0.100 remote-as 65000
 neighbor 10.0.0.100 update-source Loopback0

 address-family ipv4
  neighbor 10.0.0.2 activate
  neighbor 10.0.0.2 route-reflector-client

  neighbor 10.0.0.100 activate
  neighbor 10.0.0.100 route-reflector-client
 exit-address-family

end

OBS:

IOS
configure terminal

router bgp 65000
 bgp router-id 10.0.0.100
 no bgp default ipv4-unicast

 neighbor 10.0.0.11 remote-as 65000
 neighbor 10.0.0.11 update-source Loopback0

 neighbor 10.0.0.12 remote-as 65000
 neighbor 10.0.0.12 update-source Loopback0

 address-family ipv4
  neighbor 10.0.0.11 activate
  neighbor 10.0.0.12 activate
 exit-address-family

end

Once the sessions establish, OBS receives one reflected copy from each route reflector:

IOS
OBS# show ip bgp summary

Neighbor        V           AS   Up/Down  State/PfxRcd
10.0.0.11       4        65000   00:01:03        1
10.0.0.12       4        65000   00:01:08        1

Now inspect the test prefix:

IOS
OBS# show ip bgp 203.0.113.0

BGP routing table entry for 203.0.113.0/24, version 2
Paths: (2 available, best #2, table default)

  Local
    10.0.0.2 (metric 21) from 10.0.0.12 (10.0.0.12)
      Origin IGP, metric 0, localpref 100, valid, internal
      Originator: 10.0.0.2, Cluster list: 10.0.0.12

  Local
    10.0.0.1 (metric 21) from 10.0.0.11 (10.0.0.11)
      Origin IGP, metric 0, localpref 100, valid, internal, best
      Originator: 10.0.0.1, Cluster list: 10.0.0.11

Both paths remain tied through the earlier criteria:

Weight:           equal
Local Preference: equal
AS_PATH:          equal
Origin:           equal
MED:              equal
Path type:        both iBGP
IGP metric:       21

The difference is the Originator ID:

Via RR1:
Originator ID 10.0.0.1

Via RR2:
Originator ID 10.0.0.2

Cisco identifies the losing route with:

IOS
OBS# show ip bgp 203.0.113.0 best-path-reason

...
Originator: 10.0.0.2, Cluster list: 10.0.0.12
Best Path Evaluation: Higher router ID

...
Originator: 10.0.0.1, Cluster list: 10.0.0.11
Best Path Evaluation: Overall best path

The output still says Higher router ID, but for these reflected paths Cisco is using the Originator ID in that comparison.

Because:

10.0.0.1 < 10.0.0.2

The route originally introduced by C1 wins.

The routing table confirms the result:

IOS
OBS# show ip route 203.0.113.0

Routing entry for 203.0.113.0/24
  Known via "bgp 65000", distance 200, metric 0, type internal

Routing Descriptor Blocks:
* 10.0.0.1, from 10.0.0.11

This is the key behavior to remember: the route reflector does not replace the identity of the original advertising router for this late tie-breaker. The ORIGINATOR_ID preserves that identity through the reflected topology.

Cluster List

If the Originator ID also ties, Cisco continues farther down the decision process and compares Cluster List length.

The Cluster List records which route-reflector clusters a reflected route has crossed. Each reflector adds its own cluster ID as it reflects the route.

This is primarily a loop-prevention mechanism. If a route reflector receives a route containing its own cluster ID, it rejects that route rather than reflecting it again.

For this experiment, we stop C2 from originating the test prefix and make both paths originate from C1.

The control-plane flow becomes:

Direct reflected path:

C1 → RR1 → OBS

And:

Longer reflected path:

C1 → RR1 → RR2 → OBS

Now both copies have the same Originator ID, but one has crossed an additional reflector.

On C2, remove the test prefix:

IOS
configure terminal

router bgp 65000
 address-family ipv4
  no network 203.0.113.0 mask 255.255.255.0
 exit-address-family

no ip route 203.0.113.0 255.255.255.0 Null0

end

Next, establish a normal iBGP session between RR1 and RR2. They are not route-reflector clients of each other.

RR1:

IOS
configure terminal

router bgp 65000
 neighbor 10.0.0.12 remote-as 65000
 neighbor 10.0.0.12 update-source Loopback0

 address-family ipv4
  neighbor 10.0.0.12 activate
 exit-address-family

end

RR2:

IOS
configure terminal

router bgp 65000
 neighbor 10.0.0.11 remote-as 65000
 neighbor 10.0.0.11 update-source Loopback0

 address-family ipv4
  neighbor 10.0.0.11 activate
 exit-address-family

end

RR2 now receives the C1 route from RR1:

IOS
RR2# show ip bgp 203.0.113.0

BGP routing table entry for 203.0.113.0/24, version 4
Paths: (1 available, best #1, table default)

  Local
    10.0.0.1 (metric 11) from 10.0.0.11 (10.0.0.11)
      Origin IGP, metric 0, localpref 100, valid, internal, best
      Originator: 10.0.0.1, Cluster list: 10.0.0.11

Because OBS is a client of RR2, RR2 reflects that route again.

OBS now receives two copies with the same Originator ID:

IOS
OBS# show ip bgp 203.0.113.0

BGP routing table entry for 203.0.113.0/24, version 2
Paths: (2 available, best #2, table default)

  Local
    10.0.0.1 (metric 21) from 10.0.0.12 (10.0.0.12)
      Origin IGP, metric 0, localpref 100, valid, internal
      Originator: 10.0.0.1, Cluster list: 10.0.0.12, 10.0.0.11

  Local
    10.0.0.1 (metric 21) from 10.0.0.11 (10.0.0.11)
      Origin IGP, metric 0, localpref 100, valid, internal, best
      Originator: 10.0.0.1, Cluster list: 10.0.0.11

The earlier criteria now remain tied all the way through Originator ID:

Same Weight
Same Local Preference
Same AS_PATH
Same Origin
Same MED
Both iBGP
Same IGP metric
Same Originator ID

The difference is the Cluster List length:

Via RR1:
10.0.0.11
Length = 1

Via RR2:
10.0.0.12, 10.0.0.11
Length = 2

Cisco identifies the deciding factor directly:

IOS
OBS# show ip bgp 203.0.113.0 best-path-reason

...
Originator: 10.0.0.1, Cluster list: 10.0.0.12, 10.0.0.11
Best Path Evaluation: Longer cluster length

...
Originator: 10.0.0.1, Cluster list: 10.0.0.11
Best Path Evaluation: Overall best path

The shorter Cluster List wins.

Conceptually:

C1 → RR1 → OBS
Cluster List length = 1

C1 → RR1 → RR2 → OBS
Cluster List length = 2

So: 1 < 2

and the direct path through RR1 remains best.

This is another very late tie-breaker. In most real networks, stronger policy or topology differences will resolve the best path long before BGP reaches Cluster List length. Its primary purpose is tied to route-reflector loop prevention and deterministic selection between otherwise equivalent reflected paths.

From here, the only remaining tie-breaker we need to prove is lowest neighbor address.

Lowest Neighbor Address

If all earlier best-path criteria remain tied, Cisco uses the lowest BGP neighbor address as the final tie-breaker.

This is a last-resort deterministic comparison. By the time BGP reaches this point, the competing paths have already tied on the more meaningful policy, topology, and route-reflector criteria.

For this final experiment, we want both reflected copies of 203.0.113.0/24 to have the same Originator ID and the same Cluster List length so that BGP is forced all the way down to the peer-address comparison.

In the previous Cluster List test, the route followed:

C1 → RR1 → RR2 → OBS

That intentionally created a longer Cluster List through RR2.

First, remove the RR1↔RR2 iBGP session.

RR1:

IOS
configure terminal

router bgp 65000
 address-family ipv4
  no neighbor 10.0.0.12 activate
 exit-address-family

 no neighbor 10.0.0.12

end

RR2:

IOS
configure terminal

router bgp 65000
 address-family ipv4
  no neighbor 10.0.0.11 activate
 exit-address-family

 no neighbor 10.0.0.11

end

Next, make C1 peer directly with RR2 as well as RR1.

C1:

IOS
configure terminal

router bgp 65000
 neighbor 10.0.0.12 remote-as 65000
 neighbor 10.0.0.12 update-source Loopback0

 address-family ipv4
  neighbor 10.0.0.12 activate
 exit-address-family

end

C1 is already originating:

203.0.113.0/24

so no additional network statement is required.

Now configure C1 as a route-reflector client of RR2.

RR2:

IOS
configure terminal

router bgp 65000
 neighbor 10.0.0.1 remote-as 65000
 neighbor 10.0.0.1 update-source Loopback0

 address-family ipv4
  neighbor 10.0.0.1 activate
  neighbor 10.0.0.1 route-reflector-client
 exit-address-family

end

RR1 already has C1 configured as a route-reflector client, so no change is required there.

The control-plane now becomes:

C1 → RR1 → OBS

C1 → RR2 → OBS

Both route reflectors now receive the prefix directly from the same originator.

RR1:

IOS
RR1# show ip bgp 203.0.113.0

BGP routing table entry for 203.0.113.0/24, version 2
Paths: (1 available, best #1, table default)

  Local, (Received from a RR-client)
    10.0.0.1 (metric 11) from 10.0.0.1 (10.0.0.1)
      Origin IGP, metric 0, localpref 100, valid, internal, best

RR2:

IOS
RR2# show ip bgp 203.0.113.0

BGP routing table entry for 203.0.113.0/24, version 6
Paths: (1 available, best #1, table default)

  Local, (Received from a RR-client)
    10.0.0.1 (metric 11) from 10.0.0.1 (10.0.0.1)
      Origin IGP, metric 0, localpref 100, valid, internal, best

OBS therefore receives two reflected copies of the same route:

IOS
OBS# show ip bgp 203.0.113.0

BGP routing table entry for 203.0.113.0/24, version 2
Paths: (2 available, best #2, table default)

  Local
    10.0.0.1 (metric 21) from 10.0.0.12 (10.0.0.12)
      Origin IGP, metric 0, localpref 100, valid, internal
      Originator: 10.0.0.1, Cluster list: 10.0.0.12

  Local
    10.0.0.1 (metric 21) from 10.0.0.11 (10.0.0.11)
      Origin IGP, metric 0, localpref 100, valid, internal, best
      Originator: 10.0.0.1, Cluster list: 10.0.0.11

At this point, the relevant criteria are tied all the way down:

Weight:               same
Local Preference:     same
AS_PATH:              same
Origin:               same
MED:                  same
Path type:            both iBGP
IGP metric:           21
Originator ID:        10.0.0.1
Cluster List length:  1

That leaves only the BGP peer address.

OBS learned one path from:

RR1: 10.0.0.11

And the other from:

RR2: 10.0.0.12

Cisco prefers the lower address:

10.0.0.11 < 10.0.0.12

The best-path-reason output makes the final comparison explicit:

IOS
OBS# show ip bgp 203.0.113.0 best-path-reason

...
10.0.0.1 (metric 21) from 10.0.0.12 (10.0.0.12)
  Origin IGP, metric 0, localpref 100, valid, internal
  Originator: 10.0.0.1, Cluster list: 10.0.0.12
  Best Path Evaluation: Higher peer address

...
10.0.0.1 (metric 21) from 10.0.0.11 (10.0.0.11)
  Origin IGP, metric 0, localpref 100, valid, internal, best
  Originator: 10.0.0.1, Cluster list: 10.0.0.11
  Best Path Evaluation: Overall best path

The routing table confirms that the path learned from RR1 is installed:

IOS
OBS# show ip route 203.0.113.0

Routing entry for 203.0.113.0/24
  Known via "bgp 65000", distance 200, metric 0, type internal

Routing Descriptor Blocks:
* 10.0.0.1, from 10.0.0.11

This is the final fallback tie-breaker in the sequence we tested.

It is not a traffic-engineering mechanism. If BGP reaches this comparison, every higher-priority policy and topology decision has already tied. The purpose is simply to ensure that BGP can still choose one deterministic winner.

Conceptually:

All earlier criteria tied
        ↓
Same Originator ID
        ↓
Same Cluster List length
        ↓
Compare BGP peer address
        ↓
Lowest peer address wins

In this lab:

10.0.0.11 → RR1 → best

10.0.0.12 → RR2 → loses
             Higher peer address

Final Best-Path Decision Map

At this point, we have worked through the Cisco BGP best-path process from the highest-priority policy decisions down to the final deterministic tie-breakers.

The order we tested is:

1. Highest Weight
2. Highest Local Preference
3. Prefer locally originated path
4. Lowest AIGP metric, if AIGP is in use
5. Shortest AS_PATH
6. Lowest Origin type
7. Lowest MED
8. Prefer eBGP over iBGP
9. Lowest IGP metric to the BGP next hop
10. Multipath eligibility check
11. Oldest eBGP path
12. Lowest Router ID / Originator ID
13. Shortest Cluster List
14. Lowest neighbor address

The important troubleshooting habit is not to memorize this as a flat list and then stare at a BGP table.

Instead, compare the candidate paths from the top and stop at the first difference.

Candidate Path A
Candidate Path B
        ↓
Compare Weight
        ↓
Tie?
        ↓
Compare Local Preference
        ↓
Tie?
        ↓
Continue downward
        ↓
First difference wins

BGP does not evaluate every criterion once a winner has already been found.

That simple idea explains nearly every experiment in this lab.

When we raised Weight on one path, BGP never cared about Local Preference, AS_PATH, or anything below it.

When Local Preference differed, the fact that one path was eBGP and the other iBGP did not matter.

When MED differed, BGP selected the lower MED before reaching the eBGP-versus-iBGP comparison.

When every meaningful attribute tied, we eventually reached late criteria such as Router ID, Cluster List length, and peer address.

A Repeatable Troubleshooting Workflow

When a router is choosing a BGP path you did not expect, start by looking at the candidates themselves.

IOS
show ip bgp <prefix>

Identify:

How many valid paths exist?
Which one is marked best?
What are the next hops?
Are the paths internal or external?
What are the visible attributes?

Then ask Cisco directly why each path did or did not win:

IOS
show ip bgp <prefix> best-path-reason

That command became one of the most useful tools in this entire lab.

Instead of guessing, we repeatedly saw explicit reasons such as:

Lower weight
Lower local preference
Not sourced
Longer AS path
Less favorable origin
Higher MED
Same MED but path is internal while bestpath is external
Higher IGP metric
Path is younger
Higher router ID
Longer cluster length
Higher peer address

From there, verify what BGP actually installed:

IOS
show ip route <prefix>

And when the forwarding behavior matters, verify the data plane too:

IOS
traceroute <destination> source <loopback>

or, for ECMP and recursive forwarding:

IOS
show ip cef <destination>

A useful hierarchy is:

show ip bgp
    ↓
What paths exist?

show ip bgp ... best-path-reason
    ↓
Why did BGP choose one?

show ip route
    ↓
What did the RIB install?

show ip cef / traceroute
    ↓
Where will packets actually go?

That distinction matters because the BGP table, RIB, and forwarding plane answer different questions.

What We Learned

BGP best-path selection is much easier to reason about when treated as an ordered decision process rather than a collection of unrelated attributes.

The biggest lessons from this lab are:

  • The first difference wins. Once a criterion selects a winner, everything below it becomes irrelevant for that comparison.
  • Policy generally beats topology. Weight, Local Preference, AS_PATH, Origin, and MED are evaluated before later topology-oriented criteria such as eBGP/iBGP and IGP cost.
  • The IGP still matters. Even with BGP carrying the destination route, BGP relies on the underlying IGP to resolve next hops and can use that IGP cost when choosing between otherwise equal paths.
  • Multipath is not another winner/loser criterion. BGP still chooses one canonical best path while additional sufficiently equal paths may also be installed for forwarding.
  • The late tie-breakers are about determinism and stability. Oldest path, Router ID, Originator ID, Cluster List length, and peer address are rarely the attributes an engineer intentionally manipulates for normal traffic engineering.

The larger operational lesson is that unexpected BGP behavior usually becomes much less mysterious once the competing paths are compared in the correct order.

Instead of asking:

Why did BGP choose this route?

Ask:

What is the first attribute or criterion
where these two paths differ?

Final Decision Flow

Valid BGP paths
      ↓
Highest Weight
      ↓
Highest Local Preference
      ↓
Locally originated?
      ↓
Lowest AIGP
      ↓
Shortest AS_PATH
      ↓
Best Origin
      ↓
Lowest MED
      ↓
eBGP over iBGP
      ↓
Lowest IGP metric to BGP next hop
      ↓
Multipath eligibility
      ↓
Oldest eBGP path
      ↓
Lowest Router ID / Originator ID
      ↓
Shortest Cluster List
      ↓
Lowest neighbor address
      ↓
Best path

After working through each of these in the lab, the algorithm stops looking like an arbitrary list of BGP trivia.

It becomes a hierarchy:

Policy
  ↓
Path characteristics
  ↓
External vs internal preference
  ↓
Underlying topology
  ↓
Stability
  ↓
Deterministic tie-breakers

And that is a much more useful way to remember it.

References

  • RFC 4271 — A Border Gateway Protocol 4 (BGP-4)
    The base BGP specification. Useful for BGP operation, path attributes including ORIGIN, AS_PATH, NEXT_HOP, MULTI_EXIT_DISC, and LOCAL_PREF, and the general BGP decision process.
    RFC 4271 — A Border Gateway Protocol 4 (BGP-4)
  • Cisco — Select BGP Best-path Algorithm
    The primary reference for the Cisco-specific best-path order used throughout this lab, including Weight, Local Preference, locally originated routes, AIGP, AS_PATH, Origin, MED, eBGP over iBGP, IGP metric, oldest external path, Router ID / Originator ID, Cluster List length, and neighbor address. This should be the main reference for the article.
    Cisco — Select BGP Best-path Algorithm
  • Cisco — Understand the Importance of BGP Weight Path Attribute
    Supports the Weight section, including Cisco-specific behavior and the fact that Weight is locally significant rather than propagated between BGP speakers.
    Cisco — Understand the Importance of BGP Weight Path Attribute
  • Cisco — Examine Border Gateway Protocol Case Studies
    Useful supporting material for Local Preference, Weight, AS_PATH manipulation, MED, and general BGP policy behavior.
    Cisco — Examine Border Gateway Protocol Case Studies
  • RFC 7311 — The Accumulated IGP Metric Attribute for BGP
    Defines AIGP as an optional, non-transitive BGP attribute and explains its purpose for accumulating IGP-derived cost across an administrative domain.
    RFC 7311 — The Accumulated IGP Metric Attribute for BGP
  • Cisco — Configure the AIGP Metric Attribute for BGP
    Cisco-specific AIGP configuration and its placement in the Cisco best-path process. This directly supports the AIGP discussion even though we intentionally did not configure AIGP in the lab.
    Cisco — Configure the AIGP Metric Attribute for BGP
  • Cisco — Use MultiExit Discriminator to Influence BGP Best Path Selection
    Supports the MED experiment, including the preference for lower MED and MED’s use in influencing which entry point a neighboring AS selects.
    Cisco — Use MultiExit Discriminator to Influence BGP Best Path Selection
  • Cisco — How the bgp deterministic-med Command Differs from the bgp always-compare-med Command
    Supports the distinction made in the MED section: always-compare-med allows MED comparison across different neighboring ASes, while deterministic-med changes how routes from the same neighboring AS are grouped and compared.
    Cisco — deterministic-med vs always-compare-med
  • Cisco IOS BGP Command Reference — maximum-paths ibgp
    Supports the multipath section. Cisco documents that iBGP multipath can install additional eligible paths while BGP still retains and advertises a single best path. It also documents the equality requirements for multipath candidates.
    Cisco IOS BGP Command Reference — maximum-paths ibgp
  • Cisco IOS XE 17.x — Cisco BGP Overview
    Useful supporting reference for the relationship between BGP best-path selection, multipath candidates, and the routing table.
    Cisco IOS XE 17.x — Cisco BGP Overview
  • Cisco — BGP Administrative Distance
    Supports the distinction made in the eBGP-versus-iBGP section: administrative distance does not determine the winner inside the BGP best-path algorithm. Cisco documents the default values of 20 for eBGP and 200 for iBGP and explicitly notes that administrative distance affects RIB installation rather than BGP path selection itself.
    Cisco — BGP Administrative Distance
  • RFC 4456 — BGP Route Reflection: An Alternative to Full Mesh Internal BGP
    The primary standards reference for the route-reflector portion of the article, including route-reflector clients, ORIGINATOR_ID, and CLUSTER_LIST.
    RFC 4456 — BGP Route Reflection
  • Cisco IOS XE 17.x — Configuring Internal BGP Features
    Cisco’s route-reflector documentation. Supports the micro-lab configuration, route-reflector-client, cluster IDs, and displaying Originator ID and Cluster List attributes.
    Cisco IOS XE 17.x — Configuring Internal BGP Features
  • netlab — Using Containerlab with netlab
    Reference for the lab orchestration used throughout the article, including provider: clab, Cisco IOL containers, topology files, and netlab up.
    netlab — Using Containerlab with netlab
  • Containerlab — Quickstart and Topology Definition
    General reference for Containerlab topology-based network labs and containerized network-device orchestration.
    Containerlab — Quickstart
Recent Posts