Dual‑Transit Edge: How LocalPreference Overrides AS‑Path Length
Overview
A dual‑transit edge router runs two independent eBGP sessions—one to Transit‑A and one to Transit‑B. Each session advertises the full Internet table learned from its provider. The router’s BGP best‑path algorithm (RFC 4271) evaluates attributes in a fixed order:
- Weight (vendor‑specific)
- LOCAL_PREF
- Locally originated
- AS‑PATH length
- Origin type
- MED
- eBGP over iBGP 8. IGP metric to next‑hop
- Multipath
- Tie‑breakers (router ID, cluster‑list length)
Because LOCAL_PREF is checked before AS‑PATH, a higher local preference can deliberately win over a shorter AS path, giving operators a clean way to steer egress traffic.
LOCAL_PREF Attribute
- Well‑known, discretionary, exchanged only inside the AS (iBGP). * 32‑bit unsigned integer; higher value = more preferred.
- Default on Cisco IOS/IOS‑XR and Juniper JunOS = 100 for routes learned from eBGP peers unless overridden by inbound policy.
Path‑Selection Example
| Transit | AS_PATH (length) | LOCAL_PREF (inbound policy) |
|---|---|---|
| A | 65001 65010 (2) | 100 (default) |
| B | 65002 (1) | 200 (set via route‑map) |
Best‑path steps:
- Weight equal (0). 2. LOCAL_PREF: 200 > 100 → Transit‑B selected.
- AS‑PATH comparison never reached.
Thus the router forwards toward Transit‑B even though its AS_PATH is longer (or, conversely, despite Transit‑A having a shorter path but lower LOCAL_PREF).
Why Operators Misread the Outcome * Route‑map applied incorrectly – e.g., attached to the wrong address‑family or VRF, so the LOCAL_PREF change never reaches the BGP table.
- Policy not propagated – missing
next-hop-selfor route‑reflector misconfiguration leaves some iBGP peers seeing the default value. - CLI glance bias – operators read the AS_PATH column first and overlook the hidden LOCAL_PREF column unless explicitly requested.
Verifying the Decision with CLI
Cisco IOS/XR
show ip bgp 203.0.113.0/24
show ip route 203.0.113.0/24
show cef 203.0.113.0/24 detail
Juniper JunOS
show route protocol bgp 203.0.113.0/24 detail
show route 203.0.113.0/24
show route forwarding-table destination 203.0.113.0/24
Sample Cisco output
RP/0/RP0/CPU0:router#show ip bgp 203.0.113.0/24
BGP routing table entry for 203.0.113.0/24, version 42
Paths: (2 available, best #1, table default)
Not advertised to any peer
65002
10.0.0.2 from 10.0.0.2 (65002)
Origin IGP, localpref 200, valid, external, best
65001 65010
10.0.1.2 from 10.0.1.2 (65001)
Origin IGP, localpref 100, valid, external
Sample JunOS output
user@router> show route protocol bgp 203.0.113.0/24 detail
203.0.113.0/24 *[BGP/170] 00:05:12, localpref 200, from 10.0.0.2
AS path: 65002 I, validation-state: unverified
> to 10.0.0.2 via ge-0/0/0.0
*[BGP/170] 00:05:10, localpref 100, from 10.0.1.2
AS path: 65001 65010 I, validation-state: unverified
> to 10.0.1.2 via ge-0/0/1.0
The higher LOCAL_PREF wins despite the AS_PATH length.
Control‑Plane Checks to Confirm Intentional Egress
-
RIB verification – ensure the next‑hop points to the transit with the higher LOCAL_PREF.
show ip route 203.0.113.0/24 # IOS/XR show route 203.0.113.0/24 # JunOS -
BGP neighbor session & received routes – confirm the inbound policy is applied.
show ip bgp neighbors 10.0.0.2 received-routes # IOS/XR show bgp neighbor 10.0.0.2 received-routes # JunOS ``` -
Route‑map / policy inspection – verify the LOCAL_PREF setting and its attachment.
show route-map LOCAL_PREF_IN # IOS/XR show configuration policy-options policy-statement LOCAL_PREF_IN # JunOS ``` *Check:* - `neighbor x.x.x.x route-map LOCAL_PREF_IN in` (or `import LOCAL_PREF_IN;` in JunOS). - The route‑map contains `set local-preference 200` (or `local-preference 200;`). - No later policy overwrites the value.
Configuration Examples
Cisco IOS‑XR
route-map LOCAL_PREF_IN permit 10
set local-preference 200
!
router bgp 65000
neighbor 10.0.0.2 remote-as 65002
address-family ipv4 unicast
route-map LOCAL_PREF_IN in
!
neighbor 10.0.1.2 remote-as 65001
address-family ipv4 unicast
# no explicit route‑map → inherits default LOCAL_PREF 100```
#### Juniper JunOS
```bash
policy-options {
policy-statement LOCAL_PREF_IN {
term set-pref {
then {
local-preference 200;
accept;
}
}
}
}
protocols {
bgp {
group transit {
type external;
neighbor 10.0.0.2 {
peer-as 65002;
import LOCAL_PREF_IN;
}
neighbor 10.0.1.2 {
peer-as 65001;
# no import policy → default local-preference 100
}
}
}
}
(Optional outbound community or default‑originate policies omitted for brevity.)
Post‑Commit Validation
IOS‑XR
show run router bgp | include neighbor 10.0.0.2
show bgp neighbors 10.0.0.2 received-routes | include 203.0.113.0/24
show ip bgp 203.0.113.0/24
show ip route 203.0.113.0/24
show cef 203.0.113.0/24 detail
JunOS
show configuration protocols bgp group transit neighbor 10.0.0.2
show route receive-protocol bgp 10.0.0.2 203.0.113.0/24 detail
show route protocol bgp 203.0.113.0/24 detail
show route 203.0.113.0/24
show route forwarding-table destination 203.0.113.0/24
If the output displays LOCAL_PREF 200 and the next‑hop points to the preferred transit, the control‑plane intent is confirmed.
Scaling Considerations
- AS_PATH influence – only consulted when LOCAL_PREF, weight, and locally‑originated are equal. In a primary/secondary design where LOCAL_PREF differs, AS_PATH variations have no effect on the chosen path.
- Session growth – each additional transit adds a BGP peer; memory use scales with prefixes received. Use
maximum-prefixlimits and, if needed, route‑reflector clusters or add‑paths to reduce iBGP mesh overhead. - RIB/FIB pressure – the RIB temporarily holds two copies of each prefix until the best‑path decision is made; the FIB stores only the selected path. Monitoring prefix counts and enabling BGP dampening can help maintain stability in large‑scale deployments.
By correctly setting and verifying LOCAL_PREF, operators can reliably steer egress traffic in a dual‑transit edge, avoiding the common pitfall of assuming a shorter AS_PATH always wins.