Capstone: Engineer a Dual-Homed Edge
From a blank-slate edge router, engineer both outbound (LOCAL_PREF) and inbound (AS_PATH prepend) traffic so a dual-homed AS prefers one upstream over the other.
Download the lab (topology + configs), unzip it, then from that folder run containerlab deploy -t topology.clab.yml.
Capstone: Engineer a Dual-Homed Edge
You run AS 65001. You bought two upstream links: one to a primary provider (upstream A) and one to a backup (upstream B). Both can reach the internet. Both work. But you are paying for the primary and you want it used, in both directions: traffic you send out and traffic the world sends back to you should ride the primary, with the backup sitting idle until the primary fails.
Here is the catch that trips up every new operator: outbound and inbound are two completely different problems. You control which way packets leave with LOCAL_PREF, a knob that lives entirely inside your AS. You do not control which way the world sends packets back, because that decision happens in other people's routers. The only lever you have on inbound is what you advertise, so you make the backup path look worse by prepending your own AS to it. This capstone makes you wire up both.
Topology
Your edge router r1 is a blank slate: it has interface and loopback addressing and nothing else. The two upstreams (r2, r3) and the internet (r4) are already configured and running; you do not touch them. r4 originates a single destination prefix, 100.64.0.0/24, and hears your 1.1.1.1/32 back through whichever upstream advertises it.
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 four routers. Drop into your edge router r1:
docker exec -it clab-bgp-path-selection-capstone-r1 vtyshYou can open the upstreams and the internet the same way to inspect them, but you only configure r1:
docker exec -it clab-bgp-path-selection-capstone-r2 vtysh
docker exec -it clab-bgp-path-selection-capstone-r4 vtyshYour mission
Configure only r1 so that:
- It runs eBGP to both upstreams:
remote-as 65002toward A (10.0.12.2) andremote-as 65003toward B (10.0.13.3). - It advertises your prefix
1.1.1.1/32into BGP so the world can reach you. - OUTBOUND, your best path to
100.64.0.0/24prefers upstream A, by raisingLOCAL_PREFon the routes you learn from A. - INBOUND, the world's best path back to
1.1.1.1/32prefers upstream A, by prepending your own AS on the routes you advertise toward B so that path looks longer.
Set no bgp ebgp-requires-policy so RFC 8212 does not silently filter your eBGP routes.
Objectives
- ✅ Outbound:
r1's best path to100.64.0.0/24is via the primary, AS_PATH65002 65004. - ✅ Inbound:
r4's best path back to1.1.1.1/32is via the primary, AS_PATH65002 65001. - ✅ The eBGP session from
r1to the primary10.0.12.2is Established.
Hints
Terse nudges only. This is your proof, so reach for these only when stuck.
- Outbound is LOCAL_PREF. Higher wins, and it is the first real tiebreaker. Set it with an inbound route-map on the session toward the preferred upstream (A).
- Inbound is AS_PATH. You cannot set LOCAL_PREF in someone else's router. Make the backup path look longer with
set as-path prependon an outbound route-map toward the non-preferred upstream (B). - Verify inbound from r4, not r1. The whole point is that the far end picks A. Check
show ip bgp 1.1.1.1/32onr4and read the AS_PATH it chose.
Verify
On your edge r1, confirm both sessions are up and that outbound prefers A:
The best path to 100.64.0.0/24 should carry AS_PATH 65002 65004 (through A), not 65003 65004 (through B). Then check inbound from the internet's point of view on r4:
docker exec -it clab-bgp-path-selection-capstone-r4 vtyshr4 should pick the path with AS_PATH 65002 65001 (through A). The path through B now reads 65003 65001 65001 65001, longer because of your prepend, so r4 rejects it.
Tear down
containerlab destroy -t topology.clab.ymlWhat you learned
- Outbound and inbound are separate engineering problems with separate tools. One config file, two policies, two directions.
LOCAL_PREFsteers outbound and stays inside your AS. It is applied inbound (on routes you receive) on the session toward your preferred upstream, and higher wins.- AS_PATH prepend steers inbound, the only practical lever you have on traffic other people send you. It is applied outbound (on routes you advertise) toward the upstream you want the world to avoid, making that path look longer.
- A route-map is directional:
... inshapes what you accept,... outshapes what you announce. Picking the wrong direction is the classic dual-homing mistake.
Next: you steered whole prefixes; now learn to match specific prefixes with bgp-prefix-lists.
Objectives
0/3 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.
Outbound: r1's best path to 100.64.0.0/24 goes via the PRIMARY (upstream A), AS_PATH 65002 65004.
$ docker exec -it clab-bgp-path-selection-capstone-r1 vtysh -c 'show ip bgp 100.64.0.0/24'Inbound: r4's best path to 1.1.1.1/32 comes back via the PRIMARY (upstream A), AS_PATH 65002 65001.
$ docker exec -it clab-bgp-path-selection-capstone-r4 vtysh -c 'show ip bgp 1.1.1.1/32'The eBGP session from r1 to the PRIMARY (10.0.12.2) reaches the Established state.
$ docker exec -it clab-bgp-path-selection-capstone-r1 vtysh -c 'show ip bgp summary'