72. BGP in depth: attributes and path selection
72.1 The model
BGP-4 (RFC 4271) connects ~75,000 autonomous systems. It is a path-vector protocol: advertisements carry the full list of ASes traversed.
Runs over TCP port 179 (so it inherits TCP reliability, and needs
IP reachability BEFORE it can peer)
eBGP between different ASes -- usually directly connected, TTL 1 by default
iBGP within one AS -- carries external routes across your network;
peers are often multiple hops apart
The iBGP full-mesh rule: a route learned from one iBGP peer is not
re-advertised to another iBGP peer (that's how BGP prevents internal loops).
Therefore every iBGP speaker must peer with every other — n(n-1)/2 sessions —
unless you use route reflectors or confederations (§73.2).
72.2 The best-path selection algorithm
When BGP has several paths to a prefix, it walks this list and stops at the first tiebreak. Memorise the first four; the rest are rare.
0. Prefer the path with a reachable NEXT_HOP (if not reachable, discard)
1. Highest WEIGHT (Cisco-proprietary, LOCAL to one router)
2. Highest LOCAL_PREF (iBGP-wide; THE knob for choosing outbound)
3. Locally originated (network / redistribute / aggregate)
4. Shortest AS_PATH (the famous one -- but it is only #4)
5. Lowest ORIGIN (IGP < EGP < Incomplete)
6. Lowest MED (a hint TO a neighbour about inbound; only
compared between paths from the SAME AS
by default)
7. eBGP over iBGP
8. Lowest IGP metric to the next hop
9. Oldest path (stability)
10. Lowest neighbour Router ID
11. Lowest neighbour IP address
The crucial insight: LOCAL_PREF (step 2) beats AS_PATH (step 4). Policy
beats topology. The internet's shape is commercial, not geographic — which is why
your packets sometimes cross a continent to reach a server two miles away.
72.3 The attributes that matter
| Attribute | Type | Direction | Use |
|---|---|---|---|
| NEXT_HOP | well-known mandatory | — | Where to send the packet. On iBGP it is not rewritten by default → the classic "route is in the table but unusable" problem. Fix: next-hop-self. |
| AS_PATH | well-known mandatory | outbound signal | Loop detection (reject any path containing my own ASN) and path length. AS-path prepending artificially lengthens it to make a path less attractive — the standard way to influence inbound traffic. |
| LOCAL_PREF | well-known discretionary | iBGP only, internal | Choose which exit your traffic uses. Higher wins. Default 100. |
| MED (MULTI_EXIT_DISC) | optional non-transitive | to a neighbour AS | "If you have two links to me, prefer this one." Lower wins. A hint your neighbour may ignore. |
| ORIGIN | well-known mandatory | — | How the route entered BGP: IGP(i) < EGP(e) < Incomplete(?) |
| COMMUNITIES | optional transitive | tagging | 32-bit tags (64512:100) used to signal policy: "don't advertise to peers", "prepend twice in Europe", "blackhole this". Large communities (RFC 8092) extend this to 96 bits for 4-byte ASNs. |
| ATOMIC_AGGREGATE / AGGREGATOR | — | — | Marks that summarisation lost detail |
Well-known communities you should recognise:
NO_EXPORT (don't send outside this AS), NO_ADVERTISE (don't send to anyone),
NO_EXPORT_SUBCONFED, and the widely-implemented blackhole community
65535:666 (RFC 7999) — "drop all traffic to this prefix", used for DDoS
mitigation (Ch. 54.2).
72.4 Influencing traffic: the asymmetry
OUTBOUND traffic (yours leaving) -> YOU control it, easily
set LOCAL_PREF on routes learned from each provider
INBOUND traffic (coming to you) -> you can only HINT
* AS-path prepending (make one path look longer)
* MED (only works between two links to the SAME neighbour)
* communities your provider publishes (best method -- ask them)
* advertise MORE-SPECIFIC prefixes out one link (blunt but effective,
because longest-prefix match beats every BGP attribute)
Nothing you do guarantees inbound path selection — the remote network's own
LOCAL_PREF beats your prepending every time. This asymmetry is the root of most
multihoming frustration.
72.5 Real-world example
A company multihomed to two ISPs and prepended its ASN three times toward the
more expensive one, expecting traffic to shift. Nothing changed: a major content
network had a LOCAL_PREF policy preferring that ISP as a settlement-free peer,
and LOCAL_PREF is evaluated at step 2 — long before AS_PATH at step 4. The fix
was to use the ISP's published community for "de-prefer this route toward your
peers", which acts on the remote side's LOCAL_PREF.
Try it yourself
# public looking glasses show real BGP tables
# https://lg.he.net or https://stat.ripe.net
curl -s "https://stat.ripe.net/data/routing-status/data.json?resource=8.8.8.0/24" | python3 -m json.tool | head -40
whois -h whois.radb.net -- '-i origin AS15169' | grep -c '^route:' # prefixes an AS originates
traceroute -A 1.1.1.1 # -A annotates each hop with its ASN
# in FRR
sudo vtysh -c 'show bgp ipv4 unicast 8.8.8.0/24' # all paths + why one was chosen
sudo vtysh -c 'show bgp summary'