Skip to main content
RunBook Academy

VyOSXXVI · BGP AttributesAttributes

Local preference — the iBGP outbound path selector

Advanced⏱ ~24 minvyosvtyshshow ip bgpshow ip bgp neighborsshow ip bgp regexpshow configuration commands

What you'll learn

  • Configure `set policy route-map ... set local-preference` to influence outbound path
  • Explain why local preference is well-known discretionary and iBGP-only
  • Set local preference per-peer via neighbour route-map
  • Diagnose why a higher local preference is being ignored (outbound path still wrong)

Prerequisites

Verified against VyOS 1.5.x LTS (circinus) · VyOS 1.4.x (sagitta) — legacy · FRRouting 10.x (VyOS 1.5) · Linux kernel 6.6 LTS (VyOS 1.5 base) · strongSwan 5.9.x (IPsec) · WireGuard 1.0.x (kernel module + userspace tooling)

Not yet marked complete on this device.

BGP local preference is the operator’s tool for outbound path selection within an AS. It tells every iBGP router in the local AS: “use this path to reach the destination”. On VyOS 1.5 LTS / FRR 10.x, the configuration is set policy route-map ... set local-preference <0-4294967295>, applied via a neighbour’s inbound route-map.

This lesson is the operator’s reference for local preference: the well-known discretionary classification, the iBGP-only propagation rule, the route-map configuration, and how it fails in production.

What local preference does

LOCAL_PREF is a BGP attribute carried in UPDATE messages between iBGP peers. It is one of the four “well-known” attributes defined by RFC 4271, and one of the two “discretionary” ones (the BGP speaker is not required to recognise it, but every BGP implementation does).

The attribute’s value is a 32-bit unsigned integer. Higher values are preferred. The default is 100 (every BGP speaker assumes a default if the attribute is absent).

flowchart LR
  subgraph "AS 64512"
    R1["R1\n(inbound from eBGP)"]
    R2["R2\n(inbound from eBGP)"]
    R3["R3\n(iBGP)"]
    R4["R4\n(iBGP)"]
  end
  subgraph "AS 64513"
    P1["Provider A"]
  end
  subgraph "AS 64514"
    P2["Provider B"]
  end
  R1 -- "eBGP\nLOCAL_PREF: 200" --> P1
  R2 -- "eBGP\nLOCAL_PREF: 100" --> P2
  R1 -- "iBGP\ncarries LOCAL_PREF" --> R3
  R1 -- "iBGP\ncarries LOCAL_PREF" --> R4
  R2 -- "iBGP\ncarries LOCAL_PREF" --> R3
  R2 -- "iBGP\ncarries LOCAL_PREF" --> R4
  R3 -- "best path: R1 (LOCAL_PREF 200)" --> R3
  R4 -- "best path: R1 (LOCAL_PREF 200)" --> R4

When R3 and R4 have two paths to a destination (one via R1, one via R2), the path with the higher LOCAL_PREF wins. R3 and R4 both send their outbound traffic via R1.

The attribute is iBGP-only: it is carried in UPDATE messages between iBGP peers (routers in the same AS), but stripped when sending to eBGP peers (routers in different ASes). This is a protocol invariant — receiving routers in the remote AS cannot be told what the local AS’s preference is. The receiving eBGP peer cannot “see” the local AS’s LOCAL_PREF.

The VyOS configuration

The local preference is set via a route-map applied to the neighbour’s inbound direction (the path entering the local AS from the eBGP peer).

# Define the route-map
set policy route-map FROM-PROVIDER-A rule 10 action permit
set policy route-map FROM-PROVIDER-A rule 10 set local-preference 200

set policy route-map FROM-PROVIDER-B rule 10 action permit
set policy route-map FROM-PROVIDER-B rule 10 set local-preference 100

# Apply to the eBGP neighbours
set protocols bgp system-as 64512

set protocols bgp neighbor 10.0.0.1 remote-as 64513
set protocols bgp neighbor 10.0.0.1 address-family ipv4-unicast route-map import FROM-PROVIDER-A

set protocols bgp neighbor 10.0.0.2 remote-as 64514
set protocols bgp neighbor 10.0.0.2 address-family ipv4-unicast route-map import FROM-PROVIDER-B

commit
save

