BGP Route Selection: From Intended Policy to Observed Failover
BGP Decision Process (brief)
BGP chooses the best path using an ordered list of steps (RFC 4271 plus common vendor extensions):
- Highest weight (Cisco‑proprietary)
- Highest LOCAL_PREF
- Locally originated routes
- Shortest AS_PATH
- Lowest origin type (IGP < EGP < INCOMPLETE)
- Lowest MED (only if neighboring AS is the same, unless
bgp always-compare-medis set) - eBGP over iBGP
- Lowest IGP metric to NEXT_HOP
- Oldest route in the Loc‑RIB
- Lowest router ID of the advertising peer
- Lowest cluster length (route‑reflector)
- Lowest neighbor address (final tie‑breaker)
Communities are opaque tags; they do not appear in the decision tree but can influence LOCAL_PREF, MED, or AS‑PATH when referenced in route‑policy statements.
1. Intended Policy
Definition – High‑level routing objectives captured in design documents, policy repositories, or templates. It states what should happen (e.g., set LOCAL_PREF = 150 for primary paths, LOCAL_PREF = 100 for backup) without specifying vendor syntax.
Configuration Example – Translating the intent into vendor‑specific route‑maps/policy statements:
Cisco IOS‑XR
route-policy SET-LOCAL-PREF-BY-COMMUNITY
if community matches-any (65000:100) then
set local-preference 150
elseif community matches-any (65000:200) then
set local-preference 100
else
pass
endif
end-policy
!
router bgp 65000
address-family ipv4 unicast
neighbor 10.0.0.1 remote-as 65001
address-family ipv4 unicast
route-policy SET-LOCAL-PREF-BY-COMMUNITY in
!
neighbor 10.0.0.2 remote-as 65002
address-family ipv4 unicast
route-policy SET-LOCAL-PREF-BY-COMMUNITY in
!
!
Juniper Junos
policy-options {
policy-statement SET-LOCAL-PREF {
term primary {
from { community [ PRIMARY ]; }
then { local-preference 150; accept; }
}
term backup {
from { community [ BACKUP ]; }
then { local-preference 100; accept; }
}
term others { then accept; }
}
}
protocols {
bgp {
group PRIMARY-PEERS {
type external;
neighbor 10.0.0.1 { peer-as 65001; import [ SET-LOCAL-PREF ]; }
neighbor 10.0.0.2 { peer-as 65002; import [ SET-LOCAL-PREF ]; }
}
}
}
policy-options {
community PRIMARY members 65000:100;
community BACKUP members 65000:200;
}
These snippets encode the intended policy: routes carrying community 65000:100 get LOCAL_PREF 150 (primary); routes with community 65000:200 get LOCAL_PREF 100 (backup).
2. Rendered Config
Definition – The concrete, device‑specific configuration produced by a templating engine (Jinja2, Ansible, Terraform, etc.) after substituting variables and applying macros.
How a Refactor Can Break It
- Renaming or dropping a variable that holds the community list.
- Accidentally removing a
set community/community addstatement inside a macro. - Changing the order of policy application so an earlier
passshort‑circuits community matching.
If the community‑setting line is omitted, inbound routes never receive the expected tag, and the downstream policy cannot match them.
Detecting the Gap
Cisco IOS‑XR
show running-config route-policy SET-LOCAL-PREF-BY-COMMUNITY
# Verify presence of: set community 65000:100 additive
Juniper Junos
show configuration policy-options policy-statement SET-LOCAL-PREF
# Verify presence of: community add PRIMARY;
A missing line indicates the rendered config no longer carries the community needed for the policy to match.
3. Applied State
Definition – The active configuration loaded into the routing daemon’s memory after the device parses and installs the rendered config (e.g., after commit on Junos or a copy running-config startup-config followed by a process reload on IOS‑XR).
The applied state should match the rendered config, but discrepancies can arise from:
- Partial commit failures.
- Forgetting to reset BGP after a route‑policy change.
- Cached policy versions due to a faulty reload.
Impact on Failover
When the primary path fails, the speaker re‑evaluates all paths. If the applied state lacks the community that triggers a higher LOCAL_PREF for the backup, the backup retains its default LOCAL_PREF (often 100). Assuming the primary had LOCAL_PREF 150, the backup may lose to any alternative path with LOCAL_PREF ≥ 100, leading to sub‑optimal routing or black‑holing.
Verification Commands
Cisco IOS‑XR
show route-policy SET-LOCAL-PREF-BY-COMMUNITY detail
show bgp ipv4 unicast 203.0.113.0/24 detail
# Look for: Localpref 150, Community: 65000:100
Juniper Junos
show policy policy-statement SET-LOCAL-PREF detail
show route receive-protocol bgp 10.0.0.1 203.0.113.0/24 detail
# Look for: Local preference: 150
If the local‑pref or community values differ from the design, the applied state is suspect.
4. Observed Route Selection & Failover
Definition – The forwarding decision visible in the FIB or routing table after BGP converges. It is the ultimate result of the chain: intended policy → rendered config → applied state → observed selection.
Scenario
- PE1 (AS 65000) receives 10.0.0.0/24 from ISP‑A (AS 65001) and ISP‑B (AS 65002).
- Intended policy: ISP‑A → community 65000:100 → LOCAL_PREF 150 (primary). ISP‑B → community 65000:200 → LOCAL_PREF 100 (backup).
- After a template refactor, the
set communitystatement for ISP‑B is omitted from the rendered config.
Pre‑failure BGP table
Network Next Hop LocPrf Weight Path
*> 10.0.0.0/24 10.0.0.1 150 0 65001 i
* 10.0.0.2 100 0 65002 i
After ISP‑A link fails (with correct community)
Network Next Hop LocPrf Weight Path
*> 10.0.0.0/24 10.0.0.2 100 0 65002 i
If the community is missing, the backup path still shows LocPrf 100, but any policy that also relied on the community to prepend AS‑PATH or set a lower MED would not fire, potentially making the backup less attractive than a third‑party path.
Checking the FIB
Cisco IOS‑XR
show cef ipv4 prefix 10.0.0.0/24 detail
Juniper Junos
show route forwarding-table destination 10.0.0.0/24 extensive
An unexpected next‑hop or a missing entry confirms that the observed selection diverges from the intended policy.
5. Troubleshooting Missing Communities or Attributes
Symptoms
- Backup path present in BGP table but not selected after primary failure.
- Local‑pref values on received routes do not match the design (e.g., all show 100).
- Community list empty on routes that should carry a specific tag (
show bgp … community). - Increased latency or packet loss following a template push.
- BGP neighbor flaps with no alternate path installed.
Systematic CLI‑Based Approach
-
Confirm the backup path exists
show bgp ipv4 unicast 10.0.0.0/24 -
Inspect attributes of each path
IOS‑XRshow bgp ipv4 unicast 10.0.0.0/24 detailJunos
show route receive-protocol bgp 10.0.0.2 10.0.0.0/24 extensive -
Verify the route‑policy is active and matches the community
IOS‑XRshow route-policy SET-LOCAL-PREF-BY-COMMUNITY detailJunos
show policy policy-statement SET-LOCAL-PREF detail -
Check the rendered/applied config for the community‑setting line
IOS‑XRshow running-config route-policy SET-LOCAL-PREF-BY-COMMUNITYJunos
show configuration policy-options policy-statement SET-LOCAL-PREF -
If a mismatch is found, re‑apply the correct template or manually add the missing statement, then reset BGP
IOS‑XRclear bgp * softJunos
restart bgp
Following these steps isolates whether the problem lies in the intended policy, the rendered configuration, the applied state, or the observed forwarding decision, allowing rapid restoration of the backup path’s eligibility during failover.