eBGP
Lessons (6, study in order)
Lesson 1 - What BGP is actually for
Basics · about 8 min
Goal: First get clear on the fact that BGP and OSPF aren't even the same kind of thing, or everything after this becomes rote memorization.
OSPF solves "what's the fastest way", BGP solves "should I even go"
IGPs like OSPF / ISIS care about the shortest path. They assume the whole network is friendly territory, and every link's information is flooded out to everyone.
BGP faces a completely different problem: the Internet has tens of thousands of Autonomous Systems (AS), belonging to different companies that don't trust each other and have business relationships with each other. The question here isn't "which path is shortest", it's "am I willing to forward your traffic" and "which entry point do I want people coming in from".
So BGP is a path-vector + policy protocol: it doesn't compute the shortest path, it makes policy-based routing decisions based on a bunch of attributes (AS_PATH / LOCAL_PREF / MED ...).
Three key differences
(1) Neighbors must be configured manually. OSPF sends Hellos and discovers neighbors automatically; BGP requires you to write out a peer command for each one, and underneath it runs over a single TCP port 179 connection. Being connected in the topology != having a BGP neighbor.
(2) BGP does not compute paths itself, it completely depends on the IGP. BGP is only responsible for "who is the next hop for this prefix"; getting to that next hop is the IGP's job. So an unreachable next hop means an invalid route.
(3) Only the best route is propagated. For each prefix, BGP only advertises the one route it actually selected to its neighbors -- unlike OSPF, which synchronizes the entire link-state database.
A bit about AS numbers
AS numbers used to be 2 bytes (1-65535); they've now been extended to 4 bytes.
- Public AS: applied for from a registry such as APNIC, globally unique, required if you're on the public Internet.
- Private AS: 64512-65534, free to use inside an enterprise, but must not appear in the Internet's AS_PATH (an ISP will strip it out for you).
Same AS number means iBGP, different AS numbers mean eBGP -- this one sentence determines every behavioral difference that follows.
Hands-on: look at the simplest possible pair of AS's
Load the "Simplest eBGP" topology: R1 in AS100 and R2 in AS200 are directly connected, each advertising one prefix via network.
Go to the Topology & Neighbors page and confirm two things:
(1) the neighbor state is Established (if it isn't, don't bother looking at anything else);
(2) there's a session line between the two devices on the canvas.
On real hardware this corresponds to display bgp peer -- this is also the first step of every BGP troubleshooting session.
Key takeaways
- BGP is a path-vector + policy protocol, it does not compute shortest paths
- Neighbors must be configured manually; underneath it runs over TCP 179
- BGP relies on the IGP to make the next hop reachable; an unreachable next hop makes a route invalid
- Same AS number = iBGP, different AS numbers = eBGP
Lesson 2 - Why an eBGP neighbor won't come up
Troubleshooting · about 12 min
Goal: Get a firm handle on issues like "the neighbor is stuck in Active / OpenSent" once and for all.
The state machine: just remember the three sticking points
The full state machine: Idle -> Connect -> Active -> OpenSent -> OpenConfirm -> Established.
- Stuck at Idle: the neighbor address is misconfigured, or there is simply no route to the peer.
- Bouncing between Idle and Active: TCP can't be established. The three most common causes -- a wrong address, one-way reachability, and eBGP with no multihop configured when it isn't actually directly connected.
- Stuck at OpenSent: TCP came up but the Open message failed validation. Either the remote-as is wrong, or there's a Router-ID conflict.
Routes only start being exchanged once the session reaches Established.
Why eBGP defaults to requiring a direct connection
The TCP segments eBGP sends have a default TTL of 1, enough for just one hop. This is a deliberate security measure: it prevents someone far away from spoofing an eBGP session.
Two situations break this assumption:
(1) the two devices are not directly connected (something sits in between);
(2) the session is built using Loopback addresses -- even if the devices are physically adjacent, going from the interface to the Loopback internally counts as one more hop.
Both are solved with the same command: peer x.x.x.x ebgp-max-hop 2 (called ebgp-multihop on Cisco).
Hands-on: deliberately break a neighbor
On the Topology & Neighbors page, select that eBGP neighbor:
(1) change remote-as to a wrong number -> watch it get stuck at OpenSent, and read the diagnostic message;
(2) change it back, then check "build the session over Loopback" without adding multihop -> watch it drop to Active;
(3) change ebgp-max-hop to 2 -> it recovers to Established.
You only really remember a failure once you've caused it yourself.
Key takeaways
- Bouncing between Idle/Active = TCP can't come up (address / reachability / multihop)
- Stuck at OpenSent = wrong AS number or a Router-ID conflict
- eBGP messages have TTL=1; non-adjacent peers or Loopback sessions both need ebgp-max-hop
- Routes only exist once the session reaches Established
Lesson 3 - What eBGP changes when it advertises a route
Basics · about 12 min
Goal: See clearly how AS_PATH and NEXT_HOP change -- this is the whole essence of eBGP.
Two attributes that must change
When eBGP advertises a route to a neighbor:
(1) its own AS number is prepended to the front of AS_PATH.
So AS_PATH reads as the path of traversal from right to left -- the leftmost entry is the most recently traversed AS.
It serves two purposes: route selection (shorter is better) and loop prevention (a route containing your own AS number is dropped immediately).
(2) NEXT_HOP is changed to its own address on this link.
Makes sense: for the peer to send packets to me, it obviously needs to point at my interface address on this link.
Two attributes that are not passed along
- LOCAL_PREF is not sent to eBGP neighbors. It is a purely internal AS attribute expressing "which way this AS prefers to exit", and it has nothing to do with anyone else. The receiver treats it with its own default value (100).
- MED by default does not cross a second AS. AS200 tells AS100 "it's better to come in through this entry point"; when AS100 passes the route on to AS300, it clears the MED, because that suggestion is meaningless to AS300.
Walk through the attribute changes on paper
Take the chain AS100(R1) -> AS200(R2) -> AS300(R3) and work through the attributes of 8.8.8.0/24 yourself:
R1 sends AS_PATH=[100] NEXT_HOP=R1's interface address R2 receives AS_PATH=[100] NEXT_HOP=R1 R2 sends AS_PATH=[200,100] NEXT_HOP=R2's interface address <- both changed R3 receives AS_PATH=[200,100] NEXT_HOP=R2
Verify three rules for yourself:
(1) every time AS_PATH crosses an AS, that AS's number is inserted at the left end -- so the leftmost is the most recently traversed
(2) NEXT_HOP changes to its own address every time it crosses an eBGP neighbor (it does not change when passed along inside iBGP -- that's the root cause of "unreachable next hop" in the iBGP tab)
(3) LOCAL_PREF never leaves the AS at all -- the message R3 receives doesn't contain this attribute
* Verify on real hardware: display bgp routing-table 8.8.8.0 shows both of these attributes.
Key takeaways
- eBGP advertisement: AS_PATH gains its own AS, NEXT_HOP changes to itself
- AS_PATH read right-to-left is the traversal order; the leftmost entry is most recent
- LOCAL_PREF never leaves the AS; MED by default doesn't cross a second AS
Lesson 4 - AS_PATH loop prevention, and using prepend to steer traffic
Advanced · about 10 min
Goal: Understand BGP's only cross-AS loop-prevention mechanism, and how to use it the other way around.
Loop prevention: drop a route that already contains your own AS number
When BGP propagates across AS's, there's no TTL, no sequence number, and no link-state database -- loop detection relies entirely on AS_PATH:
when an eBGP neighbor receives a route and finds its own AS number already in AS_PATH, that means the route went out from here and looped back around -> drop it immediately.
Special case: MPLS VPN Hub-Spoke scenarios genuinely need the route to loop back, in which case peer allow-as-loop relaxes the restriction.
Prepend: make others not want to use your path
Shorter AS_PATH is preferred, so the flip side is -- deliberately repeat your own AS number several extra times, and once others see how long the path is, they stop choosing it.
Command form (Huawei route-policy):
route-policy LONG permit node 10 apply as-path 100 100 100 additive
This is the most commonly used way to control inbound traffic. Why not use MED instead? Because MED is only meaningful within a single neighbor AS, while everyone compares AS_PATH.
Rule of thumb: LOCAL_PREF controls outbound, AS_PATH prepend controls inbound.
Hands-on: load the "dual-homed multipath" topology and take a look
Go to the Topology & Neighbors page and load "Dual-homed Multipath": R1 in AS100 learns 8.8.8.0/24 from three different directions.
Then work through who wins yourself -- walk down the 12 rules in order, and stop at the first rule that breaks the tie:
(1) compare LOCAL_PREF first (higher wins). If they're all equal, move on.
(2) then compare AS_PATH length (shorter wins).
(3) still tied? compare Origin, MED, eBGP over iBGP...
* To verify prepend's effect, on real hardware add apply as-path 100 100 additive inside a route-policy for one of them, stretching AS_PATH by two hops, and the result will flip.
Key takeaways
- AS_PATH is BGP's only cross-AS loop-prevention mechanism
- Stretching AS_PATH with prepend can make others avoid your path
- LOCAL_PREF controls outbound, AS_PATH prepend controls inbound
Lesson 5 - How to use the 12 path-selection rules
Advanced · about 18 min
Goal: Learn to "compare from top to bottom, one rule at a time" instead of rote-memorizing a rule table.
First, get the mental model right
The rules have an order, and the moment one rule breaks a tie, none of the later ones are even looked at.
The most common beginner mistake: seeing that AS_PATH differs and concluding that AS_PATH decided the outcome. But if LOCAL_PREF (rule 3) already broke the tie, AS_PATH (rule 5) never even gets a turn.
So the correct approach is: start at rule 1 and work down. For each rule, first check whether all candidates have the same value (if so, skip it); if they differ, eliminate the worse ones; once only one candidate remains, stop.
All 12 rules, listed in order
(1) Discard routes whose NEXT_HOP is unreachable (validity check -- if there's no * in the routing table, it's stuck at this rule)
(2) Higher Preferred-Value wins (Huawei-proprietary, only effective on the local device, never passed to any neighbor)
(3) Higher Local_Pref wins (default 100, propagated only within the AS, controls this AS's outbound traffic)
(4) Locally originated routes preferred (manual aggregate > automatic aggregate > network > import-route > learned from a peer)
(5) Shorter AS_Path wins (prepending your own AS number can make others avoid your path, controlling inbound traffic)
(6) Origin: IGP > EGP > Incomplete (routes advertised via network are IGP; those imported via import-route are Incomplete)
(7) Lower MED wins (by default only compared between routes from the same neighbor AS; it's a suggestion made to that neighbor AS)
(8) eBGP preferred over iBGP (learned directly from outside beats one that was relayed through the AS internally)
(9) Lower IGP cost to NEXT_HOP wins (hot-potato routing: get the traffic out of your own AS as quickly as possible)
(10) Shorter Cluster_List wins (RR scenarios; fewer reflections wins)
(11) Lower Originator_ID / Router-ID wins (no technical merit either way, purely to make the outcome consistent network-wide)
(12) Lower peer address wins (the final tiebreaker; reaching this point means the first 11 rules were completely identical)
* This list and its order exactly match the backend's path-selection engine -- it isn't a simplified version. On real hardware, the "which rule" number reported by display bgp routing-table <prefix> is counted in exactly this order.
The four most commonly used rules
Of the 12 rules above, only four are actually tunable in real work and most commonly tested:
Rule 3, LOCAL_PREF (higher is better, default 100) -- controls this AS's outbound traffic. It only propagates within the AS, so it's a unified decision made by the whole AS.
Rule 5, AS_PATH (shorter is better) -- prepending to stretch it can control inbound traffic.
Rule 7, MED (lower is better, default 0) -- a suggestion made to a neighbor AS, controlling inbound traffic. Warning: by default it only compares routes from the same neighbor AS.
Rule 8, eBGP over iBGP -- learned directly from outside beats one relayed internally.
The MED precondition that's easiest to overlook
MED by default is only compared between routes from the same neighbor AS.
Example: R1 learns a route from AS200 (MED=50) and one from AS300 (MED=10). Many people assume the MED=10 one is chosen -- wrong, these two come from different AS's, so MED is not compared at all, and selection continues down to rules 8 and 9.
To compare MED across AS's you'd need to configure compare-different-as-med (generally not recommended). The preset "Dual-homed Multipath" topology has two devices in AS200, which is exactly the scenario where MED actually takes effect -- MED is only compared between two routes from the same neighbor AS.
Hands-on: work through these three practice problems
Decide which one wins and at which numbered rule the tie is broken (answers explained below in "Lab takeaways"):
Problem 1
A: LOCAL_PREF=100 AS_PATH=[200,300] MED=10 B: LOCAL_PREF=200 AS_PATH=[200,300,400,500] MED=0
-> B wins, decided at rule 3. LOCAL_PREF is higher, so the longer AS_PATH and higher MED after it are never even considered.
Problem 2
A: LOCAL_PREF=100 AS_PATH=[200] from AS200 MED=50 B: LOCAL_PREF=100 AS_PATH=[300] from AS300 MED=10
-> LOCAL_PREF ties, AS_PATH length is 1 for both, Origin also matches, and we get to MED -- but these two come from different neighbor AS's, so MED isn't compared at all, and selection continues down to rules such as "eBGP over iBGP" and "lower IGP metric".
* This problem is exactly the trap described in the previous step.
Problem 3
A: LOCAL_PREF=100 AS_PATH=[200,300] from AS200 MED=50 B: LOCAL_PREF=100 AS_PATH=[200,400] from AS200 MED=10
-> B wins, decided at rule 7 (MED). Both AS_PATHs are 2 hops, and critically they come from the same neighbor AS, so this time MED really is compared, and the lower one wins.
Verify on real hardware: display bgp routing-table 8.8.8.0 will tell you directly which route is best and why.
Key takeaways
- Rules have an order; whichever one breaks the tie first speaks, and none after it matter
- LOCAL_PREF controls outbound; AS_PATH prepend and MED control inbound
- MED by default only compares routes from the same neighbor AS
- Always ask: which numbered rule actually decided this route selection
Lesson 6 - Community attributes and a troubleshooting routine
Troubleshooting · about 10 min
Goal: Use community attributes for policy, plus a troubleshooting workflow you can copy directly.
Three well-known community attributes
COMMUNITY is a tag attached to a route; it has no behavior of its own -- the behavior is decided by whoever receives it. But three values are universally recognized:
- no-export: can propagate inside this AS, but must not be sent to eBGP neighbors (never leaves the AS).
- no-advertise: once received, it must not be sent onward by anyone.
- no-export-subconfed: in confederation scenarios, doesn't leave the sub-AS.
Custom communities are typically written as AS:number, e.g. 100:666 meaning "this is a customer route", used together with route-policy to do bulk policy matching.
A troubleshooting workflow (follow this order, don't skip steps)
(1) Is the neighbor up? display bgp peer -- the state must be Established.
(2) Was it sent upstream? on the upstream device, display bgp routing-table peer <ip> advertised-routes.
(3) Was it received locally? display bgp routing-table peer <ip> received-routes.
(4) Received but not effective? check for a * (valid) marker -- if missing, it's an unreachable next hop.
(5) Valid but not selected? display bgp routing-table <prefix>, and check which numbered rule decided it.
90% of BGP failures can be pinpointed at steps (1), (2), and (4).
* Remember the three tables these five steps map to -- knowing which table the problem is on makes everything clear:
- step (2) checks the upstream's Adj-RIB-Out (did it actually send it or not)
- steps (3) and (4) check the local device's Adj-RIB-In (was it received, and is it valid)
- step (5) checks the Loc-RIB (the result of path selection)
Key takeaways
- no-export doesn't leave the AS; no-advertise is never sent onward by anyone
- Troubleshooting order: neighbor state -> upstream Adj-RIB-Out -> local Adj-RIB-In -> validity -> path selection
- A route present in the table without a * marker = unreachable next hop