BGP Peering and Route Exchange, Packet by Packet
A frame-by-frame read of a BGP peering coming up in a real Wireshark BGP capture โ three autonomous systems, a hub that peers with two others, and the full arc from the first TCP SYN to a converged routing table. The trace was decoded and annotated with VisualEther, which turns a Wireshark PCAP into a sequence diagram with a plain-English caption on every message.
๐ก Read the walkthrough and the diagram side by side. Open the interactive diagram (or PDF) in a split-screen window so the captions stay in view as you read. In Edge, Chrome, or Firefox, right-click the link and pick your browser's split-screen option (Edge labels it "Open link in split screen window"). On macOS, prefer Chrome or Firefox โ Safari has no in-browser split screen. Otherwise, open the diagram in a new tab and snap the two windows side by side.
Overview
The Border Gateway Protocol is how the independent networks that make up the internet โ autonomous systems, each with its own AS number โ tell each other which destinations they can reach. This 154-frame capture is a small, self-contained lab of exactly that: three autonomous systems, a routing table converging from nothing, and every mechanism BGP uses to get there visible on the wire.
The topology is hub-and-spoke. AS 65000 is the hub; it peers with AS 65100 over one link and AS 65200 over another. The two spokes never peer directly โ everything they learn about each other transits the hub, which is BGP's core job.
The flow moves through five phases, each building on the last:
- TCP setup (frames 1โ14). BGP runs over TCP, so nothing BGP-level happens until a TCP connection exists. The hub is up first, and its outbound attempts are refused until each neighbor's BGP is listening.
- OPEN and Established (frames 16โ21). Once TCP connects, the two ends exchange BGP
OPENmessages, agree on a hold time, negotiate capabilities, and aKEEPALIVEpromotes the session to Established. - Route exchange (frames 24โ32). Each side advertises its routes in
UPDATEmessages and closes its initial table with an End-of-RIB marker. - Propagation across the fabric (frames 34โ82). When the second spoke comes up, its routes ripple through the hub to the first spoke โ without the two ever peering.
- Steady state (frames 84โ154). Once converged, the sessions carry nothing but periodic
KEEPALIVEheartbeats, until the capture stops.
Every session walks the BGP finite state machine (RFC 4271) on its way to Established:
A primer on BGP
A few ideas make the rest of the walkthrough read cleanly:
- BGP runs over TCP, port 179. TCP provides the reliability, ordering, and flow control that BGP needs; BGP itself never retransmits. A session that will not come up is often a transport problem โ a refused or filtered port 179 โ not a BGP one.
- eBGP is between autonomous systems. A session between two different AS numbers is external BGP. Every route carries an
AS_PATHโ the list of autonomous systems it has traversed, newest first: each AS prepends its own number as it forwards the route, so the leftmost AS is the neighbor that just handed it to you and the rightmost is the AS that originated the prefix. For example, a path of65000 65200was originated byAS 65200and relayed by the hub,AS 65000; a single-AS path like65100is an origin route. AS_PATHis also loop prevention. Before accepting a route, a router checks whether its own AS number already appears in the path. If it does, the route is a loop and is discarded. This single rule is what keeps routes from cycling forever in a mesh.- Capabilities are negotiated in
OPEN. Each side advertises what it supports โ multiprotocol families, route refresh, 4-octet AS numbers, graceful restart โ and only the common set is used. - Graceful restart and End-of-RIB. A router recovering from a restart asks its peers to hold onto its routes until it has finished re-advertising its table. The "I'm done" signal is an End-of-RIB marker โ the RIB being the Routing Information Base, the router's table of routes โ an
UPDATEwith no routes in it (RFC 4724). - Hold time and
KEEPALIVE. The two ends agree on a hold time (180 s here); each sends aKEEPALIVEabout a third of the way through (~60 s). Miss the hold interval and the peer is declared dead.
Phase 1 โ TCP setup: refused until the far side is listening (frames 1โ14)
The capture opens with the hub (AS 65000) actively trying to connect to both neighbors: a TCP SYN to destination port 179 on each. Every one is answered with RST, ACK โ a reset, before a single BGP byte is exchanged.
Frames 1โ4 โ the first refusals. Frame 1 is the hub's SYN toward AS 65200 (ephemeral source port 51416 โ destination 179); frame 2 is the RST, ACK that refuses it. Frames 3 and 4 are the same exchange toward AS 65100 on the other link. A reset this early means no process is listening on TCP/179 โ the neighbor's BGP daemon is not up yet. This is a transport-layer refusal, not a BGP NOTIFICATION or a policy rejection.
Frames 5โ12 โ the ConnectRetry loop. Frame 5 retries AS 65100 about 120 s after frame 3; its ephemeral source port stepped up (55404) so you can see it is a brand-new attempt, not a retransmission. That ~120 s cadence is BGP's ConnectRetry timer: when an active connect fails, BGP moves to the Active state, waits ConnectRetry seconds, and tries again. Frames 5โ12 are two more rounds of this against both still-silent neighbors โ every one refused.
Frames 13โ14 โ the .51 session comes up, and note who connects. Frame 13 is the turning point: now AS 65100 (192.168.51.2) sends the SYN inbound to the hub's port 179, and frame 14 is the hub's SYN, ACK completing the handshake. The hub's outbound attempts never worked โ the session completes only once the passive side's BGP is running and connects in. A session needs one end listening and the other connecting, and here the listener (the hub) was ready long before the callers were. With TCP up, both ends move to OpenSent.
Phase 2 โ OPEN, capabilities, and Established (frames 16โ21)
With TCP established on the .51 link, both ends exchange BGP OPEN messages โ the first BGP-level bytes in the whole capture.
Frames 16 and 18 โ the two OPENs. Frame 16 is AS 65100's OPEN; frame 18 is the hub's reply. Each carries the sender's My AS, a BGP Identifier (router ID), a proposed Hold Time of 180 s, and a capability list: 4-octet AS numbers, MP-BGP IPv4 unicast, route refresh, graceful restart with long-lived graceful restart, add-paths, and an FQDN capability. The lower of the two proposed hold times wins; both proposed 180, so 180 it is.
One capability detail in frame 16 matters for what follows: AS 65100's graceful-restart Restart-State flag is set, telling the hub it is recovering from a restart. The hub should hold any stale AS 65100 routes until an End-of-RIB marker says the spoke has finished re-advertising. The hub's own flag, back in frame 18, is clear โ it did not restart. To find it in the field tree below, expand Optional Parameters and open the second-to-last capability, Graceful Restart capability (the last is Long-Lived Graceful Restart); its Restart Timers node holds the Restart state: Yes flag.
Frames 20 and 21 โ KEEPALIVE promotes to Established. A KEEPALIVE in each direction โ frame 20 from the spoke, frame 21 from the hub โ received in OpenConfirm, promotes both ends to Established, and route exchange can begin.
Frame 16 in full. Everything the two ends negotiate is in this one message: the sender's AS number, its router ID, the proposed hold time, and the full capability list โ including the graceful-restart capability whose Restart-State flag drives the rest of the flow. The decoded field tree lays it all out:
frame : Frame 16: Packet, 166 bytes on wire (1328 bits), 166 bytes captured (1328 bits) on interface ens39, id 1
Interface id : 1 (ens39)
eth : Ethernet II, Src: 00:0c:29:dc:92:4e, Dst: 00:0c:29:c8:75:81
Destination : 00:0c:29:c8:75:81
Source : 00:0c:29:dc:92:4e
ip : Internet Protocol Version 4, Src: 192.168.51.2, Dst: 192.168.51.1
Differentiated Services Field : 0xc0 (DSCP: CS6, ECN: Not-ECT)
010. .... = Flags : 0x2, Don't fragment
Time to Live : 1
Expert Info (Note/Sequence) : "Time To Live" only 1
tcp : Transmission Control Protocol, Src Port: 54402, Dst Port: 179, Seq: 1, Ack: 1, Len: 100
Conversation completeness : Incomplete, DATA (15)
Flags : 0x018 (PSH, ACK)
Options : (12 bytes), No-Operation (NOP), No-Operation (NOP), Timestamps
TCP Option - No-Operation (NOP)
TCP Option - No-Operation (NOP)
TCP Option - Timestamps : TSval 3256349416, TSecr 253927126
Timestamps
SEQ/ACK analysis
bgp : Border Gateway Protocol - OPEN Message
Optional Parameters
Optional Parameter : Capability
Capability : Multiprotocol extensions capability
Optional Parameter : Capability
Capability : Route Refresh Capability (Cisco)
Optional Parameter : Capability
Capability : Route refresh capability
Optional Parameter : Capability
Capability : Enhanced route refresh capability
Optional Parameter : Capability
Capability : Support for 4-octet AS number capability
Optional Parameter : Capability
Capability : BGP-Extended Message
Optional Parameter : Capability
Capability : Support for Additional Paths
Optional Parameter : Capability
Capability : FQDN Capability
Optional Parameter : Capability
Capability : Graceful Restart capability
Length : 2
Expert Info (Chat/Request) : Graceful Restart Capability supported in Helper mode only
Restart Timers : 0xc078, Restart state, Graceful notification
Optional Parameter : Capability
Capability : Long-Lived Graceful Restart (LLGR) Capability
Frame 16, BGP OPEN from AS 65100. Under Border Gateway Protocol - OPEN Message sit My AS (65100), Hold Time (180 s), and the BGP Identifier (router ID); the Optional Parameters -> Optional Parameter -> Capability list carries the Multiprotocol extensions, Route Refresh, Support for 4-octet AS number, Support for Additional Paths, and FQDN capabilities, plus the Graceful Restart and Long-Lived Graceful Restart capabilities that bracket the initial table.
Phase 3 โ Route exchange (frames 24โ32)
With the session up, each side advertises its routes in UPDATE messages. In frame 24, AS 65100 sends its two origin prefixes; in frame 26 the hub replies with its full table toward AS 65100; and each UPDATE burst closes with an End-of-RIB marker. The AS_PATH on every route tells the story of where it came from:
| Prefix | Advertised by | AS_PATH | Meaning |
|---|---|---|---|
10.30.0.0/16 | AS 65100 | 65100 | AS 65100's own route (one hop = origin) |
10.40.0.0/16 | AS 65100 | 65100 | AS 65100's own route |
10.10.0.0/16 | hub | 65000 | hub-originated |
10.20.0.0/16 | hub | 65000 | hub-originated |
10.30.0.0/16 | hub | 65000 65100 | 65100's route, reflected back with the hub prepended |
10.40.0.0/16 | hub | 65000 65100 | 65100's route, reflected back |
That last pair, in frame 26, is AS_PATH loop prevention in action. The hub advertises everything it uses, including the routes it learned from AS 65100, straight back to AS 65100. The spoke sees its own AS number (65100) already in the path and silently discards them. Harmless, and a clean illustration of why the AS_PATH check exists โ without it, those two prefixes would ricochet between the peers forever. The End-of-RIB marker โ an UPDATE carrying no NLRI and no withdrawals โ is the "my initial table is complete" signal the graceful-restart flag promised back in the OPEN. There is no dedicated message or flag for it: on the wire it is simply the smallest legal UPDATE, 23 bytes with both its Withdrawn Routes Length and Total Path Attribute Length set to zero, and the receiver recognizes it by that empty shape (RFC 4724).
Frame 28 closes the exchange the other way: AS 65100 re-advertises the hub's own origin routes (10.10, 10.20) back to it with AS_PATH 65100 65000, and the hub drops them by the same rule โ 65000 is already in the path. With that, the two tables are synchronized, and frames 30 and 32 are the session's first periodic KEEPALIVEs, ~60 s apart, carrying no routes.
Frame 24 in full. The first two rows of that table on the wire: the spoke advertising its own prefixes with a one-hop AS_PATH, the signature of an origin route. The path attributes โ ORIGIN, AS_PATH, NEXT_HOP โ and the reachable prefixes are all here:
frame : Frame 24: Packet, 211 bytes on wire (1688 bits), 211 bytes captured (1688 bits) on interface ens39, id 1
Interface id : 1 (ens39)
eth : Ethernet II, Src: 00:0c:29:dc:92:4e, Dst: 00:0c:29:c8:75:81
Destination : 00:0c:29:c8:75:81
Source : 00:0c:29:dc:92:4e
ip : Internet Protocol Version 4, Src: 192.168.51.2, Dst: 192.168.51.1
Differentiated Services Field : 0xc0 (DSCP: CS6, ECN: Not-ECT)
010. .... = Flags : 0x2, Don't fragment
Time to Live : 1
Expert Info (Note/Sequence) : "Time To Live" only 1
tcp : Transmission Control Protocol, Src Port: 54402, Dst Port: 179, Seq: 120, Ack: 120, Len: 145
Conversation completeness : Incomplete, DATA (15)
Flags : 0x018 (PSH, ACK)
Options : (12 bytes), No-Operation (NOP), No-Operation (NOP), Timestamps
TCP Option - No-Operation (NOP)
TCP Option - No-Operation (NOP)
TCP Option - Timestamps : TSval 3256350519, TSecr 253927129
Timestamps
SEQ/ACK analysis
bgp : Border Gateway Protocol - UPDATE Message
Path attributes
Path Attribute - ORIGIN : IGP
Flags : 0x40, Transitive, Well-known, Complete
Path Attribute - AS_PATH : 65100
Flags : 0x50, Transitive, Extended-Length, Well-known, Complete
AS Path segment : 65100
Path Attribute - NEXT_HOP : 192.168.51.2
Flags : 0x40, Transitive, Well-known, Complete
Path Attribute - MULTI_EXIT_DISC : 0
Flags : 0x80, Optional, Non-transitive, Complete
Path Attribute - COMMUNITIES : 321:654
Flags : 0xc0, Optional, Transitive, Complete
Communities : 321:654
Community : 321:654
Network Layer Reachability Information (NLRI)
10.30.0.0/16
bgp : Border Gateway Protocol - UPDATE Message
Path attributes
Path Attribute - ORIGIN : IGP
Flags : 0x40, Transitive, Well-known, Complete
Path Attribute - AS_PATH : 65100
Flags : 0x50, Transitive, Extended-Length, Well-known, Complete
AS Path segment : 65100
Path Attribute - NEXT_HOP : 192.168.51.2
Flags : 0x40, Transitive, Well-known, Complete
Path Attribute - MULTI_EXIT_DISC : 0
Flags : 0x80, Optional, Non-transitive, Complete
Path Attribute - COMMUNITIES : 123:456
Flags : 0xc0, Optional, Transitive, Complete
Communities : 123:456
Community : 123:456
Network Layer Reachability Information (NLRI)
10.40.0.0/16
bgp : Border Gateway Protocol - UPDATE Message
Frame 24, BGP UPDATE from AS 65100. Under Border Gateway Protocol - UPDATE Message: Path Attribute - ORIGIN (IGP), Path Attribute - AS_PATH -> AS Path segment holding the single AS 65100 (a one-hop, origin path), and Path Attribute - NEXT_HOP; the advertised prefixes sit under Network Layer Reachability Information (NLRI) -> NLRI prefix.
Phase 4 โ Propagation across the fabric (frames 34โ82)
Meanwhile, the hub keeps retrying the second neighbor: active-open attempts toward AS 65200 at frames 34, 44, 52, and 60, each ~120 s apart and each refused, exactly as in Phase 1. Then, minutes in, the AS 65200 spoke finally comes up on the .50 link the same way AS 65100 did โ frame 62 is its inbound SYN, frame 63 the hub's SYN, ACK, frames 65 and 67 the two OPENs (with AS 65200 also flagging Restart-State), and frames 69โ70 the KEEPALIVE pair that brings the second session to Established.
AS 65200's new routes do not stay on the .50 link โ they ripple across the existing .51 session too, in a ~50 ms flurry at frames 73โ82. In frame 74, the hub takes the 10.50.0.0/16 and 10.60.0.0/16 prefixes it just learned from AS 65200, prepends its own AS, and advertises them to AS 65100 as AS_PATH 65000 65200. In frame 78, it hands AS 65200 everything it knows โ its own origins and the routes it learned from AS 65100 (AS_PATH 65000 65100). This is the whole point of BGP: it makes AS 65200's reachability visible to AS 65100, and vice versa, without those two autonomous systems ever peering directly. And every route the hub reflects back toward its origin โ frame 80 toward AS 65200, and the 65200-prepended pairs AS 65200 sends back in frame 82 โ is dropped by the same AS_PATH rule from Phase 3. With both peerings converged, all three autonomous systems can now reach all six /16 prefixes.
Frame 74 in full. One of those cross-fabric advertisements: the hub handing AS 65200's route to AS 65100 with its own AS prepended. The AS_PATH now reads two hops โ 65000 65200 โ and the NEXT_HOP is the hub, so AS 65100 reaches AS 65200 through it:
frame : Frame 74: Packet, 127 bytes on wire (1016 bits), 127 bytes captured (1016 bits) on interface ens39, id 1
Interface id : 1 (ens39)
eth : Ethernet II, Src: 00:0c:29:c8:75:81, Dst: 00:0c:29:dc:92:4e
Destination : 00:0c:29:dc:92:4e
Source : 00:0c:29:c8:75:81
ip : Internet Protocol Version 4, Src: 192.168.51.1, Dst: 192.168.51.2
Differentiated Services Field : 0xc0 (DSCP: CS6, ECN: Not-ECT)
010. .... = Flags : 0x2, Don't fragment
Time to Live : 1
Expert Info (Note/Sequence) : "Time To Live" only 1
tcp : Transmission Control Protocol, Src Port: 179, Dst Port: 54402, Seq: 518, Ack: 579, Len: 61
Conversation completeness : Incomplete, DATA (15)
Flags : 0x018 (PSH, ACK)
Options : (12 bytes), No-Operation (NOP), No-Operation (NOP), Timestamps
TCP Option - No-Operation (NOP)
TCP Option - No-Operation (NOP)
TCP Option - Timestamps : TSval 254396967, TSecr 3256819254
Timestamps
SEQ/ACK analysis
bgp : Border Gateway Protocol - UPDATE Message
Path attributes
Path Attribute - ORIGIN : IGP
Flags : 0x40, Transitive, Well-known, Complete
Path Attribute - AS_PATH : 65000 65200
Flags : 0x50, Transitive, Extended-Length, Well-known, Complete
AS Path segment : 65000 65200
Path Attribute - NEXT_HOP : 192.168.51.1
Flags : 0x40, Transitive, Well-known, Complete
Path Attribute - COMMUNITIES : 321:654
Flags : 0xc0, Optional, Transitive, Complete
Communities : 321:654
Community : 321:654
Network Layer Reachability Information (NLRI)
10.50.0.0/16
10.60.0.0/16
Frame 74, BGP UPDATE from the hub (AS 65000) to AS 65100. The Path Attribute - AS_PATH -> AS Path segment now lists 65000 65200 โ the hub prepended its own AS to AS 65200's origin route โ while Path Attribute - NEXT_HOP points at the hub and the carried prefix sits under Network Layer Reachability Information (NLRI) -> NLRI prefix.
Once both sessions settle, every AS can reach all six prefixes. This is the converged state โ each cell is the AS_PATH by which that AS reaches that prefix, read straight from the UPDATEs on the wire (local means the AS originates the prefix itself, so there is no path to traverse; and what a router selects as best path is its internal decision โ here every prefix has only one path to choose from):
| Prefix (origin) | AS_PATH at AS 65100 | AS_PATH at hub AS 65000 | AS_PATH at AS 65200 |
|---|---|---|---|
10.10.0.0/16 (hub) | 65000 | local | 65000 |
10.20.0.0/16 (hub) | 65000 | local | 65000 |
10.30.0.0/16 (65100) | local | 65100 | 65000 65100 |
10.40.0.0/16 (65100) | local | 65100 | 65000 65100 |
10.50.0.0/16 (65200) | 65000 65200 | 65200 | local |
10.60.0.0/16 (65200) | 65000 65200 | 65200 | local |
The two spokes never exchanged a single packet, yet each reaches the other's prefixes โ through the hub, 65000 65200 in one direction and 65000 65100 in the other. That is the whole hub-and-spoke payoff in one table.
Phase 5 โ Steady state (frames 84โ154)
From frame 84 onward, the tables have converged, and there are no more route changes for the rest of the capture โ only KEEPALIVE heartbeats on each session, one about every 60 s, each resetting the sender's 180 s hold timer. Frame 154, the last in the capture, is one such routine KEEPALIVE (hub โ AS 65100).
Both peerings are still Established and perfectly healthy when the recording stops. There is no BGP NOTIFICATION and no TCP FIN or RST teardown โ the capture ends mid-flight.
A note on the lab capture: the two spokes carry the same BGP Identifier (192.168.51.2), and one reflected route arrives as AS_PATH 65200 65100 where a live network would show 65200 65000 65100. Both are artifacts of how this teaching capture was built; they do not change the mechanisms above. The interactive diagram and the printable PDF above carry the full per-message detail, with every field decoded.
Takeaways
- BGP is TCP-first. The most common reason a peering will not come up is a transport problem โ a refused or filtered port 179, or one side simply not listening yet โ long before any BGP logic runs. The
RST, ACKpattern in Phase 1 is exactly what that looks like on the wire. - A session needs a listener and a caller. Both ends can be active, but the connection only completes once the passive side's BGP is running and one end connects in.
AS_PATHis loop prevention you can watch. Routes reflected back toward their origin are dropped on sight because the receiver's AS is already in the path โ twice over in this capture.- Graceful restart brackets the initial table. The Restart-State flag in
OPENand the End-of-RIB marker that closes each advertisement are a matched pair: "hold my routes" and "I'm done." - A hub gives full reachability without a full mesh. Two spokes that never peer still reach each other, because the hub transits and re-advertises their routes.
Try it on your own capture
Every arrow in this walkthrough was decoded and captioned by VisualEther from a raw Wireshark PCAP โ no manual diagramming. Point it at your own routing, 5G, or IMS trace and read it the same way.