Steer Outbound Traffic with LOCAL_PREF
Raise LOCAL_PREF on routes from a preferred upstream to steer your AS's outbound traffic onto it.
Download the lab (topology + configs), unzip it, then from that folder run containerlab deploy -t topology.clab.yml.
Steer Outbound Traffic with LOCAL_PREF
Your AS is dual-homed: two upstreams, two cables, two ways out to the internet. That's great for resilience, but it raises a question you now get to answer: when both upstreams can reach the same destination, which one does your traffic actually leave through?
Right now BGP is picking for you, quietly, with a tie-breaker you didn't choose. In this lab you'll take the wheel. You have two upstreams, r2 (AS 65002, call it upstream A) and r3 (AS 65003, upstream B), and both advertise the very same prefix 100.64.0.0/24. You'll make every packet your AS sends toward that prefix leave via upstream A, using the single most important outbound lever in BGP: LOCAL_PREF.
Topology
The two eBGP sessions are already up and routes are already flowing; that part is pre-staged. The decision of which exit to use is the part you'll build.
Deploy the lab
Download the lab and unzip it (the download includes the topology and the router configs). From inside the unzipped folder, run:
containerlab deploy -t topology.clab.ymlThat boots all three routers. Drop into r1's FRR shell:
docker exec -it clab-bgp-influence-local-pref-r1 vtyshStep 1: Observe the default choice
On r1, look at how BGP sees 100.64.0.0/24:
You should see two paths for the prefix: one learned from 10.0.12.2 (upstream A, AS 65002) and one from 10.0.13.3 (upstream B, AS 65003). Exactly one is marked best (with a >). Both AS_PATHs are the same length (a single hop), the metrics match, and LOCAL_PREF is the default 100 on both. With everything else tied, BGP falls through to a low-level tie-breaker (such as the lower neighbor router-id or peer address) to pick the winner.
That works, but it is arbitrary. You did not choose it, and it could flip if a router-id changes. Let's make the choice explicit and intentional.
Step 2: Prefer upstream A with LOCAL_PREF
LOCAL_PREF is checked very early in the best-path algorithm, before AS_PATH length, and the rule is simple: higher LOCAL_PREF wins. It is also AS-wide: it is the one attribute every router inside your AS agrees on, which makes it the natural lever for "everyone in my AS, please exit this way."
You set it with an inbound route-map on the neighbor whose routes you want to prefer. Apply it to upstream A (10.0.12.2):
Policy changes are not applied retroactively to routes already in the table, so nudge BGP to re-evaluate what it learned from the neighbor:
(A soft inbound reset, clear ip bgp * soft in, does the same job without tearing the sessions down. clear ip bgp * is fine in a lab.)
Step 3: Verify the best path moved
Give it a couple of seconds, then look again:
The path via 10.0.12.2 (upstream A) should now carry LocPrf 200 and be marked best (>), while the path via 10.0.13.3 still shows the default 100. Because 200 beats 100, the algorithm stops right there and never even gets to the AS_PATH comparison. Your AS now sends all traffic for 100.64.0.0/24 out through upstream A.
✅ Objective 1: r1 learns 100.64.0.0/24 from both upstreams (two paths in the table).
✅ Objective 2: r1's best path for 100.64.0.0/24 is via upstream A (10.0.12.2, AS 65002), chosen by the higher LOCAL_PREF.
Troubleshooting
- Best path did not move? Confirm the route-map is applied inbound (
... route-map PREFER-UPSTREAM-A in) on the r2 neighbor, not r3, and that you ranclear ip bgp *(orclear ip bgp * soft in) afterward. Without the clear, the old route stays in the table at LocPrf 100. - Remember the direction of the rule: higher LOCAL_PREF wins. Setting it to something lower than 100 would steer traffic to the other upstream.
- Only one path showing? A session may be down. Check
show ip bgp summaryfor two Established neighbors, and thatno bgp ebgp-requires-policyis present so routes are exchanged. - Route-map has no effect at all? A route-map with a
permitclause and asetbut nomatchapplies thesetto every route, which is what you want here. If you added amatchthat nothing matches, thesetnever fires.
Tear down
containerlab destroy -t topology.clab.ymlWhat you learned
- When two upstreams advertise the same prefix, BGP picks one exit, and without policy it leans on an arbitrary tie-breaker.
- LOCAL_PREF is the AS-wide lever for outbound traffic engineering: it is compared early in best-path selection and higher wins.
- You set it with an inbound route-map on the preferred neighbor (
set local-preference 200), then re-evaluate routes with a clear or soft reset. - LOCAL_PREF stays inside your AS (it is never sent to eBGP peers), which is exactly why it can make your whole AS agree on one exit.
Next: influence the traffic coming back to you, and lengthen an AS_PATH to make a path look worse on purpose, in bgp-as-path-prepend.
Objectives
0/2 verifiedRun each command against your running lab, confirm what you see, and tick it off. Self-assessed for now; a hosted auto-grader will check these for you later.
r1 learns 100.64.0.0/24 from both upstreams (two paths in the BGP table).
$ docker exec -it clab-bgp-influence-local-pref-r1 vtysh -c 'show ip bgp 100.64.0.0/24'r1's best path for 100.64.0.0/24 is via upstream A (r2, AS 65002), chosen by LOCAL_PREF.
$ docker exec -it clab-bgp-influence-local-pref-r1 vtysh -c 'show ip bgp 100.64.0.0/24'