Files
ferrix/slides/sections/03-bgp-update.md
T
Rayhaan JaufeerallyandClaude Fable 5.1 2910a2a800 slides: light theme, final edits, single-file bundle
As presented. The palette is light on request of the reviewer; code blocks
and byte dumps keep a dark ground so the byte colours still work. The OPEN
walk lights the hovered bytes as an inverted block and its table cells are
dark text on a tint of their group colour.

build.py inlines reveal.js, the stylesheets, scripts and Markdown sections
into slides/dist/hands-on-bgp.html for uploading.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-01 20:40:55 +02:00

24 KiB
Raw Blame History

BGP in detail

Notes: We're going to look at some implementation details of the protocol


  • Runs over TCP, port 179, and is exchanged typically between peering routers
  • Each side tells the other its best route per prefix
  • Only changes are sent: no periodic refresh
  • If the session drops, after a timeout the routes learned over that session are dropped

Notes: BGP is a very old protocol, and a lot of it's design predates the internet being something with adversarial participants. Security and extensions have had to be bolted on, in perhaps strange ways.


The four message types

Type Name Says
1 OPEN AS number, router ID, capabilities
2 UPDATE these prefixes are reachable, those no longer are
3 NOTIFICATION errors and informational messages: e.g. rebooting
4 KEEPALIVE Heartbeat to keep the session up when there's no update

OPEN, OPEN, KEEPALIVE, KEEPALIVE, and then a stream of UPDATEs.

Notes: There is actually a fifth type, ROUTE-REFRESH: "send me everything again, my policy changed".


OPEN: a handshake between peers.

header, the same on every message: 19 bytes marker 16 bytes, all ff length 2 bytes type 1 byte OPEN: the fixed part version 1 byte: 4 my AS 2 bytes, or 23456 hold time 2 bytes, seconds BGP identifier 4 bytes, the router ID opt. length 1 byte optional parameters: today always one, of type 2 = capabilities, each a (code, length, value) type 2 capabilities length 1 byte IPv6 unicast code 1: AFI 2, SAFI 1 4-byte AS code 65: 210036 route refresh code 2, empty … more capabilities

Notes: Sent once, by each side, as soon as the TCP connection is up. The two sides must agree: the AS must be the one configured for the neighbour, the hold time becomes the smaller of the two, and only capabilities both announced are used. A 4-byte AS does not fit in "my AS", so that field carries 23456 and the real number rides in a capability, which is how our AS210036 arrives.


BGP Open message

ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00 37 01 04 5b a0 00 f0 0a ff 00 01 1a 02 18 01 04 00 02 00 01 02 00 06 00 40 02 00 00 41 04 00 03 34 74 46 00 47 00
BGP header: 19 bytes, on every message
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ffmarkersixteen bytes of ff.
00 37length0x0037 = 55 bytes, header included. At most 4096, or 65535 with the extended-message capability
01type1 = OPEN (2 UPDATE, 3 NOTIFICATION, 4 KEEPALIVE, 5 ROUTE-REFRESH)
OPEN: the fixed part, 10 bytes
04versionBGP version 4
5b a0my AS0x5ba0 = 23456, AS_TRANS: the ASN is longer than 16 bits so is encoded in a capability instead
00 f0hold time0x00f0 = 240 seconds. both peers use the minimum announced; a KEEPALIVE typically is sent every 1/3rd of this duration
0a ff 00 01BGP identifier0a ff 00 01 = 10.255.0.1, the router ID. Looks like an IPv4 address, just needs to be a unique identifier.
1aoptional parameters length0x1a = 26 bytes follow
Optional parameter: 2 + 24 bytes
02parameter type2 = capabilities
18parameter length0x18 = 24 bytes of capabilities follow, each as type, length, value
Capability 1: multiprotocol (RFC 4760)
01code1 = multiprotocol extensions
04length4
00 02AFI0x0002 = IPv6. Address Family Identifier
00reserved0
01SAFI1 = unicast. Subsequent Address Family Identifier.
Capability 2: route refresh (RFC 2918)
02code2 = route refresh: “you may ask me to resend everything”
00length0
Capability 6: extended message (RFC 8654)
06code6 = messages up to 65535 bytes are supported
00length0
Capability 64: graceful restart (RFC 4724)
40code0x40 = 64, graceful restart
02length2
00 00flags and restart time0x0000: not restarting, restart time 0, and no address families listed.
Capability 65: four-octet AS (RFC 6793)
41code0x41 = 65, four-octet AS number
04length4
00 03 34 74AS number00 03 34 74 = 210036: the real AS. Included here since it doesn't fit in the header
Capability 70: enhanced route refresh (RFC 7313)
46code0x46 = 70
00length0
Capability 71: long-lived graceful restart
47code0x47 = 71
00length0, no address families listed

