BGP does not balance load and it does not measure link quality. For each prefix it elects exactly one best path by walking an ordered list of tie-breakers, installing that path, and advertising only that path to peers. Policy in BGP is the art of arranging for the right path to win this election, and the list is worth memorising in order — a higher step always beats everything below it.
The decision order (Cisco)
- 1. Highest weight — Cisco-proprietary, local to the router, never advertised. A per-neighbour sledgehammer for local decisions.
- 2. Highest local preference — shared across the whole AS via iBGP (default 100). The standard tool for 'all traffic to this prefix leaves via the primary ISP'.
- 3. Locally originated — routes this router injected itself (network, aggregate, redistribute) beat learned ones.
- 4. Shortest AS-path — the famous one; each AS in the path counts as one, which is why prepending your own AS three times makes a path look three ASes worse.
- 5. Lowest origin code — IGP (i) beats incomplete (?); a fossil, but still in the list.
- 6. Lowest MED — the multi-exit discriminator, a suggestion to a neighbouring AS about which of several links into your AS to prefer; compared by default only between paths from the same AS.
- 7. eBGP over iBGP — leave the AS at the nearest edge rather than crossing it to another exit.
- 8. Lowest IGP metric to next hop — among what remains, the exit this router can reach most cheaply: hot-potato routing.
- 9. Oldest eBGP path — stability bias: don't move traffic because a newer, equal path appeared.
- 10. Lowest router ID; 11. lowest neighbour address — deterministic final tie-breaks.
The practical mapping
Outbound traffic (which way do my packets leave?) is controlled by what you do to routes you receive: set weight for one-router decisions, set local preference in an inbound route map for AS-wide decisions. Inbound traffic (which way do packets reach me?) is controlled by what you advertise: prepend the AS-path toward the ISP you want less traffic from, or send MED — remembering that the remote AS's local preference outranks anything you send, so inbound engineering is negotiation, not command.
R1(config)# route-map FROM-ISP-A permit 10R1(config-route-map)# set local-preference 200R1(config)# route-map PREPEND-TO-ISP-B permit 10R1(config-route-map)# set as-path prepend 65001 65001 65001R1(config-router)# neighbor 203.0.113.2 route-map FROM-ISP-A inR1(config-router)# neighbor 198.51.100.2 route-map PREPEND-TO-ISP-B out
Reading the table
R1# show bgp ipv4 unicast 172.16.0.0/16Paths: (2 available, best #1) 65002 64500 203.0.113.2 from 203.0.113.2 (2.2.2.2) Origin IGP, localpref 200, valid, external, best 65003 64500 198.51.100.2 from 198.51.100.2 (3.3.3.3) Origin IGP, metric 0, localpref 100, valid, external
The output narrates the algorithm: both paths are valid, both external, AS-path lengths equal — and localpref 200 beats 100 at step two, so path #1 is best and nothing below step two was even consulted. One caveat closes the chapter: before any of the eleven steps, a path must be valid, which above all means the next hop must be resolvable in the routing table. Half of all 'BGP learned the route but won't use it' tickets are next-hop reachability, not path selection.