BGP Basics - Sessions, AS-PATH, eBGP and iBGP
- BGP (Border Gateway Protocol, version 4, RFC 4271) is the routing protocol between autonomous systems. Two routers form a session over TCP port 179, then trade UPDATE messages that say "I can reach this prefix, and here is the path."
- A session climbs six states, Idle, Connect, Active, OpenSent, OpenConfirm, Established. Only in Established do UPDATEs flow. A session stuck in Active means the TCP connection is failing, not that BGP is busy.
- BGP is a path-vector protocol. Every route carries its AS-PATH, the list of ASes it crossed. A router that finds its own ASN in the list drops the route, which is the loop protection.
- eBGP runs between different ASes and prepends the sender's ASN. iBGP runs inside one AS, leaves the AS-PATH alone, and never re-advertises an iBGP-learned route to another iBGP peer, so iBGP needs a full mesh of
n(n-1)/2sessions or route reflectors (RFC 4456). - BGP carries reachability, not traffic, and it chooses by policy first. A longer AS-PATH can win over a shorter one.
Mental model
Picture border posts between countries that pass notes to each other: "I can get you to Harbourville, via these countries, in this order." Each post adds its own country to the front of the note before passing it on, and it throws away any note that already lists its own country, because that note has gone in a circle. The post never sees a map, only the notes its neighbours hand it, and it decides which note to believe by its own rules, not by distance.
Where it breaks: a note lists countries, not roads. It says nothing about how long or congested each country's roads are, so a "short" note can be a terrible route.
BGP is a publish-subscribe gossip protocol over long-lived TCP connections. Each message carries its own provenance chain, the AS-PATH, and the chain doubles as the loop check. A router's table is the union of what its neighbours published, filtered and ranked by local rules, much like a cache that trusts its upstreams.
Where it breaks: unlike a distance-vector protocol it carries the whole path, not just a distance, and unlike OSPF no router holds a map of the network. There is only advertisement, which is why a false advertisement is believed unless something checks it.
How it works
Why inter-AS routing is different
Inside one AS an operator controls every router and an IGP such as OSPF finds shortest paths on a shared map (routing overview). Between ASes there is no shared map, no shared authority and no willingness to expose internal topology to a competitor. Reachability is also entangled with contracts: who pays whom to carry traffic (ISPs, peering and IXPs). So BGP exchanges reachability and paths, not link states, and each AS applies its own policy on top. The ASN itself and the IGP versus EGP split are covered in autonomous systems and routing overview; here we only need that every AS has a number.
The session
Two BGP routers that are configured as neighbours (peers) open a TCP connection to port 179 (RFC 4271, section 8). Using TCP means BGP has no retransmission or fragmentation logic of its own and one long-lived connection carries everything (TCP connection). Every BGP message starts with the same 19-byte header: a 16-byte marker, a 2-byte length and a 1-byte type. A message is at most 4096 bytes. There are four types:
| Type | Purpose | Key contents |
|---|---|---|
| OPEN (1) | Start the session; agree on parameters | Version 4, sender's ASN, proposed hold time, BGP identifier (a 32-bit router ID), optional capabilities such as 4-byte ASNs (RFC 6793) and multiprotocol support (RFC 4760) |
| UPDATE (2) | Announce or withdraw routes | Withdrawn prefixes, path attributes (ORIGIN, AS_PATH, NEXT_HOP, ...), and the NLRI: the prefixes that share those attributes |
| KEEPALIVE (4) | Prove the peer is alive | Header only, 19 bytes |
| NOTIFICATION (3) | Report an error and close the session | Error code (message header, OPEN, UPDATE, hold timer expired, FSM error, cease) and subcode |
Each side sends an OPEN with a hold time. The session uses the smaller of the two. A KEEPALIVE is sent roughly every third of the hold time, and if nothing (KEEPALIVE or UPDATE) arrives within the hold time, the router sends a NOTIFICATION and tears the session down. RFC 4271 suggests a 90 second hold time and a 30 second keepalive. Router defaults are vendor-specific: Cisco IOS and FRR default to 60 and 180 seconds, other platforms differ, so check yours.
Both sides track the session with a finite state machine:
| State | What it means | If it sticks here |
|---|---|---|
| Idle | Not trying yet; refuses incoming connections | Session is administratively down, or the router is backing off after repeated failures |
| Connect | Waiting for the TCP handshake to finish | TCP is slow or blocked |
| Active | TCP attempt failed; retrying (and listening) | Almost always no TCP path to the peer: wrong neighbour address, a filter on port 179, or the peer not configured for you |
| OpenSent | TCP is up; our OPEN is sent, waiting for theirs | Peer is not answering BGP, or it rejects our OPEN |
| OpenConfirm | Their OPEN was accepted; waiting for a KEEPALIVE | Brief on a healthy session |
| Established | Session is up; UPDATEs flow | Normal |
What an announcement physically is
A route announcement is an UPDATE message. Its path attributes describe a route, and its NLRI (network layer reachability information) lists the prefixes the attributes apply to. One UPDATE can carry many prefixes that share attributes. To retract a route, a router sends an UPDATE that lists the prefix as withdrawn. IPv6 and other address families ride in the multiprotocol attributes defined by RFC 4760 rather than in the IPv4 NLRI field.
The attributes you meet first:
| Attribute | Meaning | Notes |
|---|---|---|
| ORIGIN | How the route was first injected: IGP, EGP or incomplete | Mandatory. Rarely matters, but it is a tiebreaker |
| AS_PATH | ASes the route has crossed, most recent first | Mandatory. Each eBGP hop prepends its own ASN. Used for loop detection and as a length tiebreaker |
| NEXT_HOP | The address traffic for this prefix should be sent to | Mandatory. Set to the sender when advertising over eBGP; left alone over iBGP |
| LOCAL_PREF | How much this AS prefers the route | iBGP only, never sent to another AS. Set by local policy; higher wins |
| MED | A hint from a neighbouring AS about which of its entry points it prefers | Optional, compared only between routes from the same neighbouring AS; lower wins |
Worked example: one prefix across three ASes
This lab uses documentation values only: ASNs 64496, 64497 and 64498 (RFC 5398) and the prefix 192.0.2.0/24 (RFC 5737). The peering link between AS 64496 and AS 64497 uses 198.51.100.0/30, with .1 on the AS 64496 side.
- The AS 64496 router opens TCP 179 to
198.51.100.2. Both send OPEN (version 4, their own ASN, hold time, router ID). Both accept and answer with a KEEPALIVE. State: Established. - AS 64496 originates
192.0.2.0/24and sends an UPDATE to AS 64497: NLRI192.0.2.0/24, AS_PATH[64496], NEXT_HOP198.51.100.1, ORIGIN IGP. - AS 64497 picks that route as best, installs it, and advertises it onward to AS 64498. Over eBGP it prepends its own ASN and sets NEXT_HOP to itself: AS_PATH
[64497 64496]. - AS 64498 receives it. Its own ASN is not in the path, so it accepts. If a route ever arrived with
64498in its AS_PATH, the router would discard it. - Packets flow the opposite way to the announcement: a host in AS 64498 sending to
192.0.2.10is forwarded toward AS 64497, then AS 64496. The announcement went right; the traffic goes left.
Where the announcement becomes forwarding: BGP keeps its received routes in per-neighbour tables (Adj-RIB-In), runs the decision process into its own best-route table (Loc-RIB), and offers the winner to the router's main routing table. There it competes with OSPF, static and connected routes by administrative distance (routing overview), and the winner is copied into the FIB that forwards packets (longest-prefix match).
Deep dive
eBGP versus iBGP
BGP runs in two modes, depending on whether the two speakers are in the same AS.
| eBGP | iBGP | |
|---|---|---|
| Peers | Routers in different ASes | Routers in the same AS |
| Purpose | Learn routes from neighbouring ASes | Carry externally learned routes across the AS interior |
| AS_PATH | Sender prepends its ASN | Left unchanged |
| NEXT_HOP | Set to the sender | Left as the external next hop unless next-hop-self is configured |
| Typical TTL | 1: peers are directly connected by default | Normal TTL: peers are usually loopbacks reached over the IGP |
| Advertise to peers | Everything it chooses to, per policy | Never re-advertise a route learned from an iBGP peer to another iBGP peer |
A border router learns outside prefixes over eBGP, then uses iBGP to share them with the other routers in its AS. Two consequences follow.
The iBGP rule and the full mesh. Because the AS_PATH does not change inside an AS, it cannot be used to detect loops between iBGP peers. RFC 4271 instead forbids passing an iBGP-learned route to another iBGP peer. The price is that every iBGP router must hear every external route directly from the border router that learned it, so iBGP needs a full mesh: n(n-1)/2 sessions, which is 45 for 10 routers and 4950 for 100. Two standard fixes:
- A route reflector (RFC 4456) is allowed to break the rule. Routers configured as its clients send it their routes and it reflects them to the other clients and to non-client peers. Routes from a non-client are reflected to clients only. Two extra attributes, ORIGINATOR_ID and CLUSTER_LIST, stop reflection loops.
- A confederation (RFC 5065) splits one AS into sub-ASes that speak a special eBGP among themselves while looking like one AS to the outside.
Next-hop-self. Over eBGP, B1 learns a route from R1 with NEXT_HOP set to R1's address on the peering link. When B1 passes the route over iBGP, that NEXT_HOP is unchanged by default, but R1's link address belongs to a neighbour's network and is usually not in the AS's IGP, so the other routers cannot resolve it and the route is unusable. The usual fixes are configuring next-hop-self on the border router or putting the peering link into the IGP as a passive interface.
iBGP sessions are not link-local. iBGP peers are rarely directly connected. They peer between loopback addresses and rely on the IGP to deliver the TCP segments, which also keeps the session up when a single link fails.
The decision process
When a router has several routes to the same prefix, it picks one. RFC 4271 (section 9.1) defines the order, applied until one route is left:
- Highest LOCAL_PREF (the "degree of preference", set by local policy).
- Shortest AS_PATH.
- Lowest ORIGIN (IGP before EGP before incomplete).
- Lowest MED, compared only among routes from the same neighbouring AS.
- A route learned over eBGP beats one learned over iBGP.
- Lowest IGP metric to the NEXT_HOP (this is the hot-potato rule: leave the AS as soon as possible).
- Lowest BGP identifier (router ID), then lowest peer address.
Vendors add steps. Cisco, for instance, puts a local-only weight attribute above LOCAL_PREF (Cisco BGP best path selection); the exact order and extra tie-breakers such as "oldest route" are vendor-specific, so read your platform's documentation before relying on them. LOCAL_PREF, MED, prepending and communities are the policy attributes. They are covered on BGP policy and security; this page only needs the ordering.
Policy and security in brief
Policy outranks distance. If AS 65001 hears 198.51.100.0/24 with AS_PATH length 2 and LOCAL_PREF 100 from one neighbour, and with AS_PATH length 4 and LOCAL_PREF 200 from another, step 1 picks the longer path. (65001 is from the private-use range, used here for illustration.) The reason is economic: routes learned from a customer are preferred and are advertised to everyone, because the customer pays to be reachable, while routes from a provider or peer are normally advertised only to customers (ISPs, peering and IXPs).
The cost of this design is that BGP trusts what neighbours say. An AS that announces a prefix it does not own, or a more specific piece of it, pulls traffic toward itself because forwarding uses longest-prefix match. This is a prefix hijack, and a route accepted and passed on when it should have been filtered is a route leak (RFC 7908 defines the leak taxonomy). The attack side is summarised in network attacks; the policy attributes, the relationship rules and origin validation (RPKI) belong on BGP policy and security.
Timers, convergence and the table
- Advertisement interval. RFC 4271 (section 10) suggests that a router sends updates for the same prefix to a peer at most every 30 seconds over eBGP and every 5 seconds over iBGP (MinRouteAdvertisementIntervalTimer). Withdrawals are not instant for the same reason: they ripple out through many ASes, and a router may try a succession of worse alternate paths before settling. That is path exploration, and it is why BGP convergence is measured in tens of seconds to minutes, unlike OSPF.
- Fast failure detection. The hold timer takes tens of seconds to notice a dead peer. Operators pair BGP with BFD (RFC 5880) to detect a dead link in well under a second, and use graceful restart (RFC 4724) so a router that restarts its control plane does not blackhole traffic while it re-learns routes.
- 4-byte ASNs. The original OPEN carried a 2-byte ASN. RFC 6793 extends this to 32 bits and reserves the 2-byte value 23456 (AS_TRANS) to stand in for a 4-byte ASN when talking to an old speaker.
- Table size. The global IPv4 table holds on the order of a million prefixes and keeps growing. Do not trust a frozen number; watch a live view such as bgp.potaroo.net.
- Default route versus full table. A network with one upstream can use just a default route (
0.0.0.0/0) from its provider and receive no BGP table at all. A multi-homed network with two or more upstreams needs more than a default, either the full table or a partial one, to choose the better exit per destination.
BGP beyond ISPs
BGP is not only for the internet's core. RFC 7938 describes using eBGP as the only routing protocol in large data-center fabrics, with each switch or tier in its own ASN. Kubernetes tools such as Calico and MetalLB use BGP to advertise pod and service addresses to the physical network, and cloud private links (private connectivity) use BGP to exchange routes with your router. Anycast, one prefix announced from many places, is just BGP doing what it does (global traffic steering).
Textbook vs real world
| The textbook says | Production does | Why |
|---|---|---|
| BGP picks the shortest AS path | It checks LOCAL_PREF first; path length is the second step | Routes are chosen by contract and cost, so operators set LOCAL_PREF to express them |
| BGP converges like OSPF | Convergence takes tens of seconds to minutes, with path exploration | No shared map, advertisement timers, and many ASes re-deciding in turn |
| BGP is only for ISPs | Data centers, clouds and Kubernetes clusters run it too | It scales, it is policy-capable, and eBGP-only fabrics are simple (RFC 7938) |
| A default route is enough | Multi-homed networks take full or partial tables | A default route cannot choose the best of several exits per destination |
| iBGP is a mirror of eBGP | iBGP leaves AS_PATH and NEXT_HOP alone and has its own re-advertisement rule | AS_PATH cannot catch loops inside one AS, so the rule replaces it |
In production
- Cloud private links. AWS Direct Connect and Azure ExpressRoute exchange routes with your router over BGP (AWS Direct Connect, Azure ExpressRoute routing). The session state of those peers is the first thing you check when a link looks down.
- Kubernetes. Calico can peer every node with the top-of-rack switch over BGP to advertise pod CIDRs (Calico BGP). MetalLB's BGP mode announces LoadBalancer service IPs to the network (MetalLB BGP).
- Data centers. Large operators run eBGP between switch tiers as described in RFC 7938.
- Anycast CDNs and DNS. An operator announces the same prefix from many sites and lets BGP steer each user to a nearby one (Cloudflare: what is BGP, global traffic steering).
History and evolution
- 1982 EGP, the Exterior Gateway Protocol (RFC 827), joins the early internet's core to separately run networks, but it assumes a tree and cannot handle loops or policy.
- 1989 BGP-1 (RFC 1105) replaces it with a path-vector design that carries the AS path, so loops can be detected on arbitrary topologies. It is often called the "two-napkin protocol" after the way it is said to have been sketched.
- 1994 BGP-4 (RFC 1654, now RFC 4271) adds prefixes with lengths (CIDR) because classful routes were exhausting address space and growing the table.
- 1996 Communities (RFC 1997) let ASes tag routes so neighbours can apply policy to them.
- 2012 4-byte ASNs (RFC 6793) fix the shortage of 16-bit AS numbers, and RPKI (RFC 6480) starts to add origin checks to a trust-based protocol.
- Now BGP-4 runs between essentially every pair of ASes on the internet and inside many data centers. The table holds on the order of a million IPv4 prefixes; see a live dashboard such as bgp.potaroo.net.
- Next BGP roles and the Only To Customer attribute (RFC 9234) and path validation work such as ASPA aim to stop leaks by making relationships explicit in the protocol.
Hands-on
A two-router lab with FRR reproduces the worked example. On the AS 64496 router, in vtysh configuration mode:
The network statement only announces a prefix that already exists in the routing table, so add a local route for it first, for example ip route 192.0.2.0/24 blackhole. Recent FRR versions also require an inbound and outbound policy on eBGP sessions by default; for a lab, no bgp ebgp-requires-policy turns that off. Then look at the session:
(Illustrative output, abbreviated. Column layout varies by FRR version.) State/PfxRcd shows a number once the session is Established. It shows Active, Connect or Idle otherwise, which is the FSM state from above. Then see the route and its attributes:
The first prints the AS_PATH, NEXT_HOP and whether the route is the best path. The second prints the negotiated hold time, message counters and the state history. To watch the protocol itself:
In Wireshark use the display filter bgp to see OPEN, KEEPALIVE and UPDATE decoded. To see real AS-PATHs, use a public looking glass or route collector: bgp.he.net, RIPEstat or RouteViews. Look up a prefix and read how many ASes it crosses. A forward path can also be compared with traceroute; the two need not match exactly, since traceroute shows router hops and the AS-PATH shows ASes.
If a session sits in Active: from each router, test that the peer's address is reachable, that TCP 179 is not filtered, and that each side has the other's address configured as neighbour. Mismatched ASNs show up one step later, as a NOTIFICATION during OpenSent.
Gotchas
Interview questions
Show answer
BGP exchanges reachability between autonomous systems, over TCP port 179, and lets each AS apply its own policy. OSPF is a link-state IGP that floods link information so every router in one AS can compute shortest paths on a shared map. BGP has no map: it is a path-vector protocol where each route carries the list of ASes it crossed. Choosing by policy rather than by link cost is the design goal, not a flaw.
Follow-ups:
- Why TCP? BGP gets reliable, ordered delivery and flow control for free, and does not need its own retransmission.
- Can OSPF and BGP run together? Yes. OSPF (or another IGP) carries internal reachability and BGP carries external routes.
Show answer
One side opens a TCP connection to port 179. Each side sends an OPEN with version, ASN, hold time, router ID and capabilities, and the session adopts the smaller hold time. Each acknowledges with a KEEPALIVE and the state becomes Established. After that, UPDATE messages carry announcements and withdrawals, and KEEPALIVEs about every third of the hold time keep the session alive. An error produces a NOTIFICATION and the session closes.
Follow-ups:
- Stuck in Active? The TCP connection is failing: reachability, a filter on 179, or a wrong neighbour address.
- Stuck in OpenSent, then reset? The peer rejected the OPEN, often a wrong remote ASN.
Show answer
Every route carries its AS-PATH, and each eBGP hop prepends its own ASN. If a router receives a route whose AS-PATH already contains its own ASN, it discards it, since the route has already passed through it. This is path-vector loop prevention and it is why BGP does not count to infinity the way a plain distance-vector protocol can.
Follow-ups:
- And inside an AS? The AS-PATH does not change in iBGP, so the rule is different: iBGP-learned routes are not re-advertised to other iBGP peers.
Show answer
iBGP leaves the AS-PATH unchanged, so it cannot detect loops inside the AS. RFC 4271 therefore forbids re-advertising an iBGP-learned route to another iBGP peer, which means every router must peer with every other: n(n-1)/2 sessions. You avoid that with route reflectors (RFC 4456), where clients peer only with the reflector, or with confederations (RFC 5065), which split the AS into sub-ASes.
Follow-ups:
- How do reflectors avoid loops? The ORIGINATOR_ID and CLUSTER_LIST attributes identify the origin and the reflection clusters a route has passed.
- What do you give up? The reflector chooses one best path to reflect, so clients may see fewer paths than they would in a full mesh.
Show answer
A common cause is NEXT_HOP. Over iBGP the external next hop is left unchanged, so if it is not reachable through the IGP, the route is unusable. The fix is next-hop-self on the border router, or advertising the peering subnet into the IGP. Other causes are inbound policy that rejected the route, or a better route from another source winning in the routing table by administrative distance.
Follow-ups:
- How do you check? Look at the route's NEXT_HOP in the BGP table and verify the IGP has a route to it.
Show answer
BGP's decision process compares LOCAL_PREF before AS-PATH length. LOCAL_PREF is set by the operator's policy, for example "prefer customers over peers over providers", so a route through a paid customer wins even with a longer path. AS-PATH length only breaks ties among routes that are equal on the earlier steps.
Follow-ups:
- Does that hold on every vendor? The RFC order does, but vendors add attributes such as Cisco's weight above LOCAL_PREF.
Show answer
A single-homed network, with one upstream, can use a default route: there is only one place to send anything. A multi-homed network with several upstreams needs full or partial tables to pick the best exit for each destination, otherwise it cannot tell which upstream is better for which prefix. Table size drives router memory and FIB requirements.
Follow-ups:
- Middle ground? A partial table plus a default route: routes from peers and your own customers, with a default to the transit provider for the rest.
Fun facts
- BGP-1 (RFC 1105) is nicknamed the "two-napkin protocol" in IETF folklore, after the story that Yakov Rekhter and Kirk Lougheed sketched the design on napkins.
- BGP is an application-layer protocol that is used to build the network layer. It runs over TCP, even though what it configures is the IP forwarding table.
- A BGP KEEPALIVE is only the 19-byte header: the smallest message the protocol has.
- The 2-byte ASN 23456 (AS_TRANS) exists purely as a placeholder for 4-byte ASNs.
Cheat sheet
- 179 - TCP port for BGP
- 19 bytes - BGP message header; also the size of a KEEPALIVE
- 4096 bytes - maximum BGP message size
- 90 s / 30 s - RFC 4271 suggested hold time and keepalive; Cisco IOS and FRR default to 180 s and 60 s
- 30 s / 5 s - suggested eBGP and iBGP minimum route advertisement interval
- n(n-1)/2 - iBGP full-mesh session count
- 23456 - AS_TRANS