Three things about the neighbour lines are worth stating plainly, because they are where a configuration written for VyOS 1.3 stops working on 1.5. The local ASN is now the system-as leaf rather than a level of the tree. Peers hang off set protocols bgp neighbor <address> with no ASN in the path. And the policy is attached under the address family as route-map import <name> — the peer-level route-map NAME import spelling is gone, which matters because a peer can carry different policy for IPv4 and IPv6 and the old spelling had nowhere to say which.

The import direction is the route-map applied to routes received from the peer. The set local-preference 200 rewrites the LOCAL_PREF attribute on every route that matches the route-map’s permit rule.

After commit, every iBGP peer in AS 64512 sees:

  • Routes from Provider A with LOCAL_PREF 200
  • Routes from Provider B with LOCAL_PREF 100

When an iBGP router (R3 or R4) runs the best-path algorithm, it picks the path with LOCAL_PREF 200 (Provider A) as the best path.

vyos@r3:~$ show ip bgp 8.8.8.0/24

BGP routing table entry for 8.8.8.0/24
Paths: (2 available, best #1, table default)
  Advertised to non peer-group peers:
    ...
  64513 15169
    10.0.0.1 from 10.0.0.1 (10.0.0.1)
      Origin IGP, localpref 200, valid, external, best
      ...
  64514 15169
    10.0.0.2 from 10.0.0.2 (10.0.0.2)
      Origin IGP, localpref 100, valid, external
      ...

The localpref 200 and localpref 100 columns show the LOCAL_PREF values. The best flag is on the path with the higher LOCAL_PREF.

The default of 100

If a route enters the AS without an explicit LOCAL_PREF configuration, the default is 100. This applies:

  • When a route enters via an eBGP peer with no inbound route-map setting local preference.
  • When a route is locally originated (via network or redistribution) — the default is 100.

The default of 100 is the reason most operators set LOCAL_PREF explicitly. Setting one peer’s LOCAL_PREF to 200 (preferred) and leaving the other at 100 (default) creates an asymmetry: the 200 peer is always preferred. Setting the less preferred peer to a value lower than 100 (e.g. 50) makes the asymmetry explicit but the result is the same.

Local preference vs weight

BGP has two “preference” attributes: LOCAL_PREF (interior) and weight (per-router). The order in the best-path algorithm:

  1. Weight (Cisco-proprietary, also in FRR) — higher wins. Local to the router. Not propagated.
  2. LOCAL_PREF — higher wins. Propagated through iBGP.
  3. Locally originated — preferred over learned.
  4. AS-path length — shorter wins.
  5. Origin — IGP < EGP < incomplete.
  6. MED — lower wins.
  7. eBGP over iBGP.
  8. IGP cost to next-hop — lower wins.
  9. Router-id — lower wins.
  10. Cluster-list length, neighbour address.

The two attributes solve different problems:

  • Weight is for “this specific router should prefer X”. It does not propagate; it does not influence other routers in the AS.
  • LOCAL_PREF is for “the entire AS should prefer X”. It propagates through iBGP; every iBGP router sees the same value.
flowchart TB
  subgraph "AS 64512"
    R1["R1\nweight: 0 (default)\nLOCAL_PREF: 200\n(preferred outbound)"]
    R2["R2\nweight: 0 (default)\nLOCAL_PREF: 200\n(preferred outbound)"]
    R3["R3\nweight: 5000 (override)\nLOCAL_PREF: 200\n(R3 prefers differently)"]
  end
  R1 -- "iBGP\nLOCAL_PREF: 200" --> R3
  R2 -- "iBGP\nLOCAL_PREF: 200" --> R3
  R3 -- "weight: 5000 overrides LOCAL_PREF 200" --> R3

Weight is checked before LOCAL_PREF. If R3 has weight 5000 on a route, R3 prefers that route regardless of LOCAL_PREF. The other iBGP peers (R1, R2) still use LOCAL_PREF 200.

Filtering by prefix or community

The route-map that sets LOCAL_PREF can also filter which prefixes receive the LOCAL_PREF:

set policy prefix-list PREFER-A-ROUTES rule 10 action permit
set policy prefix-list PREFER-A-ROUTES rule 10 prefix 198.51.100.0/24
set policy prefix-list PREFER-A-ROUTES rule 20 action deny

set policy route-map FROM-PROVIDER-A rule 10 action permit
set policy route-map FROM-PROVIDER-A rule 10 match ip address prefix-list PREFER-A-ROUTES
set policy route-map FROM-PROVIDER-A rule 10 set local-preference 200

set policy route-map FROM-PROVIDER-A rule 20 action permit

This configuration sets LOCAL_PREF 200 only for the prefix 198.51.100.0/24 from Provider A. Other prefixes from Provider A are passed through with the default LOCAL_PREF 100.

The rule 20 with action permit and no set is a no-op — it permits the route but does not change LOCAL_PREF. The route keeps its default.

A common production pattern: prefer Provider A for traffic destined to one set of prefixes (e.g. North America), Provider B for another set (e.g. Europe):

set policy route-map FROM-PROVIDER-A rule 10 action permit
set policy route-map FROM-PROVIDER-A rule 10 match ip address prefix-list NA-ROUTES
set policy route-map FROM-PROVIDER-A rule 10 set local-preference 200

set policy route-map FROM-PROVIDER-A rule 20 action permit
set policy route-map FROM-PROVIDER-A rule 20 match ip address prefix-list EU-ROUTES
set policy route-map FROM-PROVIDER-A rule 20 set local-preference 50

The EU-ROUTES rule explicitly sets LOCAL_PREF to 50 (less than the default 100), so Provider B is preferred for European destinations.

Validation

# 1. The route-map exists and says what you think it says
show configuration commands | match FROM-PROVIDER-A
vtysh -c 'show route-map FROM-PROVIDER-A'

# 2. The peer has it bound inbound
show ip bgp neighbors 10.0.0.1
# Read the policy lines: "Route map for incoming advertisements is *FROM-PROVIDER-A*"

# 3. The LOCAL_PREF is set on the received routes
show ip bgp 8.8.8.0/24
# Expected: localpref 200 on the path from 10.0.0.1

# 4. The best path is the one with the higher LOCAL_PREF
show ip bgp 8.8.8.0/24 bestpath

Step 2 is the one to be careful about. There is no show ip bgp neighbors <ip> route-map command — the binding is reported inside the ordinary show ip bgp neighbors <ip> output, in the block that names the inbound and outbound policy. Reading that block is how you tell “the route-map is not applied” from “the route-map is applied and does not match”, which are the two halves of nearly every local-preference incident.

For a comprehensive view of LOCAL_PREF across the paths from one origin AS:

Read-only / SafeLOCAL_PREF across paths from one origin AS
vyos@r3:~$ show ip bgp regexp _15169$
BGP table version is 12345, local router ID is 10.255.0.3, vrf id 0
Default local pref 100, local AS 64512
Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
             i internal, r RIB-failure, S Stale, R Removed
Origin codes:  i - IGP, e - EGP, ? - incomplete

 Network          Next Hop            Metric LocPrf Weight Path
*>i8.8.8.0/24       10.0.0.1                 0    200      0 64513 15169 i
* i                 10.0.0.2                 0    100      0 64514 15169 i

Illustrative output

Read three things here. The LocPrf column carries the values the route-maps set. The leading i on both rows says these paths reached R3 over iBGP, which is the whole point — the attribute survived the internal hop. And *> marks the best path, on the row with 200.

Note also that show ip bgp regexp filters on the AS path, not on the prefix: _15169$ means “paths originated by AS 15169”. A regex written as though it were a prefix filter matches nothing and looks like an empty table.

Failure modes

Local preference is set but the path is not preferred

The route-map sets LOCAL_PREF 200 on Provider A’s routes, but the best-path algorithm picks Provider B’s path with LOCAL_PREF 100.

Diagnostic:

  1. Is the route-map applied? show ip bgp neighbors 10.0.0.1 and read the policy block, which names the inbound and outbound route-maps. A peer with no inbound policy simply does not print one.
  2. Is the LOCAL_PREF set on the received routes? Run show ip bgp 8.8.8.0/24 and look for localpref 200 on the path from Provider A.
  3. Is the route-map’s match clause matching? vtysh -c 'show route-map FROM-PROVIDER-A' prints the rendered rules and a per-rule match counter. A rule with a zero counter is not matching, which is a different problem from a rule that is missing.
  4. Is the prefix being filtered out by the route-map? The route-map may have a deny rule that matches the prefix before the permit rule with set local-preference.

Local preference is set but iBGP peers do not honour it

The iBGP peer sees LOCAL_PREF 200 in the UPDATE but picks a different path.

Diagnostic:

  • The iBGP peer has its own weight setting that overrides LOCAL_PREF. show ip bgp <prefix> on the iBGP peer; look for non-zero weight.
  • The iBGP peer has its own inbound route-map that rewrites LOCAL_PREF. show ip bgp neighbors 10.255.0.1 on that peer and read its policy block.
  • The iBGP peer does not have a route to the next-hop (RIB-failure).

Inbound route-map is not in place

The operator set up the route-map but forgot to apply it to the neighbour. The route-map exists in the policy configuration but is not bound to a neighbour.

Diagnostic:

  • show configuration commands | match FROM-PROVIDER-A — the policy exists, and the output shows no protocols bgp line referencing it.
  • show ip bgp neighbors 10.0.0.1 — no inbound policy named.

The fix:

set protocols bgp neighbor 10.0.0.1 address-family ipv4-unicast route-map import FROM-PROVIDER-A

A route-map that is defined but bound to nothing is one of the quietest faults in BGP: it commits cleanly, it shows up in the configuration, and it does nothing at all.

The route-map is applied in the wrong direction

The operator applied the route-map outbound instead of inbound. The outbound route-map is for advertising, not for receiving. LOCAL_PREF is set on receipt, not on sending.

Diagnostic: show ip bgp neighbors 10.0.0.1 names the route-map as the policy for outgoing advertisements rather than incoming ones.

The fix:

delete protocols bgp neighbor 10.0.0.1 address-family ipv4-unicast route-map export
set protocols bgp neighbor 10.0.0.1 address-family ipv4-unicast route-map import FROM-PROVIDER-A

Rollback

# Remove the route-map from the neighbour
delete protocols bgp neighbor 10.0.0.1 address-family ipv4-unicast route-map import
commit

# Or remove the local-preference setting from the route-map
delete policy route-map FROM-PROVIDER-A rule 10 set local-preference
commit

The rollback for a misconfigured LOCAL_PREF is straightforward: remove the route-map from the neighbour, and the routes return to the default LOCAL_PREF 100. The iBGP peers will see the change and re-run the best-path algorithm.

For a planned rollback:

  1. Capture the before state (show ip bgp <prefix>).
  2. Remove the route-map.
  3. Verify the after state (LOCAL_PREF back to 100, best path may change).

Production discipline

Cross-course references

  • Part XXV (XXV-VyOS-BGPAdvertise) covers the origination primitives that produce routes in the BGP table; LOCAL_PREF acts on these routes after they arrive.
  • Part XXVI-02 (XXVI-VyOS-BGPAttributes / AS path) covers the next attribute in the best-path algorithm.
  • Part XXVII (XXVII-VyOS-BGPBestPath) covers the best-path algorithm in full, including the tie-breakers after LOCAL_PREF.
  • Part XXXIII (XXXIII-VyOS-RoutePolicy) covers the route-map primitives used here.
  • Part XXXIX (XXXIX-VyOS-MultiWAN) covers the multi-WAN use case where LOCAL_PREF is the primary tool.

Quiz

Knowledge check · 4 questions

  1. Q1. A route enters AS 64512 from an eBGP peer with no inbound route-map. What is the LOCAL_PREF of the route?

  2. Q2. BGP LOCAL_PREF is sent on eBGP sessions and stripped on iBGP sessions.

  3. Q3. R3 (an iBGP router in AS 64512) receives a route from R1 with LOCAL_PREF 200 (preferred). R3 has weight 5000 on the same route from R2 (which has LOCAL_PREF 100). Which path does R3 select as best?

    R3 has: - iBGP session to R1 (carrying LOCAL_PREF 200 on the route) - iBGP session to R2 (carrying LOCAL_PREF 100 on the route) R3 also has a forgotten weight configuration: set protocols bgp neighbor 10.0.0.2 address-family ipv4-unicast route-map import WEIGHT-OVERRIDE set policy route-map WEIGHT-OVERRIDE rule 10 action permit set policy route-map WEIGHT-OVERRIDE rule 10 set weight 5000

  4. Q4. R1 configures `set protocols bgp neighbor 10.0.0.1 address-family ipv4-unicast route-map export FROM-PROVIDER-A` and expects the LOCAL_PREF 200 setting on that route-map to influence outbound path selection within AS 64512. Why does this not work?

    R1's route-map: set policy route-map FROM-PROVIDER-A rule 10 action permit set policy route-map FROM-PROVIDER-A rule 10 set local-preference 200 R1's neighbour: set protocols bgp neighbor 10.0.0.1 address-family ipv4-unicast route-map export FROM-PROVIDER-A 10.0.0.1 is the eBGP peer (Provider A).

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