Notes: What BIRD on our upstream router sends the lab daemon, byte for byte. Hold time 240 is BIRD's default; keepalives go every third of it.


Update message format

header: 19 bytes marker 16 bytes, all ff length 2 bytes type 1 byte UPDATE body: two lengths, three variable parts withdrawn length 2 bytes withdrawn routes IPv4 prefixes gone attributes length 2 bytes path attributes everything about the route NLRI IPv4 prefixes, new one path attribute; repeated for multiple flags 1 byte type 1 byte: ORIGIN = 1, AS_PATH = 2 … length 1 or 2 bytes value as many bytes as it said one prefix, in NLRI and in withdrawn routes: a bit count, then only the bytes that count needs length 1 byte: 24 for a /24 prefix 3 bytes for a /24, 6 for a /48 …

Notes: One UPDATE carries one set of attributes, and every prefix that shares them. The withdrawn and NLRI fields can only hold IPv4; the next slides show where IPv6 goes. Lengths everywhere: a receiver can walk the message without understanding any of it, which is what lets unknown attributes pass through.


An example BGP update

headerlengthspath attributesNLRI
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00 59 02 00 00 00 42 40 01 01 00 40 02 06 02 01 00 03 34 74 80 04 04 00 00 00 00 80 0e 1c 00 02 01 10 20 01 07 f8 00 24 00 00 00 00 00 00 00 00 00 c9 00 30 2a 0d d7 40 00 00 c0 20 0c 00 03 34 74 00 00 00 0a 00 00 00 02

2a0d:d740::/48, as AS210036 announces it to the SwissIX route servers.

Notes: Built with the lab daemon's own encoder and checked by parsing it back, with the attributes pr01 puts on routes it exports to peers. Press down to walk through it part by part. Note there is nothing yellow: the NLRI field is empty. Hold that thought.


Header

ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00 59 02 00 00 00 42 40 01 01 00 40 02 06 02 01 00 03 34 74 80 04 04 00 00 00 00 80 0e 1c 00 02 01 10 20 01 07 f8 00 24 00 00 00 00 00 00 00 00 00 c9 00 30 2a 0d d7 40 00 00 c0 20 0c 00 03 34 74 00 00 00 0a 00 00 00 02
ff × 16Start of message marker.
00 59length of the whole message: 89 bytes (maximum 4096)
02type 2 = UPDATE

Two lengths

ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00 59 02 00 00 00 42 40 01 01 00 40 02 06 02 01 00 03 34 74 80 04 04 00 00 00 00 80 0e 1c 00 02 01 10 20 01 07 f8 00 24 00 00 00 00 00 00 00 00 00 c9 00 30 2a 0d d7 40 00 00 c0 20 0c 00 03 34 74 00 00 00 0a 00 00 00 02
00 000 bytes of withdrawn routes: nothing is being taken back
00 4266 bytes of path attributes follow
89 − 19 − 2 − 2 − 66 = 0 bytes left over for NLRI

ORIGIN

ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00 59 02 00 00 00 42 40 01 01 00 40 02 06 02 01 00 03 34 74 80 04 04 00 00 00 00 80 0e 1c 00 02 01 10 20 01 07 f8 00 24 00 00 00 00 00 00 00 00 00 c9 00 30 2a 0d d7 40 00 00 c0 20 0c 00 03 34 74 00 00 00 0a 00 00 00 02
40flags: well-known, transitive
01type 1 = ORIGIN
011 byte of value
00IGP: the route was originated inside this AS

