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>
330 lines
24 KiB
Markdown
330 lines
24 KiB
Markdown
# 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.
|
||
|
||
<!-- .element: class="note" -->
|
||
|
||
Notes:
|
||
There is actually a fifth type, ROUTE-REFRESH: "send me everything again, my policy changed".
|
||
|
||
---
|
||
|
||
## OPEN: a handshake between peers.
|
||
|
||
<svg class="diagram" viewBox="0 0 1000 340" role="img" aria-label="An OPEN message: the common header, then version, AS number, hold time, BGP identifier, and optional parameters that carry the capabilities">
|
||
<text x="20" y="22" class="left small pkt-title">header, the same on every message: 19 bytes</text>
|
||
<g class="pkt hh"><rect x="20" y="30" width="470" height="64" rx="6"/></g>
|
||
<text x="255" y="59" class="pkt-name">marker</text>
|
||
<text x="255" y="81" class="pkt-size">16 bytes, all ff</text>
|
||
<g class="pkt hh"><rect x="494" y="30" width="240" height="64" rx="6"/></g>
|
||
<text x="614" y="59" class="pkt-name">length</text>
|
||
<text x="614" y="81" class="pkt-size">2 bytes</text>
|
||
<g class="pkt hh"><rect x="738" y="30" width="242" height="64" rx="6"/></g>
|
||
<text x="859" y="59" class="pkt-name">type</text>
|
||
<text x="859" y="81" class="pkt-size">1 byte</text>
|
||
<text x="20" y="132" class="left small pkt-title">OPEN: the fixed part</text>
|
||
<g class="pkt hl"><rect x="20" y="140" width="150" height="64" rx="6"/></g>
|
||
<text x="95" y="169" class="pkt-name">version</text>
|
||
<text x="95" y="191" class="pkt-size">1 byte: 4</text>
|
||
<g class="pkt hl"><rect x="174" y="140" width="200" height="64" rx="6"/></g>
|
||
<text x="274" y="169" class="pkt-name">my AS</text>
|
||
<text x="274" y="191" class="pkt-size">2 bytes, or 23456</text>
|
||
<g class="pkt hl"><rect x="378" y="140" width="200" height="64" rx="6"/></g>
|
||
<text x="478" y="169" class="pkt-name">hold time</text>
|
||
<text x="478" y="191" class="pkt-size">2 bytes, seconds</text>
|
||
<g class="pkt hl"><rect x="582" y="140" width="240" height="64" rx="6"/></g>
|
||
<text x="702" y="169" class="pkt-name">BGP identifier</text>
|
||
<text x="702" y="191" class="pkt-size">4 bytes, the router ID</text>
|
||
<g class="pkt hl"><rect x="826" y="140" width="154" height="64" rx="6"/></g>
|
||
<text x="903" y="169" class="pkt-name">opt. length</text>
|
||
<text x="903" y="191" class="pkt-size">1 byte</text>
|
||
<path class="pkt-expand" d="M 826 204 L 20 250"/>
|
||
<path class="pkt-expand" d="M 980 204 L 980 250"/>
|
||
<text x="20" y="250" class="left small pkt-title">optional parameters: today always one, of type 2 = capabilities, each a (code, length, value)</text>
|
||
<g class="pkt ha"><rect x="20" y="258" width="120" height="64" rx="6"/></g>
|
||
<text x="80" y="287" class="pkt-name">type 2</text>
|
||
<text x="80" y="309" class="pkt-size">capabilities</text>
|
||
<g class="pkt ha"><rect x="144" y="258" width="110" height="64" rx="6"/></g>
|
||
<text x="199" y="287" class="pkt-name">length</text>
|
||
<text x="199" y="309" class="pkt-size">1 byte</text>
|
||
<g class="pkt ha2"><rect x="258" y="258" width="200" height="64" rx="6"/></g>
|
||
<text x="358" y="287" class="pkt-name">IPv6 unicast</text>
|
||
<text x="358" y="309" class="pkt-size">code 1: AFI 2, SAFI 1</text>
|
||
<g class="pkt ha2"><rect x="462" y="258" width="190" height="64" rx="6"/></g>
|
||
<text x="557" y="287" class="pkt-name">4-byte AS</text>
|
||
<text x="557" y="309" class="pkt-size">code 65: 210036</text>
|
||
<g class="pkt ha2"><rect x="656" y="258" width="170" height="64" rx="6"/></g>
|
||
<text x="741" y="287" class="pkt-name">route refresh</text>
|
||
<text x="741" y="309" class="pkt-size">code 2, empty</text>
|
||
<g class="pkt ha2"><rect x="830" y="258" width="150" height="64" rx="6"/></g>
|
||
<text x="905" y="287" class="pkt-name">…</text>
|
||
<text x="905" y="309" class="pkt-size">more capabilities</text>
|
||
</svg>
|
||
|
||
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
|
||
|
||
<div class="bytewalk">
|
||
<pre class="bytes bw-dump"><span class="hh" data-i="0">ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff</span> <span class="hh" data-i="1">00 37</span> <span class="hh" data-i="2">01</span> <span class="hl" data-i="3">04</span> <span class="hl" data-i="4">5b a0</span> <span class="hl" data-i="5">00 f0</span> <span class="hl" data-i="6">0a ff 00 01</span> <span class="hl" data-i="7">1a</span> <span class="ha" data-i="8">02</span> <span class="ha" data-i="9">18</span> <span class="ha2" data-i="10">01</span> <span class="ha2" data-i="11">04</span> <span class="ha2" data-i="12">00 02</span> <span class="ha2" data-i="13">00</span> <span class="ha2" data-i="14">01</span> <span class="ha2" data-i="15">02</span> <span class="ha2" data-i="16">00</span> <span class="ha2" data-i="17">06</span> <span class="ha2" data-i="18">00</span> <span class="ha2" data-i="19">40</span> <span class="ha2" data-i="20">02</span> <span class="ha2" data-i="21">00 00</span> <span class="ha2" data-i="22">41</span> <span class="ha2" data-i="23">04</span> <span class="ha2" data-i="24">00 03 34 74</span> <span class="ha2" data-i="25">46</span> <span class="ha2" data-i="26">00</span> <span class="ha2" data-i="27">47</span> <span class="ha2" data-i="28">00</span></pre>
|
||
<div class="bw-rows">
|
||
<div class="bw-group">BGP header: 19 bytes, on every message</div>
|
||
<div class="bw-row" data-i="0" tabindex="0"><code class="hh">ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff</code><b>marker</b><span>sixteen bytes of ff.</span></div>
|
||
<div class="bw-row" data-i="1" tabindex="0"><code class="hh">00 37</code><b>length</b><span>0x0037 = 55 bytes, header included. At most 4096, or 65535 with the extended-message capability</span></div>
|
||
<div class="bw-row" data-i="2" tabindex="0"><code class="hh">01</code><b>type</b><span>1 = OPEN (2 UPDATE, 3 NOTIFICATION, 4 KEEPALIVE, 5 ROUTE-REFRESH)</span></div>
|
||
<div class="bw-group">OPEN: the fixed part, 10 bytes</div>
|
||
<div class="bw-row" data-i="3" tabindex="0"><code class="hl">04</code><b>version</b><span>BGP version 4</span></div>
|
||
<div class="bw-row" data-i="4" tabindex="0"><code class="hl">5b a0</code><b>my AS</b><span>0x5ba0 = 23456, AS_TRANS: the ASN is longer than 16 bits so is encoded in a capability instead</span></div>
|
||
<div class="bw-row" data-i="5" tabindex="0"><code class="hl">00 f0</code><b>hold time</b><span>0x00f0 = 240 seconds. both peers use the minimum announced; a KEEPALIVE typically is sent every 1/3rd of this duration</span></div>
|
||
<div class="bw-row" data-i="6" tabindex="0"><code class="hl">0a ff 00 01</code><b>BGP identifier</b><span>0a ff 00 01 = 10.255.0.1, the router ID. Looks like an IPv4 address, just needs to be a unique identifier.</span></div>
|
||
<div class="bw-row" data-i="7" tabindex="0"><code class="hl">1a</code><b>optional parameters length</b><span>0x1a = 26 bytes follow</span></div>
|
||
<div class="bw-group">Optional parameter: 2 + 24 bytes</div>
|
||
<div class="bw-row" data-i="8" tabindex="0"><code class="ha">02</code><b>parameter type</b><span>2 = capabilities</span></div>
|
||
<div class="bw-row" data-i="9" tabindex="0"><code class="ha">18</code><b>parameter length</b><span>0x18 = 24 bytes of capabilities follow, each as type, length, value</span></div>
|
||
<div class="bw-group">Capability 1: multiprotocol (RFC 4760)</div>
|
||
<div class="bw-row" data-i="10" tabindex="0"><code class="ha2">01</code><b>code</b><span>1 = multiprotocol extensions</span></div>
|
||
<div class="bw-row" data-i="11" tabindex="0"><code class="ha2">04</code><b>length</b><span>4</span></div>
|
||
<div class="bw-row" data-i="12" tabindex="0"><code class="ha2">00 02</code><b>AFI</b><span>0x0002 = IPv6. Address Family Identifier</span></div>
|
||
<div class="bw-row" data-i="13" tabindex="0"><code class="ha2">00</code><b>reserved</b><span>0</span></div>
|
||
<div class="bw-row" data-i="14" tabindex="0"><code class="ha2">01</code><b>SAFI</b><span>1 = unicast. Subsequent Address Family Identifier.</span></div>
|
||
<div class="bw-group">Capability 2: route refresh (RFC 2918)</div>
|
||
<div class="bw-row" data-i="15" tabindex="0"><code class="ha2">02</code><b>code</b><span>2 = route refresh: “you may ask me to resend everything”</span></div>
|
||
<div class="bw-row" data-i="16" tabindex="0"><code class="ha2">00</code><b>length</b><span>0</span></div>
|
||
<div class="bw-group">Capability 6: extended message (RFC 8654)</div>
|
||
<div class="bw-row" data-i="17" tabindex="0"><code class="ha2">06</code><b>code</b><span>6 = messages up to 65535 bytes are supported</span></div>
|
||
<div class="bw-row" data-i="18" tabindex="0"><code class="ha2">00</code><b>length</b><span>0</span></div>
|
||
<div class="bw-group">Capability 64: graceful restart (RFC 4724)</div>
|
||
<div class="bw-row" data-i="19" tabindex="0"><code class="ha2">40</code><b>code</b><span>0x40 = 64, graceful restart</span></div>
|
||
<div class="bw-row" data-i="20" tabindex="0"><code class="ha2">02</code><b>length</b><span>2</span></div>
|
||
<div class="bw-row" data-i="21" tabindex="0"><code class="ha2">00 00</code><b>flags and restart time</b><span>0x0000: not restarting, restart time 0, and no address families listed.</span></div>
|
||
<div class="bw-group">Capability 65: four-octet AS (RFC 6793)</div>
|
||
<div class="bw-row" data-i="22" tabindex="0"><code class="ha2">41</code><b>code</b><span>0x41 = 65, four-octet AS number</span></div>
|
||
<div class="bw-row" data-i="23" tabindex="0"><code class="ha2">04</code><b>length</b><span>4</span></div>
|
||
<div class="bw-row" data-i="24" tabindex="0"><code class="ha2">00 03 34 74</code><b>AS number</b><span>00 03 34 74 = 210036: the real AS. Included here since it doesn't fit in the header</span></div>
|
||
<div class="bw-group">Capability 70: enhanced route refresh (RFC 7313)</div>
|
||
<div class="bw-row" data-i="25" tabindex="0"><code class="ha2">46</code><b>code</b><span>0x46 = 70</span></div>
|
||
<div class="bw-row" data-i="26" tabindex="0"><code class="ha2">00</code><b>length</b><span>0</span></div>
|
||
<div class="bw-group">Capability 71: long-lived graceful restart</div>
|
||
<div class="bw-row" data-i="27" tabindex="0"><code class="ha2">47</code><b>code</b><span>0x47 = 71</span></div>
|
||
<div class="bw-row" data-i="28" tabindex="0"><code class="ha2">00</code><b>length</b><span>0, no address families listed</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
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
|
||
|
||
<svg class="diagram" viewBox="0 0 1000 460" role="img" aria-label="An UPDATE message: the common header, then withdrawn routes, path attributes and NLRI, with one attribute and one prefix expanded">
|
||
<text x="20" y="22" class="left small pkt-title">header: 19 bytes</text>
|
||
<g class="pkt hh"><rect x="20" y="30" width="470" height="64" rx="6"/></g>
|
||
<text x="255" y="59" class="pkt-name">marker</text>
|
||
<text x="255" y="81" class="pkt-size">16 bytes, all ff</text>
|
||
<g class="pkt hh"><rect x="494" y="30" width="240" height="64" rx="6"/></g>
|
||
<text x="614" y="59" class="pkt-name">length</text>
|
||
<text x="614" y="81" class="pkt-size">2 bytes</text>
|
||
<g class="pkt hh"><rect x="738" y="30" width="242" height="64" rx="6"/></g>
|
||
<text x="859" y="59" class="pkt-name">type</text>
|
||
<text x="859" y="81" class="pkt-size">1 byte</text>
|
||
<text x="20" y="132" class="left small pkt-title">UPDATE body: two lengths, three variable parts</text>
|
||
<g class="pkt hl"><rect x="20" y="140" width="170" height="64" rx="6"/></g>
|
||
<text x="105" y="169" class="pkt-name">withdrawn length</text>
|
||
<text x="105" y="191" class="pkt-size">2 bytes</text>
|
||
<g class="pkt hn"><rect x="194" y="140" width="200" height="64" rx="6"/></g>
|
||
<text x="294" y="169" class="pkt-name">withdrawn routes</text>
|
||
<text x="294" y="191" class="pkt-size">IPv4 prefixes gone</text>
|
||
<g class="pkt hl"><rect x="398" y="140" width="170" height="64" rx="6"/></g>
|
||
<text x="483" y="169" class="pkt-name">attributes length</text>
|
||
<text x="483" y="191" class="pkt-size">2 bytes</text>
|
||
<g class="pkt ha"><rect x="572" y="140" width="240" height="64" rx="6"/></g>
|
||
<text x="692" y="169" class="pkt-name">path attributes</text>
|
||
<text x="692" y="191" class="pkt-size">everything about the route</text>
|
||
<g class="pkt hn"><rect x="816" y="140" width="172" height="64" rx="6"/></g>
|
||
<text x="902" y="169" class="pkt-name">NLRI</text>
|
||
<text x="902" y="191" class="pkt-size">IPv4 prefixes, new</text>
|
||
<path class="pkt-expand" d="M 572 204 L 20 250"/>
|
||
<path class="pkt-expand" d="M 812 204 L 980 250"/>
|
||
<text x="20" y="250" class="left small pkt-title">one path attribute; repeated for multiple</text>
|
||
<g class="pkt ha"><rect x="20" y="258" width="150" height="64" rx="6"/></g>
|
||
<text x="95" y="287" class="pkt-name">flags</text>
|
||
<text x="95" y="309" class="pkt-size">1 byte</text>
|
||
<g class="pkt ha"><rect x="174" y="258" width="330" height="64" rx="6"/></g>
|
||
<text x="339" y="287" class="pkt-name">type</text>
|
||
<text x="339" y="309" class="pkt-size">1 byte: ORIGIN = 1, AS_PATH = 2 …</text>
|
||
<g class="pkt ha"><rect x="508" y="258" width="180" height="64" rx="6"/></g>
|
||
<text x="598" y="287" class="pkt-name">length</text>
|
||
<text x="598" y="309" class="pkt-size">1 or 2 bytes</text>
|
||
<g class="pkt ha2"><rect x="692" y="258" width="292" height="64" rx="6"/></g>
|
||
<text x="838" y="287" class="pkt-name">value</text>
|
||
<text x="838" y="309" class="pkt-size">as many bytes as it said</text>
|
||
<path class="pkt-expand" d="M 979 204 L 979 376"/>
|
||
<text x="20" y="368" class="left small pkt-title">one prefix, in NLRI and in withdrawn routes: a bit count, then only the bytes that count needs</text>
|
||
<g class="pkt hn"><rect x="20" y="376" width="300" height="64" rx="6"/></g>
|
||
<text x="170" y="405" class="pkt-name">length</text>
|
||
<text x="170" y="427" class="pkt-size">1 byte: 24 for a /24</text>
|
||
<g class="pkt hn"><rect x="324" y="376" width="656" height="64" rx="6"/></g>
|
||
<text x="652" y="405" class="pkt-name">prefix</text>
|
||
<text x="652" y="427" class="pkt-size">3 bytes for a /24, 6 for a /48 …</text>
|
||
</svg>
|
||
|
||
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
|
||
|
||
<div class="legend"><span class="hh">header</span><span class="hl">lengths</span><span class="ha">path attributes</span><span class="hn">NLRI</span></div>
|
||
|
||
<pre class="bytes"><span class="hh">ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff</span> <span class="hh">00 59</span> <span class="hh">02</span> <span class="hl">00 00</span> <span class="hl">00 42</span> <span class="ha">40 01 01 00</span> <span class="ha2">40 02 06 02 01 00 03 34 74</span> <span class="ha">80 04 04 00 00 00 00</span> <span class="ha2">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</span> <span class="ha">c0 20 0c 00 03 34 74 00 00 00 0a 00 00 00 02</span></pre>
|
||
|
||
`2a0d:d740::/48`, as AS210036 announces it to the SwissIX route servers.
|
||
|
||
<!-- .element: class="note" -->
|
||
|
||
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
|
||
|
||
<pre class="bytes focus"><span class="hh on">ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff</span> <span class="hh on">00 59</span> <span class="hh on">02</span> <span class="hl">00 00</span> <span class="hl">00 42</span> <span class="ha">40 01 01 00</span> <span class="ha2">40 02 06 02 01 00 03 34 74</span> <span class="ha">80 04 04 00 00 00 00</span> <span class="ha2">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</span> <span class="ha">c0 20 0c 00 03 34 74 00 00 00 0a 00 00 00 02</span></pre>
|
||
|
||
<table class="decode"><tr><td>ff × 16</td><td>Start of message marker.</td></tr><tr><td>00 59</td><td>length of the whole message: 89 bytes (maximum 4096)</td></tr><tr><td>02</td><td>type 2 = UPDATE</td></tr></table>
|
||
|
||
---
|
||
|
||
## Two lengths
|
||
|
||
<pre class="bytes focus"><span class="hh">ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff</span> <span class="hh">00 59</span> <span class="hh">02</span> <span class="hl on">00 00</span> <span class="hl on">00 42</span> <span class="ha">40 01 01 00</span> <span class="ha2">40 02 06 02 01 00 03 34 74</span> <span class="ha">80 04 04 00 00 00 00</span> <span class="ha2">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</span> <span class="ha">c0 20 0c 00 03 34 74 00 00 00 0a 00 00 00 02</span></pre>
|
||
|
||
<table class="decode"><tr><td>00 00</td><td>0 bytes of withdrawn routes: nothing is being taken back</td></tr><tr><td>00 42</td><td>66 bytes of path attributes follow</td></tr><tr><td></td><td>89 − 19 − 2 − 2 − 66 = 0 bytes left over for NLRI</td></tr></table>
|
||
|
||
---
|
||
|
||
## ORIGIN
|
||
|
||
<pre class="bytes focus"><span class="hh">ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff</span> <span class="hh">00 59</span> <span class="hh">02</span> <span class="hl">00 00</span> <span class="hl">00 42</span> <span class="ha on">40 01 01 00</span> <span class="ha2">40 02 06 02 01 00 03 34 74</span> <span class="ha">80 04 04 00 00 00 00</span> <span class="ha2">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</span> <span class="ha">c0 20 0c 00 03 34 74 00 00 00 0a 00 00 00 02</span></pre>
|
||
|
||
<table class="decode"><tr><td>40</td><td>flags: well-known, transitive</td></tr><tr><td>01</td><td>type 1 = ORIGIN</td></tr><tr><td>01</td><td>1 byte of value</td></tr><tr><td>00</td><td>IGP: the route was originated inside this AS</td></tr></table>
|
||
|
||
Every attribute is _flags, type, length, value_.
|
||
|
||
<!-- .element: class="note" -->
|
||
|
||
---
|
||
|
||
## AS_PATH
|
||
|
||
<pre class="bytes focus"><span class="hh">ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff</span> <span class="hh">00 59</span> <span class="hh">02</span> <span class="hl">00 00</span> <span class="hl">00 42</span> <span class="ha">40 01 01 00</span> <span class="ha2 on">40 02 06 02 01 00 03 34 74</span> <span class="ha">80 04 04 00 00 00 00</span> <span class="ha2">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</span> <span class="ha">c0 20 0c 00 03 34 74 00 00 00 0a 00 00 00 02</span></pre>
|
||
|
||
<table class="decode"><tr><td>40 02 06</td><td>well-known, transitive; type 2; 6 bytes</td></tr><tr><td>02</td><td>an AS_SEQUENCE, order matters</td></tr><tr><td>01</td><td>of 1 AS number</td></tr><tr><td>00 03 34 74</td><td>210036, the origin. Four bytes each (RFC 6793)</td></tr></table>
|
||
|
||
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.
|
||
|
||
<!-- .element: class="note" -->
|
||
|
||
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
|
||
|
||
<pre class="bytes focus"><span class="hh">ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff</span> <span class="hh">00 59</span> <span class="hh">02</span> <span class="hl">00 00</span> <span class="hl">00 42</span> <span class="ha">40 01 01 00</span> <span class="ha2">40 02 06 02 01 00 03 34 74</span> <span class="ha on">80 04 04 00 00 00 00</span> <span class="ha2">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</span> <span class="ha">c0 20 0c 00 03 34 74 00 00 00 0a 00 00 00 02</span></pre>
|
||
|
||
<table class="decode"><tr><td>80 04 04</td><td>optional, non-transitive; type 4; 4 bytes</td></tr><tr><td>00 00 00 00</td><td>MED 0. Lower is preferred, among routes from the same neighbour AS</td></tr></table>
|
||
|
||
A hint to a neighbour about which path you prefer traffic to come in on. Non-transitive: it goes one hop and no further.
|
||
|
||
<!-- .element: class="note" -->
|
||
|
||
---
|
||
|
||
## MP_REACH_NLRI: announcing paths for non-IPv4 protocols
|
||
|
||
<pre class="bytes focus"><span class="hh">ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff</span> <span class="hh">00 59</span> <span class="hh">02</span> <span class="hl">00 00</span> <span class="hl">00 42</span> <span class="ha">40 01 01 00</span> <span class="ha2">40 02 06 02 01 00 03 34 74</span> <span class="ha">80 04 04 00 00 00 00</span> <span class="ha2 on">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</span> <span class="ha">c0 20 0c 00 03 34 74 00 00 00 0a 00 00 00 02</span></pre>
|
||
|
||
<table class="decode"><tr><td>80 0e 1c</td><td>optional, non-transitive; type 14; 28 bytes</td></tr><tr><td>00 02 · 01</td><td>address family IPv6, unicast</td></tr><tr><td>10 · 2001 07f8 0024 … 00c9</td><td>next hop, 16 bytes: 2001:7f8:24::c9, our port on the SwissIX peering LAN</td></tr><tr><td>00</td><td>reserved</td></tr><tr><td>30 · 2a 0d d7 40 00 00</td><td>48 bits of prefix: 2a0d:d740::/48</td></tr></table>
|
||
|
||
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
|
||
|
||
<pre class="bytes focus"><span class="hh">ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff</span> <span class="hh">00 59</span> <span class="hh">02</span> <span class="hl">00 00</span> <span class="hl">00 42</span> <span class="ha">40 01 01 00</span> <span class="ha2">40 02 06 02 01 00 03 34 74</span> <span class="ha">80 04 04 00 00 00 00</span> <span class="ha2">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</span> <span class="ha on">c0 20 0c 00 03 34 74 00 00 00 0a 00 00 00 02</span></pre>
|
||
|
||
<table class="decode"><tr><td>c0 20 0c</td><td>optional, transitive; type 32; 12 bytes = one community</td></tr><tr><td>00033474 · 0000000a · 00000002</td><td>210036:10:2, a tag our router puts on everything it exports to peers</td></tr></table>
|
||
|
||
Three 32-bit numbers. They mean whatever the network named in the first one says they mean.
|
||
|
||
<!-- .element: class="note" -->
|
||
|
||
---
|
||
|
||
## 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.
|
||
|
||
<!-- .element: class="note" -->
|