diff --git a/slides/README.md b/slides/README.md index 323f079..1198b31 100644 --- a/slides/README.md +++ b/slides/README.md @@ -19,10 +19,18 @@ chain of nodes and links, an AS path. | IP transit and Internet exchanges | `sections/04-transit-and-ix.md` | | The lab: ferrix, pr01.rue and its exchanges | `sections/05-lab.md` | -The UPDATE in section 3 is a real one captured from ferrix. Its byte slides -step through it one part at a time (press down); every number on them was -checked against the capture when the slides were generated. If you replace the -capture, regenerate rather than edit the hex by hand. +The UPDATE in section 3 is `2a0d:d740::/48` as AS210036 announces it to the +SwissIX route servers: next hop `2001:7f8:24::c9` (pr01's port on the peering +LAN), MED 0 and the `210036:10:2` tag, which is what pr01's export filter puts +on routes to peers. It was produced with ferrix's own encoder and parsed back +to the same message, not captured off the wire; a capture from pr01 may differ +in detail (BIRD can append a link-local next hop). The byte slides step through +it one part at a time (press down), and every number on them was checked +against the bytes when the slides were generated. To change the example, +regenerate rather than edit the hex by hand. + +The deck deliberately has no fragments or stepped code: a slide shows +everything at once. Two code blocks keep a static highlight on one line. | File | Holds | |---|---| @@ -75,8 +83,6 @@ Apply a class to the element above with ``. | Class | Effect | |---|---| -| `fragment` | appears on the next click | -| `fragment pop` | appears, grows and takes the accent colour | | `big` | one large statement on the slide | | `note` | quiet italic aside | | `attribution` | small credit under an image or quote | diff --git a/slides/sections/01-addresses.md b/slides/sections/01-addresses.md index 4093d10..a8f75f8 100644 --- a/slides/sections/01-addresses.md +++ b/slides/sections/01-addresses.md @@ -29,7 +29,7 @@ Ask: why only once? Because 2a0d::1::1 could put the zeros in several places.

2a0d:d741:0001xxxx:xxxx:xxxx:xxxx:xxxx

-The first 48 bits are fixed. The other 80 are yours. +The first **48** bits are fixed. The other 80 are yours. Notes: 2^80 addresses in one student prefix. About 1.2 million billion billion. @@ -48,7 +48,7 @@ The /n is a count of leading bits, nothing more. `` is your student number, written *in hex*. - + Notes: Student 10 is 2a0d:d741:a::/48, student 16 is 2a0d:d741:10::/48. @@ -58,7 +58,7 @@ A /40 holds exactly 256 /48s, which caps the class size at 255. ## The most specific route wins -```text [1-3|3] +```text [3] 2a0d:d740::/29 via AS210036 the aggregate 2a0d:d741::/40 via AS210036 the lab 2a0d:d741:1::/48 via AS210036 AS… student 1 <-- chosen for 2a0d:d741:1::1 diff --git a/slides/sections/02-registries.md b/slides/sections/02-registries.md index 9269e99..6b72787 100644 --- a/slides/sections/02-registries.md +++ b/slides/sections/02-registries.md @@ -26,14 +26,14 @@ an RIR, typically an ISP. Our space comes from RIPE NCC via an LIR. ## AS numbers -* 16 bits at first: `1` to `65535` -* 32 bits since RFC 6793: up to `4294967295` -* Old routers see `AS23456` (AS_TRANS) in place of a big one -* Private use: `64512–65534` and `4200000000–4294967294` +* 16 bits at first: `1` to `65535` +* 32 bits since RFC 6793: up to `4294967295` +* Old routers see `AS23456` (AS_TRANS) in place of a big one +* Private use: `64512–65534` and `4200000000–4294967294` The lab daemon is `AS4200000001`. It is stripped before the Internet sees your route. - + Notes: RFC 6996 reserves the private ranges. The upstream router removes the private @@ -43,7 +43,7 @@ AS from the path, so the origin everybody else sees is AS210036. ## The RIPE database says who may announce what -```text [1-5|3] +```text [3] route6: 2a0d:d741:1::/48 descr: ETHZ Netsec 2026 BGP lab - student 1 origin: AS210036 diff --git a/slides/sections/03-bgp-update.md b/slides/sections/03-bgp-update.md index ec83090..cb592f7 100644 --- a/slides/sections/03-bgp-update.md +++ b/slides/sections/03-bgp-update.md @@ -7,10 +7,10 @@ Section 3. The aim: by the end, the bytes view on the lab page reads like text. ## BGP in one slide -* Runs over TCP, port `179`, between neighbours you configure by hand -* Each side tells the other its best route per prefix -* Only *changes* are sent: no periodic refresh -* If the session drops, every route learned over it is gone +* Runs over TCP, port `179`, between neighbours you configure by hand +* Each side tells the other its best route per prefix +* Only *changes* are sent: no periodic refresh +* If the session drops, every route learned over it is gone Notes: No discovery, no authentication of content, no notion of truth. A neighbour @@ -29,7 +29,7 @@ says "I can reach X" and you believe it, subject to your filters. OPEN, OPEN, KEEPALIVE, KEEPALIVE, and then it is all UPDATEs. - + Notes: There is a fifth, ROUTE-REFRESH: "send me everything again, my policy changed". @@ -51,41 +51,43 @@ One UPDATE carries one set of attributes, and every prefix that shares them. ----- -## A real one: 94 bytes +## A real one: 89 bytes
headerlengthspath attributesNLRI
-
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00 5e 02 00 00 00 47 40 01 01 00 40 02 06 02 01 fa 56 ea 01 80 0e 1c 00 02 01 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 30 2a 0d d7 41 00 01 c0 20 18 00 03 34 74 00 00 00 00 00 00 00 00 00 03 34 74 00 00 00 01 00 00 a5 ec
+
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:d741:1::/48`, as the lab daemon sent it. The same view is on the lab page under *bytes*. +`2a0d:d740::/48`, as AS210036 announces it to the SwissIX route servers. Notes: -Captured from ferrix, not typed. Press down to walk through it part by part. -Note there is nothing yellow: the NLRI field is empty. Hold that thought. +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 5e 02 00 00 00 47 40 01 01 00 40 02 06 02 01 fa 56 ea 01 80 0e 1c 00 02 01 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 30 2a 0d d7 41 00 01 c0 20 18 00 03 34 74 00 00 00 00 00 00 00 00 00 03 34 74 00 00 00 01 00 00 a5 ec
+
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 × 16marker. Once carried authentication, now just filler to find message boundaries
00 5elength of the whole message: 94 bytes (maximum 4096)
02type 2 = UPDATE
+
ff × 16marker. Once carried authentication, now just filler to find message boundaries
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 5e 02 00 00 00 47 40 01 01 00 40 02 06 02 01 fa 56 ea 01 80 0e 1c 00 02 01 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 30 2a 0d d7 41 00 01 c0 20 18 00 03 34 74 00 00 00 00 00 00 00 00 00 03 34 74 00 00 00 01 00 00 a5 ec
+
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 4771 bytes of path attributes follow
94 − 19 − 2 − 2 − 71 = 0 bytes left over for NLRI
+
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 5e 02 00 00 00 47 40 01 01 00 40 02 06 02 01 fa 56 ea 01 80 0e 1c 00 02 01 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 30 2a 0d d7 41 00 01 c0 20 18 00 03 34 74 00 00 00 00 00 00 00 00 00 03 34 74 00 00 00 01 00 00 a5 ec
+
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
@@ -97,37 +99,56 @@ 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 5e 02 00 00 00 47 40 01 01 00 40 02 06 02 01 fa 56 ea 01 80 0e 1c 00 02 01 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 30 2a 0d d7 41 00 01 c0 20 18 00 03 34 74 00 00 00 00 00 00 00 00 00 03 34 74 00 00 00 01 00 00 a5 ec
+
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
fa 56 ea 014200000001, the lab daemon. Four bytes each (RFC 6793)
+
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)
Each network prepends itself on the way out. The length of this list is what best-path selection compares. +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 of *your* entrances to use. Non-transitive: it goes one hop and no further. + + + --- ## MP_REACH_NLRI: where IPv6 lives -
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00 5e 02 00 00 00 47 40 01 01 00 40 02 06 02 01 fa 56 ea 01 80 0e 1c 00 02 01 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 30 2a 0d d7 41 00 01 c0 20 18 00 03 34 74 00 00 00 00 00 00 00 00 00 03 34 74 00 00 00 01 00 00 a5 ec
+
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 · 00…01next hop, 16 bytes: ::1
00reserved
30 · 2a 0d d7 41 00 0148 bits of prefix: 2a0d:d741:1::/48
+
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 ::1 because the daemon and the router share a machine. +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 5e 02 00 00 00 47 40 01 01 00 40 02 06 02 01 fa 56 ea 01 80 0e 1c 00 02 01 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 30 2a 0d d7 41 00 01 c0 20 18 00 03 34 74 00 00 00 00 00 00 00 00 00 03 34 74 00 00 00 01 00 00 a5 ec
+
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 18optional, transitive; type 32; 24 bytes = two communities
00033474 · 0 · 0210036:0:0 our router: announce nowhere…
00033474 · 1 · 0000a5ec210036:1:42476 …except to AS42476, the SwissIX route servers
+
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 receiving network says they mean. +Three 32-bit numbers. They mean whatever the network named in the first one says they mean. @@ -144,4 +165,4 @@ Three 32-bit numbers. They mean whatever the receiving network says they mean. Transitive is why a community you set can act three networks away. - + diff --git a/slides/sections/04-transit-and-ix.md b/slides/sections/04-transit-and-ix.md index ea8ce0f..1500ce5 100644 --- a/slides/sections/04-transit-and-ix.md +++ b/slides/sections/04-transit-and-ix.md @@ -68,10 +68,10 @@ a5ec is 42476 in hex: the route server's address spells its AS number. ## What that implies -* Your neighbour is *on your LAN*: one hop, found by neighbour discovery -* A route's next hop is the peer's LAN address, so traffic goes **directly** member to member -* The exchange never routes your packets. It switches frames -* So the LAN is policed hard: one MAC address per port, no stray broadcasts, no proxy ARP +* Your neighbour is *on your LAN*: one hop, found by neighbour discovery +* A route's next hop is the peer's LAN address, so traffic goes **directly** member to member +* The exchange never routes your packets. It switches frames +* So the LAN is policed hard: one MAC address per port, no stray broadcasts, no proxy ARP Notes: A misbehaving port can hurt every member, which is why exchanges publish strict @@ -83,10 +83,10 @@ rules for what may appear on the peering LAN and quarantine ports that break the Without one, peering with 200 members is 200 BGP sessions. -* One session to the route server brings routes from everyone who uses it -* It is **not** in the traffic path, and leaves the next hop alone -* It does not add its own AS to the path -* You steer it with communities: `42476:0:` "not to them", `42476:1:` "only to them" +* One session to the route server brings routes from everyone who uses it +* It is **not** in the traffic path, and leaves the next hop alone +* It does not add its own AS to the path +* You steer it with communities: `42476:0:` "not to them", `42476:1:` "only to them" Notes: A route server is a BGP speaker that only redistributes. Because it is diff --git a/slides/sections/05-lab.md b/slides/sections/05-lab.md index 4ddc2e6..59a8430 100644 --- a/slides/sections/05-lab.md +++ b/slides/sections/05-lab.md @@ -36,9 +36,9 @@ the right of pr01 is the actual Internet. `2a0d:d741:::/48` -* `` is your number **in hex**: student 10 is `2a0d:d741:a::/48` -* Put your name in *owner*: only the owner can withdraw a route -* One prefix each +* `` is your number **in hex**: student 10 is `2a0d:d741:a::/48` +* Put your name in *owner*: only the owner can withdraw a route +* One prefix each Notes: Put the URL and the class password on the board. The page is a snapshot by @@ -48,11 +48,11 @@ default; turn on auto-refresh at the top right to watch things change. ## What happens when you press *Announce* -1. ferrix builds an UPDATE. Click *bytes* to see it, hover to decode it -2. pr01 checks it against its import filter -3. pr01 decides, per neighbour, whether to pass it on -4. Within a minute or so, the Internet can see your prefix -5. `ping 2a0d:d741:::1` answers, from anywhere +1. ferrix builds an UPDATE. Click *bytes* to see it, hover to decode it +2. pr01 checks it against its import filter +3. pr01 decides, per neighbour, whether to pass it on +4. Within a minute or so, the Internet can see your prefix +5. `ping 2a0d:d741:::1` answers, from anywhere Notes: Step 5: pr01 answers for every address in the lab space, so reachability of @@ -60,29 +60,6 @@ your prefix depends only on whether your announcement got out. ----- -## What stands between you and an outage - -```bird [2-3|5-7|9] -filter ferrix_import { - if !(net ~ [ 2a0d:d741::/40{48,48} ]) then reject; # only lab /48s - if bgp_path.first != 4200000001 then reject; # only from ferrix - - bgp_community.filter([ (65535, 65281), (65535, 65282) ]); - bgp_large_community.filter([ (42476, *, *), (210036, 0..3, *) ]); - bgp_ext_community.empty; # drop what we did not offer - - dest = RTD_UNREACHABLE; # announce-only - accept; -} -``` - -Notes: -This is the router's real import filter. ferrix refuses anything outside the -lab /40 before it gets this far, and pr01 takes at most 130 routes from it. -Two independent nets, because the web form has no idea who you are. - ------ - ## Steering your route | You add | Who acts | Effect | @@ -95,7 +72,7 @@ Two independent nets, because the web form has no idea who you are. Same idea at two hops: *never there*, *only there*, *nowhere*. - + Notes: 210036:0: never to that AS, 210036:1: to that AS, 210036:2/3: the diff --git a/slides/style.css b/slides/style.css index 7b0dacb..8a01d05 100644 --- a/slides/style.css +++ b/slides/style.css @@ -31,18 +31,6 @@ color: var(--ink-strong); } -/* A fragment that grows when it appears, for the one thing to look at. It - grows by font size, not transform, so the text around it makes room. */ -.reveal .pop { - transition: font-size 0.4s ease, color 0.4s ease; -} - -.reveal .pop.visible { - font-size: 1.5em; - font-weight: 700; - color: var(--accent); -} - /* ---- layout ------------------------------------------------------------------ */ .container {