Every attribute is flags, type, length, value.


AS_PATH

ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00 59 02 00 00 00 42 40 01 01 00 40 02 06 02 01 00 03 34 74 80 04 04 00 00 00 00 80 0e 1c 00 02 01 10 20 01 07 f8 00 24 00 00 00 00 00 00 00 00 00 c9 00 30 2a 0d d7 40 00 00 c0 20 0c 00 03 34 74 00 00 00 0a 00 00 00 02
40 02 06well-known, transitive; type 2; 6 bytes
02an AS_SEQUENCE, order matters
01of 1 AS number
00 03 34 74210036, the origin. Four bytes each (RFC 6793)

Every BGP router prepends its own AS number before announcing a route to an external peer, creating a map of which networks the announcement travelled through. This allows selecting the shortest path.

Notes: One entry, because SwissIX is one hop from the origin and the route server does not add itself. Seen from further away it reads e.g. 6939 210036.


MULTI_EXIT_DISC

ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00 59 02 00 00 00 42 40 01 01 00 40 02 06 02 01 00 03 34 74 80 04 04 00 00 00 00 80 0e 1c 00 02 01 10 20 01 07 f8 00 24 00 00 00 00 00 00 00 00 00 c9 00 30 2a 0d d7 40 00 00 c0 20 0c 00 03 34 74 00 00 00 0a 00 00 00 02
80 04 04optional, non-transitive; type 4; 4 bytes
00 00 00 00MED 0. Lower is preferred, among routes from the same neighbour AS

A hint to a neighbour about which path you prefer traffic to come in on. Non-transitive: it goes one hop and no further.


MP_REACH_NLRI: announcing paths for non-IPv4 protocols

ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00 59 02 00 00 00 42 40 01 01 00 40 02 06 02 01 00 03 34 74 80 04 04 00 00 00 00 80 0e 1c 00 02 01 10 20 01 07 f8 00 24 00 00 00 00 00 00 00 00 00 c9 00 30 2a 0d d7 40 00 00 c0 20 0c 00 03 34 74 00 00 00 0a 00 00 00 02
80 0e 1coptional, non-transitive; type 14; 28 bytes
00 02 · 01address family IPv6, unicast
10 · 2001 07f8 0024 … 00c9next hop, 16 bytes: 2001:7f8:24::c9, our port on the SwissIX peering LAN
00reserved
30 · 2a 0d d7 40 00 0048 bits of prefix: 2a0d:d740::/48

Notes: BGP-4 was built for IPv4: its NLRI field cannot carry anything else. RFC 4760 bolts other address families on as an attribute, each with its own next hop. A prefix is sent as a bit count plus only as many bytes as the count needs. The next hop is an address on the exchange's shared LAN: whoever receives this route sends packets straight to that address across the switch. Remember ::c9 for the exchange diagram in the next section. Routers may also append their link-local address here, making it 32 bytes.


LARGE_COMMUNITIES

ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00 59 02 00 00 00 42 40 01 01 00 40 02 06 02 01 00 03 34 74 80 04 04 00 00 00 00 80 0e 1c 00 02 01 10 20 01 07 f8 00 24 00 00 00 00 00 00 00 00 00 c9 00 30 2a 0d d7 40 00 00 c0 20 0c 00 03 34 74 00 00 00 0a 00 00 00 02
c0 20 0coptional, transitive; type 32; 12 bytes = one community
00033474 · 0000000a · 00000002210036:10:2, a tag our router puts on everything it exports to peers

Three 32-bit numbers. They mean whatever the network named in the first one says they mean.


The flags byte

Bit Set means Clear means
0x80 optional well-known: every BGP speaker must understand it
0x40 transitive: pass it on, even if not understood drop it at the next hop
0x20 partial: someone on the way did not understand it
0x10 length field is 2 bytes 1 byte

Path attribute transitivity allows adding instructions for networks far away from direct neighbours.