figdown 0.1.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/EXPRESSING.md +119 -0
- package/LAYOUT-GUIDE.md +367 -0
- package/LICENSE +21 -0
- package/README.md +201 -0
- package/README.zh-tw.md +185 -0
- package/SHOWCASE.md +421 -0
- package/dist/figdown.js +2239 -0
- package/dist/figdown.mjs +2231 -0
- package/examples/evpn-fabric.svg +54 -0
- package/examples/showcase/arp-resolution.svg +51 -0
- package/examples/showcase/ethernet-frame.svg +37 -0
- package/examples/showcase/l2-forwarding-logic.svg +42 -0
- package/examples/showcase/tcp-handshake.svg +56 -0
- package/examples/showcase/tcp-header.svg +47 -0
- package/examples/showcase/tcp-state-machine.svg +140 -0
- package/package.json +51 -0
- package/skill/figdown/build-svg.js +73 -0
- package/skill/figdown/figdown.html +3290 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 527 596" width="527" height="596" font-family="system-ui,sans-serif"><defs><marker id="arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 z" fill="#555"/></marker><pattern id="hatch" width="6" height="6" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><line x1="0" y1="0" x2="0" y2="6" stroke="#bbb" stroke-width="2"/></pattern></defs><g transform="translate(18,6)"><line data-edge="22" x1="157.16" y1="56" x2="96.44000000000003" y2="100" stroke="#555" stroke-width="1.6"/><line data-edge="23" x1="197.12" y1="56" x2="234.08000000000004" y2="100" stroke="#555" stroke-width="1.6"/><line data-edge="24" x1="221.2" y1="50.810457516339866" x2="371.72" y2="100" stroke="#555" stroke-width="1.6"/><line data-edge="25" x1="277.20000000000005" y1="50.810457516339866" x2="126.68000000000004" y2="100" stroke="#555" stroke-width="1.6"/><line data-edge="26" x1="301.28000000000003" y1="56" x2="264.32000000000005" y2="100" stroke="#555" stroke-width="1.6"/><line data-edge="27" x1="341.24000000000007" y1="56" x2="401.96000000000004" y2="100" stroke="#555" stroke-width="1.6"/><line data-edge="28" x1="69.98000000000002" y1="136" x2="66.02000000000001" y2="180" stroke="#555" stroke-width="1.6"/><line data-edge="29" x1="249.20000000000005" y1="136" x2="249.20000000000002" y2="180" stroke="#555" stroke-width="1.6"/><line data-edge="30" x1="428.4200000000001" y1="136" x2="432.38" y2="180" stroke="#555" stroke-width="1.6"/><line data-edge="34" x1="132.40000000000003" y1="118" x2="188.40000000000003" y2="118" stroke="#dc2626" stroke-width="1.6" stroke-dasharray="6 4"/><g data-node="sp1" data-x="142.8" data-y="20" style="cursor:move"><rect x="142.8" y="20" width="78.4" height="36" rx="14" fill="#e0e7ff" stroke="#8a8880" stroke-width="1.8"/><text x="182" y="42.55" font-size="13" text-anchor="middle" fill="#1d1d1b">Spine-1</text></g><g data-node="sp2" data-x="277.20000000000005" data-y="20" style="cursor:move"><rect x="277.20000000000005" y="20" width="78.4" height="36" rx="14" fill="#e0e7ff" stroke="#8a8880" stroke-width="1.8"/><text x="316.40000000000003" y="42.55" font-size="13" text-anchor="middle" fill="#1d1d1b">Spine-2</text></g><g data-node="lf1" data-x="10.800000000000011" data-y="100" style="cursor:move"><rect x="10.800000000000011" y="100" width="121.60000000000001" height="36" rx="14" fill="#fff" stroke="#8a8880" stroke-width="1.8"/><text x="71.60000000000002" y="122.55" font-size="13" text-anchor="middle" fill="#1d1d1b">Leaf-1 (VTEP)</text></g><g data-node="lf2" data-x="188.40000000000003" data-y="100" style="cursor:move"><rect x="188.40000000000003" y="100" width="121.60000000000001" height="36" rx="14" fill="#fff" stroke="#8a8880" stroke-width="1.8"/><text x="249.20000000000005" y="122.55" font-size="13" text-anchor="middle" fill="#1d1d1b">Leaf-2 (VTEP)</text></g><g data-node="lf3" data-x="366.00000000000006" data-y="100" style="cursor:move"><rect x="366.00000000000006" y="100" width="121.60000000000001" height="36" rx="14" fill="#fff" stroke="#8a8880" stroke-width="1.8"/><text x="426.80000000000007" y="122.55" font-size="13" text-anchor="middle" fill="#1d1d1b">Leaf-3 (VTEP)</text></g><g data-node="h1" data-x="0" data-y="180" style="cursor:move"><rect x="0" y="180" width="128.8" height="36" fill="#fff" stroke="#8a8880"/><text x="64.4" y="202.55" font-size="13" text-anchor="middle" fill="#1d1d1b">VM-A (VLAN 10)</text></g><g data-node="h2" data-x="184.8" data-y="180" style="cursor:move"><rect x="184.8" y="180" width="128.8" height="36" fill="#fff" stroke="#8a8880"/><text x="249.20000000000002" y="202.55" font-size="13" text-anchor="middle" fill="#1d1d1b">VM-B (VLAN 10)</text></g><g data-node="h3" data-x="369.6" data-y="180" style="cursor:move"><rect x="369.6" y="180" width="128.8" height="36" fill="#fff" stroke="#8a8880"/><text x="434" y="202.55" font-size="13" text-anchor="middle" fill="#1d1d1b">VM-C (VLAN 20)</text></g><text x="126.80000000000001" y="72.25" font-size="11" text-anchor="middle" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round">eBGP</text><text x="126.80000000000001" y="72.25" font-size="11" text-anchor="middle" fill="#555">eBGP</text><text x="160.40000000000003" y="112.25" font-size="11" text-anchor="middle" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round">VXLAN VNI 10010</text><text x="160.40000000000003" y="112.25" font-size="11" text-anchor="middle" fill="#dc2626">VXLAN VNI 10010</text><path d="M132.40000000000003 118 L142.48000000000005 112.4 L142.48000000000005 123.6 z" fill="#dc2626" stroke="none"/><path d="M188.40000000000003 118 L178.32000000000002 123.6 L178.32000000000002 112.4 z" fill="#dc2626" stroke="none"/><text x="0" y="240" font-size="13" font-weight="600">VNI mapping</text><rect x="0" y="248" width="71.2" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="vni:0:1" style="cursor:pointer"/><text x="35.6" y="265.3" font-size="12" text-anchor="middle" font-weight="600">Leaf</text><rect x="71.2" y="248" width="56.8" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="vni:0:2" style="cursor:pointer"/><text x="99.6" y="265.3" font-size="12" text-anchor="middle" font-weight="600">VLAN</text><rect x="128" y="248" width="64" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="vni:0:3" style="cursor:pointer"/><text x="160" y="265.3" font-size="12" text-anchor="middle" font-weight="600">VNI</text><rect x="192" y="248" width="56.8" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="vni:0:4" style="cursor:pointer"/><text x="220.4" y="265.3" font-size="12" text-anchor="middle" font-weight="600">Type</text><rect x="0" y="274" width="71.2" height="26" fill="#fff" stroke="#c9c7bf" data-cell="vni:1:1" style="cursor:pointer"/><text x="7" y="291.3" font-size="12" text-anchor="start">Leaf-1</text><rect x="71.2" y="274" width="56.8" height="26" fill="#fff" stroke="#c9c7bf" data-cell="vni:1:2" style="cursor:pointer"/><text x="99.6" y="291.3" font-size="12" text-anchor="middle">10</text><rect x="128" y="274" width="64" height="26" fill="#fee2e2" stroke="#c9c7bf" data-cell="vni:1:3" style="cursor:pointer"/><text x="135" y="291.3" font-size="12" text-anchor="start">10010</text><rect x="192" y="274" width="56.8" height="26" fill="#fff" stroke="#c9c7bf" data-cell="vni:1:4" style="cursor:pointer"/><text x="199" y="291.3" font-size="12" text-anchor="start">L2</text><rect x="0" y="300" width="71.2" height="26" fill="#fff" stroke="#c9c7bf" data-cell="vni:2:1" style="cursor:pointer"/><text x="7" y="317.3" font-size="12" text-anchor="start">Leaf-2</text><rect x="71.2" y="300" width="56.8" height="26" fill="#fff" stroke="#c9c7bf" data-cell="vni:2:2" style="cursor:pointer"/><text x="99.6" y="317.3" font-size="12" text-anchor="middle">10</text><rect x="128" y="300" width="64" height="26" fill="#fee2e2" stroke="#c9c7bf" data-cell="vni:2:3" style="cursor:pointer"/><text x="135" y="317.3" font-size="12" text-anchor="start">10010</text><rect x="192" y="300" width="56.8" height="26" fill="#fff" stroke="#c9c7bf" data-cell="vni:2:4" style="cursor:pointer"/><text x="199" y="317.3" font-size="12" text-anchor="start">L2</text><rect x="0" y="326" width="71.2" height="26" fill="#fff" stroke="#c9c7bf" data-cell="vni:3:1" style="cursor:pointer"/><text x="7" y="343.3" font-size="12" text-anchor="start">Leaf-3</text><rect x="71.2" y="326" width="56.8" height="26" fill="#fff" stroke="#c9c7bf" data-cell="vni:3:2" style="cursor:pointer"/><text x="99.6" y="343.3" font-size="12" text-anchor="middle">20</text><rect x="128" y="326" width="64" height="26" fill="#fff" stroke="#c9c7bf" data-cell="vni:3:3" style="cursor:pointer"/><text x="135" y="343.3" font-size="12" text-anchor="start">10020</text><rect x="192" y="326" width="56.8" height="26" fill="#fff" stroke="#c9c7bf" data-cell="vni:3:4" style="cursor:pointer"/><text x="199" y="343.3" font-size="12" text-anchor="start">L2</text><text x="0" y="396" font-size="13" font-weight="600">Fabric planes</text><rect x="0" y="404" width="136" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="planes:0:1" style="cursor:pointer"/><text x="68" y="421.3" font-size="12" text-anchor="middle" font-weight="600">Plane</text><rect x="136" y="404" width="143.2" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="planes:0:2" style="cursor:pointer"/><text x="207.6" y="421.3" font-size="12" text-anchor="middle" font-weight="600">Protocol</text><rect x="279.2" y="404" width="208" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="planes:0:3" style="cursor:pointer"/><text x="383.2" y="421.3" font-size="12" text-anchor="middle" font-weight="600">Role</text><rect x="0" y="430" width="136" height="26" fill="#fff" stroke="#c9c7bf" data-cell="planes:1:1" style="cursor:pointer"/><text x="7" y="447.3" font-size="12" text-anchor="start">Underlay</text><rect x="136" y="430" width="143.2" height="26" fill="#fff" stroke="#c9c7bf" data-cell="planes:1:2" style="cursor:pointer"/><text x="143" y="447.3" font-size="12" text-anchor="start">eBGP</text><rect x="279.2" y="430" width="208" height="26" fill="#fff" stroke="#c9c7bf" data-cell="planes:1:3" style="cursor:pointer"/><text x="286.2" y="447.3" font-size="12" text-anchor="start">loopback reachability</text><rect x="0" y="456" width="136" height="26" fill="#fff" stroke="#c9c7bf" data-cell="planes:2:1" style="cursor:pointer"/><text x="7" y="473.3" font-size="12" text-anchor="start">Overlay control</text><rect x="136" y="456" width="143.2" height="26" fill="#fff" stroke="#c9c7bf" data-cell="planes:2:2" style="cursor:pointer"/><text x="143" y="473.3" font-size="12" text-anchor="start">MP-BGP EVPN</text><rect x="279.2" y="456" width="208" height="26" fill="#fff" stroke="#c9c7bf" data-cell="planes:2:3" style="cursor:pointer"/><text x="286.2" y="473.3" font-size="12" text-anchor="start">MAC/IP route distribution</text><rect x="0" y="482" width="136" height="26" fill="#fff" stroke="#c9c7bf" data-cell="planes:3:1" style="cursor:pointer"/><text x="7" y="499.3" font-size="12" text-anchor="start">Overlay data</text><rect x="136" y="482" width="143.2" height="26" fill="#fff" stroke="#c9c7bf" data-cell="planes:3:2" style="cursor:pointer"/><text x="143" y="499.3" font-size="12" text-anchor="start">VXLAN (UDP 4789)</text><rect x="279.2" y="482" width="208" height="26" fill="#fff" stroke="#c9c7bf" data-cell="planes:3:3" style="cursor:pointer"/><text x="286.2" y="499.3" font-size="12" text-anchor="start">L2-in-L3 encapsulation</text><rect x="0" y="549" width="16" height="11" fill="#fff" stroke="#555"/><text x="21" y="558.5" font-size="11" fill="#1d1d1b">Physical underlay link — eBGP/L3 transport between leaf and spine</text><rect x="0" y="569" width="16" height="11" fill="#dc2626" stroke="#555" stroke-dasharray="6 4"/><text x="21" y="578.5" font-size="11" fill="#1d1d1b">Logical VXLAN overlay tunnel — rides on the physical underlay</text></g><metadata id="figdown-source" data-sha256="a4518bb370358dede9dc83a015667587b74d738a1d5b1112547d14c0eff955d8"><![CDATA[
|
|
2
|
+
figdown 0.1 topology
|
|
3
|
+
title "VXLAN/EVPN Leaf-Spine Fabric — topology with plane notes"
|
|
4
|
+
|
|
5
|
+
# ── Semantic classes ─────────────────────────────────────────────────
|
|
6
|
+
class underlay "Physical underlay link — eBGP/L3 transport between leaf and spine"
|
|
7
|
+
class overlay "Logical VXLAN overlay tunnel — rides on the physical underlay" style=dashed color=#dc2626
|
|
8
|
+
|
|
9
|
+
# ── Topology ────────────────────────────────────────────────────────
|
|
10
|
+
node sp1 "Spine-1" shape=rounded color=#e0e7ff
|
|
11
|
+
node sp2 "Spine-2" shape=rounded color=#e0e7ff
|
|
12
|
+
node lf1 "Leaf-1 (VTEP)" shape=rounded
|
|
13
|
+
node lf2 "Leaf-2 (VTEP)" shape=rounded
|
|
14
|
+
node lf3 "Leaf-3 (VTEP)" shape=rounded
|
|
15
|
+
node h1 "VM-A (VLAN 10)"
|
|
16
|
+
node h2 "VM-B (VLAN 10)"
|
|
17
|
+
node h3 "VM-C (VLAN 20)"
|
|
18
|
+
flow down
|
|
19
|
+
rank sp1 sp2
|
|
20
|
+
rank lf1 lf2 lf3
|
|
21
|
+
|
|
22
|
+
# underlay: every leaf peers with every spine
|
|
23
|
+
edge sp1 -[eBGP]- lf1 class=underlay
|
|
24
|
+
edge sp1 -- lf2 class=underlay
|
|
25
|
+
edge sp1 -- lf3 class=underlay
|
|
26
|
+
edge sp2 -- lf1 class=underlay
|
|
27
|
+
edge sp2 -- lf2 class=underlay
|
|
28
|
+
edge sp2 -- lf3 class=underlay
|
|
29
|
+
edge lf1 -- h1 class=underlay
|
|
30
|
+
edge lf2 -- h2 class=underlay
|
|
31
|
+
edge lf3 -- h3 class=underlay
|
|
32
|
+
|
|
33
|
+
# overlay: VXLAN tunnel between the two VTEPs sharing VNI 10010
|
|
34
|
+
layer overlay "VXLAN tunnels" z=2
|
|
35
|
+
edge lf1 <-[VXLAN VNI 10010]-> lf2 class=overlay layer=overlay
|
|
36
|
+
|
|
37
|
+
# ── Supplementary knowledge ─────────────────────────────────────────
|
|
38
|
+
table vni "VNI mapping"
|
|
39
|
+
| Leaf | VLAN | VNI | Type |
|
|
40
|
+
|--------|:----:|-------|------|
|
|
41
|
+
| Leaf-1 | 10 | 10010 | L2 |
|
|
42
|
+
| Leaf-2 | 10 | 10010 | L2 |
|
|
43
|
+
| Leaf-3 | 20 | 10020 | L2 |
|
|
44
|
+
cell 1,3 color=#fee2e2
|
|
45
|
+
cell 2,3 color=#fee2e2
|
|
46
|
+
|
|
47
|
+
table planes "Fabric planes"
|
|
48
|
+
| Plane | Protocol | Role |
|
|
49
|
+
|-----------------|-------------------|---------------------------|
|
|
50
|
+
| Underlay | eBGP | loopback reachability |
|
|
51
|
+
| Overlay control | MP-BGP EVPN | MAC/IP route distribution |
|
|
52
|
+
| Overlay data | VXLAN (UDP 4789) | L2-in-L3 encapsulation |
|
|
53
|
+
|
|
54
|
+
]]></metadata></svg>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 559 370" width="559" height="370" font-family="system-ui,sans-serif"><defs><marker id="arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 z" fill="#555"/></marker><pattern id="hatch" width="6" height="6" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><line x1="0" y1="0" x2="0" y2="6" stroke="#bbb" stroke-width="2"/></pattern></defs><g transform="translate(18,6)"><line data-edge="32" x1="172" y1="74.86640581330352" x2="365" y2="54.36892118501956" stroke="#dc2626" stroke-width="1.6" stroke-dasharray="6 4"/><line data-edge="33" x1="172" y1="95.46666666666667" x2="365" y2="121.2" stroke="#dc2626" stroke-width="1.6" stroke-dasharray="6 4"/><path data-edge="37" d="M443.8 72 L443.8 146 Q443.8 156 433.8 156 L96 156 Q86 156 86 146 L86 110" fill="none" stroke="#16a34a" stroke-width="1.6"/><g data-node="a" data-x="0" data-y="58" style="cursor:move"><rect x="0" y="58" width="172" height="52" fill="#fff" stroke="#8a8880"/><text x="86" y="80.1" font-size="13" text-anchor="middle" fill="#1d1d1b"><tspan x="86" dy="0">Host A</tspan><tspan x="86" dy="16.900000000000002">wants MAC for B's IP</tspan></text></g><g data-node="b" data-x="365" data-y="20" style="cursor:move"><rect x="365" y="20" width="157.6" height="52" fill="#fff" stroke="#8a8880"/><text x="443.8" y="42.099999999999994" font-size="13" text-anchor="middle" fill="#1d1d1b"><tspan x="443.8" dy="0">Host B</tspan><tspan x="443.8" dy="16.900000000000002">owns the target IP</tspan></text></g><text x="268.5" y="58.86766349916154" font-size="11" text-anchor="middle" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round">1: who-has B? (broadcast)</text><text x="268.5" y="58.86766349916154" font-size="11" text-anchor="middle" fill="#dc2626">1: who-has B? (broadcast)</text><path d="M365 54.36892118501956 L355.5677913970842 61.00215877092595 L354.38495222174663 49.864794114720844 z" fill="#dc2626" stroke="none"/><text x="268.5" y="102.58333333333334" font-size="11" text-anchor="middle" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round">1: heard, ignored</text><text x="268.5" y="102.58333333333334" font-size="11" text-anchor="middle" fill="#dc2626">1: heard, ignored</text><path d="M365 121.2 L354.2683059286093 125.41866594530529 L355.7485395936288 114.31691345765978 z" fill="#dc2626" stroke="none"/><text x="264.9" y="150.25" font-size="11" text-anchor="middle" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round">2: B is at aa:bb:cc:... A caches it</text><text x="264.9" y="150.25" font-size="11" text-anchor="middle" fill="#16a34a">2: B is at aa:bb:cc:... A caches it</text><path d="M86 110 L91.6 120.08 L80.4 120.08 z" fill="#16a34a" stroke="none"/><text x="381" y="119" font-size="10" text-anchor="start" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round"><tspan x="381" dy="0">rest of the LAN</tspan><tspan x="381" dy="13">(hosts C, D, ...)</tspan></text><text x="381" y="119" font-size="10" text-anchor="start" fill="#555"><tspan x="381" dy="0">rest of the LAN</tspan><tspan x="381" dy="13">(hosts C, D, ...)</tspan></text><text x="0" y="196" font-size="13" font-weight="600">Host A's ARP cache — before and after the exchange</text><rect x="0" y="204" width="164.8" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="cache:0:1" style="cursor:pointer"/><text x="82.4" y="221.3" font-size="12" text-anchor="middle" font-weight="600">Moment</text><rect x="164.8" y="204" width="359.2" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="cache:0:2" style="cursor:pointer"/><text x="344.4" y="221.3" font-size="12" text-anchor="middle" font-weight="600">Entry</text><rect x="0" y="230" width="164.8" height="26" fill="#fff" stroke="#c9c7bf" data-cell="cache:1:1" style="cursor:pointer"/><text x="7" y="247.3" font-size="12" text-anchor="start">before the exchange</text><rect x="164.8" y="230" width="359.2" height="26" fill="#fff" stroke="#c9c7bf" data-cell="cache:1:2" style="cursor:pointer"/><text x="171.8" y="247.3" font-size="12" text-anchor="start">(no entry for B's IP)</text><rect x="0" y="256" width="164.8" height="26" fill="#fff" stroke="#c9c7bf" data-cell="cache:2:1" style="cursor:pointer"/><text x="7" y="273.3" font-size="12" text-anchor="start">after segment 2</text><rect x="164.8" y="256" width="359.2" height="26" fill="#fff" stroke="#c9c7bf" data-cell="cache:2:2" style="cursor:pointer"/><text x="171.8" y="273.3" font-size="12" text-anchor="start">B's IP → aa:bb:cc:... , learned from the reply</text><rect x="0" y="323" width="16" height="11" fill="#dc2626" stroke="#555" stroke-dasharray="6 4"/><text x="21" y="332.5" font-size="11" fill="#1d1d1b">Broadcast — delivered to every host on the LAN (dst MAC ff:ff:ff:ff:ff:ff)</text><rect x="0" y="343" width="16" height="11" fill="#16a34a" stroke="#555"/><text x="21" y="352.5" font-size="11" fill="#1d1d1b">Unicast — delivered only to the requester (dst MAC = A's MAC)</text></g><metadata id="figdown-source" data-sha256="caa9e13ac4274b5a645a657feb74d396938d4457af8b4350c93ee3d48120e77f"><![CDATA[
|
|
2
|
+
figdown 0.1 topology
|
|
3
|
+
# ARP address resolution (RFC 826): Host A needs the MAC for B's IP.
|
|
4
|
+
# A broadcasts "who-has", B replies unicast, A caches the mapping.
|
|
5
|
+
# The broadcast vs unicast distinction is a CLASS (meaning in the label,
|
|
6
|
+
# dashed is only its presentation, R57) — presentation is never the sole
|
|
7
|
+
# carrier. "The rest of the LAN" is a boundary, not an invented node.
|
|
8
|
+
#
|
|
9
|
+
# HONEST LIMIT (EXPRESSING "strict message ordering"): step order rides on
|
|
10
|
+
# the 1/2 label ordinals, a naming convention; the sequence genre
|
|
11
|
+
# (OQ-S18, v0.2) will make it first-class. The cache update is a local
|
|
12
|
+
# action on A, not a message — it rides on the reply label and the prose
|
|
13
|
+
# (mode 3: figure + prose are one deliverable), not on a self-edge.
|
|
14
|
+
title ARP Resolution
|
|
15
|
+
|
|
16
|
+
# Semantic classes: delivery scope. Label = MEANING; dashed = presentation
|
|
17
|
+
# only; the legend derives automatically (spec §2.7, R57).
|
|
18
|
+
class bcast "Broadcast — delivered to every host on the LAN (dst MAC ff:ff:ff:ff:ff:ff)" color=#dc2626 style=dashed
|
|
19
|
+
class ucast "Unicast — delivered only to the requester (dst MAC = A's MAC)" color=#16a34a
|
|
20
|
+
|
|
21
|
+
node a "Host A\nwants MAC for B's IP"
|
|
22
|
+
node b "Host B\nowns the target IP"
|
|
23
|
+
|
|
24
|
+
# Every other station on the segment hears the broadcast but is outside the
|
|
25
|
+
# resolution proper: a boundary, drawn as an open edge end (spec §2.8).
|
|
26
|
+
boundary lan "rest of the LAN\n(hosts C, D, ...)"
|
|
27
|
+
|
|
28
|
+
flow right
|
|
29
|
+
|
|
30
|
+
# Step 1: A broadcasts the request to the whole segment. The same broadcast
|
|
31
|
+
# reaches every other station too; they ignore it (short label — detail here
|
|
32
|
+
# and in the showcase prose).
|
|
33
|
+
edge a -[1: who-has B? (broadcast)]-> b class=bcast
|
|
34
|
+
edge a -[1: heard, ignored]-> lan class=bcast
|
|
35
|
+
|
|
36
|
+
# Step 2: B replies to A directly (unicast); on receipt A caches the
|
|
37
|
+
# IP -> MAC binding — a local action on A, stated on the label, not a message.
|
|
38
|
+
edge b -[2: B is at aa:bb:cc:... A caches it]-> a class=ucast
|
|
39
|
+
|
|
40
|
+
# COMPOSITION (spec §8, OQ-S5 resolved): a second typed block below the
|
|
41
|
+
# scene, composed in document order. The cache TRANSITION is the figure's
|
|
42
|
+
# actual outcome, but it is a local state change on A, not a message — so
|
|
43
|
+
# this table carries the before/after cache state machine-readably, which
|
|
44
|
+
# the edge label alone can only gesture at.
|
|
45
|
+
table cache "Host A's ARP cache — before and after the exchange"
|
|
46
|
+
| Moment | Entry |
|
|
47
|
+
|--------------------|-----------------------------------------|
|
|
48
|
+
| before the exchange| (no entry for B's IP) |
|
|
49
|
+
| after segment 2 | B's IP → aa:bb:cc:... , learned from the reply |
|
|
50
|
+
|
|
51
|
+
]]></metadata></svg>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 884 194" width="884" height="194" font-family="system-ui,sans-serif"><defs><marker id="arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 z" fill="#555"/></marker><pattern id="hatch" width="6" height="6" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><line x1="0" y1="0" x2="0" y2="6" stroke="#bbb" stroke-width="2"/></pattern></defs><g transform="translate(18,6)"><text x="0" y="14" font-size="13" font-weight="600">Ethernet II frame — column order = wire order (byte counts in the second header tier)</text><rect x="0" y="22" width="90" height="26" fill="#eeede6" stroke="#c9c7bf"/><text x="45" y="39.3" font-size="12" text-anchor="middle" font-weight="600">Variant</text><rect x="90" y="22" width="136" height="26" fill="#eeede6" stroke="#c9c7bf"/><text x="158" y="39.3" font-size="12" text-anchor="middle" font-weight="600">Destination MAC</text><rect x="226" y="22" width="100" height="26" fill="#eeede6" stroke="#c9c7bf"/><text x="276" y="39.3" font-size="12" text-anchor="middle" font-weight="600">Source MAC</text><rect x="326" y="22" width="208" height="26" fill="#eeede6" stroke="#c9c7bf"/><text x="430" y="39.3" font-size="12" text-anchor="middle" font-weight="600">802.1Q Tag</text><rect x="534" y="22" width="92.8" height="26" fill="#eeede6" stroke="#c9c7bf"/><text x="580.4" y="39.3" font-size="12" text-anchor="middle" font-weight="600">EtherType</text><rect x="626.8" y="22" width="136" height="26" fill="#eeede6" stroke="#c9c7bf"/><text x="694.8" y="39.3" font-size="12" text-anchor="middle" font-weight="600">Payload</text><rect x="762.8" y="22" width="92.8" height="26" fill="#eeede6" stroke="#c9c7bf"/><text x="809.1999999999999" y="39.3" font-size="12" text-anchor="middle" font-weight="600">FCS</text><rect x="0" y="48" width="90" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="eth:0:1" style="cursor:pointer"/><text x="45" y="65.3" font-size="12" text-anchor="middle" font-weight="600">(frame)</text><rect x="90" y="48" width="136" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="eth:0:2" style="cursor:pointer"/><text x="158" y="65.3" font-size="12" text-anchor="middle" font-weight="600">(6 bytes)</text><rect x="226" y="48" width="100" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="eth:0:3" style="cursor:pointer"/><text x="276" y="65.3" font-size="12" text-anchor="middle" font-weight="600">(6 bytes)</text><rect x="326" y="48" width="208" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="eth:0:4" style="cursor:pointer"/><text x="430" y="65.3" font-size="12" text-anchor="middle" font-weight="600">(4 bytes)</text><rect x="534" y="48" width="92.8" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="eth:0:5" style="cursor:pointer"/><text x="580.4" y="65.3" font-size="12" text-anchor="middle" font-weight="600">(2 bytes)</text><rect x="626.8" y="48" width="136" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="eth:0:6" style="cursor:pointer"/><text x="694.8" y="65.3" font-size="12" text-anchor="middle" font-weight="600">(46-1500 bytes)</text><rect x="762.8" y="48" width="92.8" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="eth:0:7" style="cursor:pointer"/><text x="809.1999999999999" y="65.3" font-size="12" text-anchor="middle" font-weight="600">(4 bytes)</text><rect x="0" y="74" width="90" height="26" fill="#fff" stroke="#c9c7bf" data-cell="eth:1:1" style="cursor:pointer"/><text x="7" y="91.3" font-size="12" text-anchor="start">Untagged</text><rect x="90" y="74" width="136" height="26" fill="#fff" stroke="#c9c7bf" data-cell="eth:1:2" style="cursor:pointer"/><text x="97" y="91.3" font-size="12" text-anchor="start">DA</text><rect x="226" y="74" width="100" height="26" fill="#fff" stroke="#c9c7bf" data-cell="eth:1:3" style="cursor:pointer"/><text x="233" y="91.3" font-size="12" text-anchor="start">SA</text><rect x="326" y="74" width="208" height="26" fill="#dbeafe" stroke="#c9c7bf" data-cell="eth:1:4" style="cursor:pointer"/><text x="333" y="91.3" font-size="12" text-anchor="start">(none)</text><rect x="534" y="74" width="92.8" height="26" fill="#fff" stroke="#c9c7bf" data-cell="eth:1:5" style="cursor:pointer"/><text x="541" y="91.3" font-size="12" text-anchor="start">Type</text><rect x="626.8" y="74" width="136" height="26" fill="#fff" stroke="#c9c7bf" data-cell="eth:1:6" style="cursor:pointer"/><text x="633.8" y="91.3" font-size="12" text-anchor="start">Data</text><rect x="762.8" y="74" width="92.8" height="26" fill="#fff" stroke="#c9c7bf" data-cell="eth:1:7" style="cursor:pointer"/><text x="769.8" y="91.3" font-size="12" text-anchor="start">CRC-32</text><rect x="0" y="100" width="90" height="26" fill="#fff" stroke="#c9c7bf" data-cell="eth:2:1" style="cursor:pointer"/><text x="7" y="117.3" font-size="12" text-anchor="start">Tagged</text><rect x="90" y="100" width="136" height="26" fill="#fff" stroke="#c9c7bf" data-cell="eth:2:2" style="cursor:pointer"/><text x="97" y="117.3" font-size="12" text-anchor="start">DA</text><rect x="226" y="100" width="100" height="26" fill="#fff" stroke="#c9c7bf" data-cell="eth:2:3" style="cursor:pointer"/><text x="233" y="117.3" font-size="12" text-anchor="start">SA</text><rect x="326" y="100" width="208" height="26" fill="#dbeafe" stroke="#c9c7bf" data-cell="eth:2:4" style="cursor:pointer"/><text x="333" y="117.3" font-size="12" text-anchor="start">TPID 0x8100 + PCP/DEI/VID</text><rect x="534" y="100" width="92.8" height="26" fill="#fff" stroke="#c9c7bf" data-cell="eth:2:5" style="cursor:pointer"/><text x="541" y="117.3" font-size="12" text-anchor="start">Type</text><rect x="626.8" y="100" width="136" height="26" fill="#fff" stroke="#c9c7bf" data-cell="eth:2:6" style="cursor:pointer"/><text x="633.8" y="117.3" font-size="12" text-anchor="start">Data</text><rect x="762.8" y="100" width="92.8" height="26" fill="#fff" stroke="#c9c7bf" data-cell="eth:2:7" style="cursor:pointer"/><text x="769.8" y="117.3" font-size="12" text-anchor="start">CRC-32</text><rect x="0" y="167" width="16" height="11" fill="#dbeafe" stroke="#555"/><text x="21" y="176.5" font-size="11" fill="#1d1d1b">802.1Q VLAN tag (4 bytes), inserted after Source MAC; absent in an untagged frame</text></g><metadata id="figdown-source" data-sha256="c6b2c8047c1e15cb7c0a62bf7820ed3bfbbfd3f95aff8e5e3cf16470319b4f61"><![CDATA[
|
|
2
|
+
figdown 0.1 table
|
|
3
|
+
# Ethernet II frame, byte-order-on-the-wire carried by CELL ORDER (the
|
|
4
|
+
# OQ-S24 sanctioned pattern: a byte-unit packet is a single-row table, not
|
|
5
|
+
# a bitfield — no misleading bit ruler). Left-to-right cell order IS the
|
|
6
|
+
# order bytes appear on the wire; the strip test survives because that
|
|
7
|
+
# order lives in the syntax, never in geometry.
|
|
8
|
+
#
|
|
9
|
+
# Two data rows = two frame variants: untagged (Ethernet II) and 802.1Q
|
|
10
|
+
# tagged. The tag is INSERTED between Source MAC and EtherType — the class
|
|
11
|
+
# marks exactly which column is the insertion point, so a reader sees it
|
|
12
|
+
# without pixels.
|
|
13
|
+
title Ethernet II Frame — Untagged vs 802.1Q Tagged
|
|
14
|
+
|
|
15
|
+
# Semantic class: the 802.1Q tag and its insertion point. The label states
|
|
16
|
+
# the MEANING; the legend derives from this line (spec §2.7).
|
|
17
|
+
class tag "802.1Q VLAN tag (4 bytes), inserted after Source MAC; absent in an untagged frame" color=#dbeafe
|
|
18
|
+
|
|
19
|
+
table eth "Ethernet II frame — column order = wire order (byte counts in the second header tier)"
|
|
20
|
+
| Variant | Destination MAC | Source MAC | 802.1Q Tag | EtherType | Payload | FCS |
|
|
21
|
+
| (frame) | (6 bytes) | (6 bytes) | (4 bytes) | (2 bytes) | (46-1500 bytes) | (4 bytes) |
|
|
22
|
+
|----------|-----------------|------------|-------------|-----------|-----------------|-----------|
|
|
23
|
+
| Untagged | DA | SA | (none) | Type | Data | CRC-32 |
|
|
24
|
+
| Tagged | DA | SA | TPID 0x8100 + PCP/DEI/VID | Type | Data | CRC-32 |
|
|
25
|
+
colw 90 auto auto auto auto auto auto
|
|
26
|
+
cell 1,4 class=tag
|
|
27
|
+
cell 2,4 class=tag
|
|
28
|
+
|
|
29
|
+
# HONEST LIMIT (OQ-S16, span/coverage annotation): the FCS (CRC-32) is
|
|
30
|
+
# computed over DA through Payload inclusive — a coverage span across a
|
|
31
|
+
# CONTIGUOUS run of columns. FigDown has no construct to draw or annotate
|
|
32
|
+
# such a span (curly-brace grouping over a contiguous field/cell range is
|
|
33
|
+
# OQ-S16, v0.2; a `cell` note is not available in the table genre). Until it
|
|
34
|
+
# lands, this fact rides on a source comment and the SHOWCASE prose, never on
|
|
35
|
+
# geometry — stated here so a reader recovers it from the text, not pixels.
|
|
36
|
+
|
|
37
|
+
]]></metadata></svg>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 544 651" width="544" height="651" font-family="system-ui,sans-serif"><defs><marker id="arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 z" fill="#555"/></marker><pattern id="hatch" width="6" height="6" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><line x1="0" y1="0" x2="0" y2="6" stroke="#bbb" stroke-width="2"/></pattern></defs><g transform="translate(18,6)"><line data-edge="31" x1="290.37307692307695" y1="32" x2="290.37307692307695" y2="76" stroke="#555" stroke-width="1.6"/><line data-edge="32" x1="290.37307692307695" y1="144" x2="290.37307692307695" y2="188" stroke="#555" stroke-width="1.6"/><line data-edge="33" x1="290.37307692307695" y1="240" x2="290.37307692307695" y2="284" stroke="#555" stroke-width="1.6"/><line data-edge="35" x1="316.80398475528494" y1="333.30324720278287" x2="387.66843676737295" y2="386.74285714285713" stroke="#555" stroke-width="1.6"/><line data-edge="36" x1="266.24256332978035" y1="334.1248165738226" x2="191.637909323235" y2="398.2883630891489" stroke="#555" stroke-width="1.6"/><line data-edge="38" x1="186.46826779078154" y1="456.9233011944657" x2="236.0239383938394" y2="510.66221198156677" stroke="#555" stroke-width="1.6"/><line data-edge="39" x1="130.7317322092185" y1="456.9233011944657" x2="81.17606160616063" y2="510.66221198156677" stroke="#555" stroke-width="1.6"/><g data-node="learn" data-x="204.37307692307695" data-y="76" style="cursor:move"><rect x="204.37307692307695" y="76" width="172" height="68" fill="#fff" stroke="#8a8880"/><text x="290.37307692307695" y="97.64999999999999" font-size="13" text-anchor="middle" fill="#1d1d1b"><tspan x="290.37307692307695" dy="0">Learn source MAC:</tspan><tspan x="290.37307692307695" dy="16.900000000000002">update MAC table</tspan><tspan x="290.37307692307695" dy="16.900000000000002">(SA -> ingress port)</tspan></text></g><g data-node="lookup" data-x="193.57307692307694" data-y="188" style="cursor:move"><rect x="193.57307692307694" y="188" width="193.6" height="52" fill="#fff" stroke="#8a8880"/><text x="290.37307692307695" y="210.10000000000002" font-size="13" text-anchor="middle" fill="#1d1d1b"><tspan x="290.37307692307695" dy="0">Look up destination MAC</tspan><tspan x="290.37307692307695" dy="16.900000000000002">in MAC table</tspan></text></g><g data-node="hit" data-x="208.13307692307694" data-y="284" style="cursor:move"><polygon points="290.37307692307695,284 372.61307692307696,313.37142857142857 290.37307692307695,342.74285714285713 208.13307692307694,313.37142857142857" fill="#fff" stroke="#8a8880"/><text x="290.37307692307695" y="317.9214285714286" font-size="13" text-anchor="middle" fill="#1d1d1b">Entry found?</text></g><g data-node="same" data-x="44.253846153846155" data-y="386.74285714285713" style="cursor:move"><polygon points="158.60000000000002,386.74285714285713 272.94615384615383,426.70253456221195 158.60000000000002,466.66221198156677 44.253846153846155,426.70253456221195" fill="#fff" stroke="#8a8880"/><text x="158.60000000000002" y="422.802534562212" font-size="13" text-anchor="middle" fill="#1d1d1b"><tspan x="158.60000000000002" dy="0">Egress port ==</tspan><tspan x="158.60000000000002" dy="16.900000000000002">ingress port?</tspan></text></g><g data-node="fwd" data-x="0" data-y="510.66221198156677" style="cursor:move"><rect x="0" y="510.66221198156677" width="114.4" height="52" rx="14" fill="#16a34a" stroke="#8a8880" stroke-width="1.8"/><text x="57.2" y="532.7622119815667" font-size="13" text-anchor="middle" fill="#1d1d1b"><tspan x="57.2" dy="0">Forward out</tspan><tspan x="57.2" dy="16.900000000000002">learned port</tspan></text></g><g data-node="fld" data-x="328.9461538461539" data-y="386.74285714285713" style="cursor:move"><rect x="328.9461538461539" y="386.74285714285713" width="186.4" height="52" rx="14" fill="#2563eb" stroke="#8a8880" stroke-width="1.8"/><text x="422.1461538461539" y="408.84285714285716" font-size="13" text-anchor="middle" fill="#1d1d1b"><tspan x="422.1461538461539" dy="0">Flood to all ports</tspan><tspan x="422.1461538461539" dy="16.900000000000002">in VLAN except ingress</tspan></text></g><g data-node="flt" data-x="170.4" data-y="510.66221198156677" style="cursor:move"><rect x="170.4" y="510.66221198156677" width="179.20000000000002" height="52" rx="14" fill="#dc2626" stroke="#8a8880" stroke-width="1.8"/><text x="260" y="532.7622119815667" font-size="13" text-anchor="middle" fill="#1d1d1b"><tspan x="260" dy="0">Filter (drop):</tspan><tspan x="260" dy="16.900000000000002">same-port destination</tspan></text></g><path d="M290.37307692307695 76 L284.7730769230769 65.92 L295.973076923077 65.92 z" fill="#555" stroke="none"/><path d="M290.37307692307695 188 L284.7730769230769 177.92 L295.973076923077 177.92 z" fill="#555" stroke="none"/><path d="M290.37307692307695 284 L284.7730769230769 273.92 L295.973076923077 273.92 z" fill="#555" stroke="none"/><text x="332.3941641979443" y="357.40996138959923" font-size="11" text-anchor="middle" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round">no</text><text x="332.3941641979443" y="357.40996138959923" font-size="11" text-anchor="middle" fill="#555">no</text><path d="M387.66843676737295 386.74285714285713 L376.2485927245621 385.1448702724861 L382.99209291771245 376.2025436655576 z" fill="#555" stroke="none"/><text x="249.82953944834037" y="360.5907968071944" font-size="11" text-anchor="middle" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round">yes</text><text x="249.82953944834037" y="360.5907968071944" font-size="11" text-anchor="middle" fill="#555">yes</text><path d="M191.637909323235 398.2883630891489 L195.62870077540882 387.46986117875224 L202.93177246717303 395.96133595436993 z" fill="#555" stroke="none"/><text x="207.33496897169888" y="476.34497443059604" font-size="11" text-anchor="start" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round">yes</text><text x="207.33496897169888" y="476.34497443059604" font-size="11" text-anchor="start" fill="#555">yes</text><path d="M236.0239383938394 510.66221198156677 L225.07377169049153 507.04831530776835 L233.30734750001278 499.4556721982269 z" fill="#555" stroke="none"/><text x="121.86503102830115" y="476.34497443059604" font-size="11" text-anchor="start" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round">no</text><text x="121.86503102830115" y="476.34497443059604" font-size="11" text-anchor="start" fill="#555">no</text><path d="M81.17606160616063 510.66221198156677 L83.89265249998722 499.4556721982269 L92.1262283095085 507.04831530776835 z" fill="#555" stroke="none"/><text x="290.37307692307695" y="16" font-size="10" text-anchor="middle" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round">from ingress port</text><text x="290.37307692307695" y="16" font-size="10" text-anchor="middle" fill="#555">from ingress port</text><rect x="0" y="583.6622119815668" width="16" height="11" fill="#16a34a" stroke="#555"/><text x="21" y="593.1622119815668" font-size="11" fill="#1d1d1b">Forward — send the frame out the single learned egress port</text><rect x="0" y="603.6622119815668" width="16" height="11" fill="#2563eb" stroke="#555"/><text x="21" y="613.1622119815668" font-size="11" fill="#1d1d1b">Flood — send out every port in the VLAN except the ingress port</text><rect x="0" y="623.6622119815668" width="16" height="11" fill="#dc2626" stroke="#555"/><text x="21" y="633.1622119815668" font-size="11" fill="#1d1d1b">Filter — discard; destination is out the same port it arrived on</text></g><metadata id="figdown-source" data-sha256="4ee81fee8c81e33d2509064df822874cb7cad6da03f39df44cc6c69fca4f04db"><![CDATA[
|
|
2
|
+
figdown 0.1 flowchart
|
|
3
|
+
# The classic learning-bridge / L2 switch forwarding decision (IEEE 802.1D).
|
|
4
|
+
# A frame arrives; the switch learns the source, looks up the destination,
|
|
5
|
+
# and takes one of three actions. The LOGIC is machine-readable: a reader
|
|
6
|
+
# answers "when does a switch flood?" by tracing the Y/N edges — no pixels.
|
|
7
|
+
title L2 Switch Forwarding Decision
|
|
8
|
+
|
|
9
|
+
# Semantic classes: the three terminal OUTCOMES. Each label states the
|
|
10
|
+
# MEANING; the legend derives from these lines (spec §2.7).
|
|
11
|
+
class forward "Forward — send the frame out the single learned egress port" color=#16a34a
|
|
12
|
+
class flood "Flood — send out every port in the VLAN except the ingress port" color=#2563eb
|
|
13
|
+
class filter "Filter — discard; destination is out the same port it arrived on" color=#dc2626
|
|
14
|
+
|
|
15
|
+
# The wire is external to the decision logic: the frame enters from outside
|
|
16
|
+
# the figure (spec §2.8 boundary — never drawn as a shape, edge ends open).
|
|
17
|
+
boundary wire "from ingress port"
|
|
18
|
+
|
|
19
|
+
# Actions are boxes; ONLY decisions get shape=diamond (branch semantics by
|
|
20
|
+
# convention). The lookup is an action — the decision is "Entry found?".
|
|
21
|
+
node learn "Learn source MAC:\nupdate MAC table\n(SA -> ingress port)"
|
|
22
|
+
node lookup "Look up destination MAC\nin MAC table"
|
|
23
|
+
node hit "Entry found?" shape=diamond
|
|
24
|
+
node same "Egress port ==\ningress port?" shape=diamond
|
|
25
|
+
node fwd "Forward out\nlearned port" shape=rounded class=forward
|
|
26
|
+
node fld "Flood to all ports\nin VLAN except ingress" shape=rounded class=flood
|
|
27
|
+
node flt "Filter (drop):\nsame-port destination" shape=rounded class=filter
|
|
28
|
+
|
|
29
|
+
# top-to-bottom reading order for the decision process.
|
|
30
|
+
flow down
|
|
31
|
+
|
|
32
|
+
edge wire -> learn
|
|
33
|
+
edge learn -> lookup
|
|
34
|
+
edge lookup -> hit
|
|
35
|
+
# Miss (unknown unicast, or broadcast/multicast) -> flood.
|
|
36
|
+
edge hit -[no]-> fld
|
|
37
|
+
edge hit -[yes]-> same
|
|
38
|
+
# Hit, but destination is behind the ingress port -> filter; else forward.
|
|
39
|
+
edge same -[yes]-> flt
|
|
40
|
+
edge same -[no]-> fwd
|
|
41
|
+
|
|
42
|
+
]]></metadata></svg>
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 624 350" width="624" height="350" font-family="system-ui,sans-serif"><defs><marker id="arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 z" fill="#555"/></marker><pattern id="hatch" width="6" height="6" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><line x1="0" y1="0" x2="0" y2="6" stroke="#bbb" stroke-width="2"/></pattern></defs><g transform="translate(18,6)"><line data-edge="31" x1="172" y1="34.5" x2="358.5" y2="34.5" stroke="#2563eb" stroke-width="1.6"/><path data-edge="34" d="M476.9 56 L476.9 74 Q476.9 84 466.9 84 L96 84 Q86 84 86 74 L86 56" fill="none" stroke="#2563eb" stroke-width="1.6"/><line data-edge="39" x1="172" y1="41.5" x2="358.5" y2="41.5" stroke="#16a34a" stroke-width="1.6"/><g data-node="client" data-x="0" data-y="20" style="cursor:move"><rect x="0" y="20" width="172" height="36" fill="#fff" stroke="#8a8880"/><text x="86" y="42.55" font-size="13" text-anchor="middle" fill="#1d1d1b">Client (active open)</text></g><g data-node="server" data-x="358.5" data-y="20" style="cursor:move"><rect x="358.5" y="20" width="236.8" height="36" fill="#fff" stroke="#8a8880"/><text x="476.9" y="42.55" font-size="13" text-anchor="middle" fill="#1d1d1b">Server (passive open, LISTEN)</text></g><text x="265.25" y="28.75" font-size="11" text-anchor="middle" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round">1: SYN seq=x</text><text x="265.25" y="28.75" font-size="11" text-anchor="middle" fill="#2563eb">1: SYN seq=x</text><path d="M358.5 34.5 L348.42 40.1 L348.42 28.9 z" fill="#2563eb" stroke="none"/><text x="281.45" y="78.25" font-size="11" text-anchor="middle" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round">2: SYN,ACK seq=y ack=x+1</text><text x="281.45" y="78.25" font-size="11" text-anchor="middle" fill="#2563eb">2: SYN,ACK seq=y ack=x+1</text><path d="M86 56 L91.6 66.08 L80.4 66.08 z" fill="#2563eb" stroke="none"/><text x="265.25" y="53.85" font-size="11" text-anchor="middle" fill="#fff" stroke="#fff" stroke-width="3" stroke-linejoin="round">3: ACK ack=y+1 (+ data)</text><text x="265.25" y="53.85" font-size="11" text-anchor="middle" fill="#16a34a">3: ACK ack=y+1 (+ data)</text><path d="M358.5 41.5 L348.42 47.1 L348.42 35.9 z" fill="#16a34a" stroke="none"/><text x="0" y="124" font-size="13" font-weight="600">Endpoint state after each segment (RFC 9293 §3.3.2 state names)</text><rect x="0" y="132" width="114.4" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="state:0:1" style="cursor:pointer"/><text x="57.2" y="149.3" font-size="12" text-anchor="middle" font-weight="600">Segment</text><rect x="114.4" y="132" width="186.4" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="state:0:2" style="cursor:pointer"/><text x="207.60000000000002" y="149.3" font-size="12" text-anchor="middle" font-weight="600">Client state</text><rect x="300.8" y="132" width="193.6" height="26" fill="#eeede6" stroke="#c9c7bf" data-cell="state:0:3" style="cursor:pointer"/><text x="397.6" y="149.3" font-size="12" text-anchor="middle" font-weight="600">Server state</text><rect x="0" y="158" width="114.4" height="26" fill="#fff" stroke="#c9c7bf" data-cell="state:1:1" style="cursor:pointer"/><text x="7" y="175.3" font-size="12" text-anchor="start">start</text><rect x="114.4" y="158" width="186.4" height="26" fill="#fff" stroke="#c9c7bf" data-cell="state:1:2" style="cursor:pointer"/><text x="121.4" y="175.3" font-size="12" text-anchor="start">CLOSED</text><rect x="300.8" y="158" width="193.6" height="26" fill="#fff" stroke="#c9c7bf" data-cell="state:1:3" style="cursor:pointer"/><text x="307.8" y="175.3" font-size="12" text-anchor="start">LISTEN</text><rect x="0" y="184" width="114.4" height="26" fill="#fff" stroke="#c9c7bf" data-cell="state:2:1" style="cursor:pointer"/><text x="7" y="201.3" font-size="12" text-anchor="start">1: SYN →</text><rect x="114.4" y="184" width="186.4" height="26" fill="#fff" stroke="#c9c7bf" data-cell="state:2:2" style="cursor:pointer"/><text x="121.4" y="201.3" font-size="12" text-anchor="start">SYN-SENT</text><rect x="300.8" y="184" width="193.6" height="26" fill="#fff" stroke="#c9c7bf" data-cell="state:2:3" style="cursor:pointer"/><text x="307.8" y="201.3" font-size="12" text-anchor="start">SYN-RECEIVED on receipt</text><rect x="0" y="210" width="114.4" height="26" fill="#fff" stroke="#c9c7bf" data-cell="state:3:1" style="cursor:pointer"/><text x="7" y="227.3" font-size="12" text-anchor="start">2: SYN,ACK ←</text><rect x="114.4" y="210" width="186.4" height="26" fill="#fff" stroke="#c9c7bf" data-cell="state:3:2" style="cursor:pointer"/><text x="121.4" y="227.3" font-size="12" text-anchor="start">ESTABLISHED on receipt</text><rect x="300.8" y="210" width="193.6" height="26" fill="#fff" stroke="#c9c7bf" data-cell="state:3:3" style="cursor:pointer"/><text x="307.8" y="227.3" font-size="12" text-anchor="start">SYN-RECEIVED</text><rect x="0" y="236" width="114.4" height="26" fill="#fff" stroke="#c9c7bf" data-cell="state:4:1" style="cursor:pointer"/><text x="7" y="253.3" font-size="12" text-anchor="start">3: ACK →</text><rect x="114.4" y="236" width="186.4" height="26" fill="#fff" stroke="#c9c7bf" data-cell="state:4:2" style="cursor:pointer"/><text x="121.4" y="253.3" font-size="12" text-anchor="start">ESTABLISHED</text><rect x="300.8" y="236" width="193.6" height="26" fill="#fff" stroke="#c9c7bf" data-cell="state:4:3" style="cursor:pointer"/><text x="307.8" y="253.3" font-size="12" text-anchor="start">ESTABLISHED on receipt</text><rect x="0" y="303" width="16" height="11" fill="#2563eb" stroke="#555"/><text x="21" y="312.5" font-size="11" fill="#1d1d1b">Connection-setup segment — carries SYN and/or ACK control flags</text><rect x="0" y="323" width="16" height="11" fill="#16a34a" stroke="#555"/><text x="21" y="332.5" font-size="11" fill="#1d1d1b">Segment that also carries application data (piggybacked on the ACK)</text></g><metadata id="figdown-source" data-sha256="6064267340e45c25cdb009cb0c6f96edf34f15baacf2b50773eb6785a07e3e98"><![CDATA[
|
|
2
|
+
figdown 0.1 topology
|
|
3
|
+
# TCP three-way handshake + data on the third segment (RFC 9293 §3.5).
|
|
4
|
+
# Two endpoints, three directed segments carrying the connection-setup
|
|
5
|
+
# exchange. Each segment's ordinal (1/2/3) is in its edge label.
|
|
6
|
+
#
|
|
7
|
+
# HONEST LIMIT (EXPRESSING known limits — "strict message ordering"):
|
|
8
|
+
# message ORDER is carried only by the 1/2/3 numbering convention in the
|
|
9
|
+
# labels, a naming convention that R37 does not treat as first-class order.
|
|
10
|
+
# The sequence genre (OQ-S18, v0.2) will make order first-class semantics;
|
|
11
|
+
# until then a reader must trust the ordinal prefixes below.
|
|
12
|
+
# Likewise, the canonical RFC 9293 figure carries the per-endpoint TCP
|
|
13
|
+
# STATE (LISTEN, SYN-SENT, …) on the lifelines; the topology genre has no
|
|
14
|
+
# lifeline-state construct, so the companion `table` block below carries
|
|
15
|
+
# those states machine-readably — composition (multiple typed blocks in one
|
|
16
|
+
# document, in document order) is the ruled interim until sequence lands.
|
|
17
|
+
title TCP Three-Way Handshake
|
|
18
|
+
|
|
19
|
+
# Semantic classes: the label states the MEANING; colour merely renders it,
|
|
20
|
+
# and the legend derives automatically (spec §2.7). Each segment is classed
|
|
21
|
+
# by what it does — a reader queries the class, not the arrow colour.
|
|
22
|
+
class setup "Connection-setup segment — carries SYN and/or ACK control flags" color=#2563eb
|
|
23
|
+
class data "Segment that also carries application data (piggybacked on the ACK)" color=#16a34a
|
|
24
|
+
|
|
25
|
+
node client "Client (active open)"
|
|
26
|
+
node server "Server (passive open, LISTEN)"
|
|
27
|
+
|
|
28
|
+
# left-to-right reading: client on the left issues the active open.
|
|
29
|
+
flow right
|
|
30
|
+
|
|
31
|
+
# Segment 1: client -> server, SYN, seq=x (flags: SYN)
|
|
32
|
+
edge client -[1: SYN seq=x]-> server class=setup
|
|
33
|
+
|
|
34
|
+
# Segment 2: server -> client, SYN+ACK, seq=y ack=x+1 (flags: SYN, ACK)
|
|
35
|
+
edge server -[2: SYN,ACK seq=y ack=x+1]-> client class=setup
|
|
36
|
+
|
|
37
|
+
# Segment 3: client -> server, ACK ack=y+1, carrying piggybacked data
|
|
38
|
+
# (flags: ACK). One segment, so ONE edge; it is both an ACK and a data
|
|
39
|
+
# carrier, so it is classed as data (the stronger claim). Detail in prose.
|
|
40
|
+
edge client -[3: ACK ack=y+1 (+ data)]-> server class=data
|
|
41
|
+
|
|
42
|
+
# COMPOSITION (spec §8, OQ-S5 resolved): a second typed block in the same
|
|
43
|
+
# document, composed in document order below the scene. The canonical RFC
|
|
44
|
+
# 9293 figure carries the TCP state names on the two lifelines; the topology
|
|
45
|
+
# genre has no lifeline-state construct, so this table carries them
|
|
46
|
+
# machine-readably. State names are the RFC 9293 §3.3.2 constants
|
|
47
|
+
# (CLOSED, LISTEN, SYN-SENT, SYN-RECEIVED, ESTABLISHED) verbatim.
|
|
48
|
+
table state "Endpoint state after each segment (RFC 9293 §3.3.2 state names)"
|
|
49
|
+
| Segment | Client state | Server state |
|
|
50
|
+
|--------------------|-----------------------|---------------------------|
|
|
51
|
+
| start | CLOSED | LISTEN |
|
|
52
|
+
| 1: SYN → | SYN-SENT | SYN-RECEIVED on receipt |
|
|
53
|
+
| 2: SYN,ACK ← | ESTABLISHED on receipt| SYN-RECEIVED |
|
|
54
|
+
| 3: ACK → | ESTABLISHED | ESTABLISHED on receipt |
|
|
55
|
+
|
|
56
|
+
]]></metadata></svg>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 764 284" width="764" height="284" font-family="system-ui,sans-serif"><defs><marker id="arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 z" fill="#555"/></marker><pattern id="hatch" width="6" height="6" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><line x1="0" y1="0" x2="0" y2="6" stroke="#bbb" stroke-width="2"/></pattern></defs><g transform="translate(18,6)"><text x="0" y="14" font-size="13" font-weight="600">TCP Header (RFC 9293)</text><text x="11.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">0</text><text x="34.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">1</text><text x="57.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">2</text><text x="80.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">3</text><text x="103.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">4</text><text x="126.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">5</text><text x="149.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">6</text><text x="172.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">7</text><text x="195.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">8</text><text x="218.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">9</text><text x="241.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">10</text><text x="264.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">11</text><text x="287.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">12</text><text x="310.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">13</text><text x="333.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">14</text><text x="356.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">15</text><text x="379.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">16</text><text x="402.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">17</text><text x="425.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">18</text><text x="448.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">19</text><text x="471.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">20</text><text x="494.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">21</text><text x="517.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">22</text><text x="540.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">23</text><text x="563.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">24</text><text x="586.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">25</text><text x="609.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">26</text><text x="632.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">27</text><text x="655.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">28</text><text x="678.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">29</text><text x="701.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">30</text><text x="724.5" y="29" font-size="8.5" text-anchor="middle" fill="#6f6e69">31</text><rect x="0" y="34" width="368" height="30" fill="#fff" stroke="#555"/><text x="184" y="52.85" font-size="11" text-anchor="middle">Source Port</text><rect x="368" y="34" width="368" height="30" fill="#fff" stroke="#555"/><text x="552" y="52.85" font-size="11" text-anchor="middle">Destination Port</text><rect x="0" y="64" width="736" height="30" fill="#fff" stroke="#555"/><text x="368" y="82.85" font-size="11" text-anchor="middle">Sequence Number</text><rect x="0" y="94" width="736" height="30" fill="#fff" stroke="#555"/><text x="368" y="112.85" font-size="11" text-anchor="middle">Acknowledgment Number</text><rect x="0" y="124" width="92" height="30" fill="#fff" stroke="#555"/><text x="46" y="142.85" font-size="11" text-anchor="middle">Data Offset</text><title>header length in 32-bit words; min 5 (=20 bytes), max 15 (=60 bytes)</title><rect x="92" y="124" width="92" height="30" fill="#fff" stroke="#555"/><text x="138" y="142.85" font-size="11" text-anchor="middle">Reserved</text><title>must be zero</title><rect x="184" y="124" width="23" height="30" fill="#fff" stroke="#555"/><text x="195.5" y="142.5188172043011" font-size="10.053763440860214" text-anchor="middle">CWR</text><rect x="207" y="124" width="23" height="30" fill="#fff" stroke="#555"/><text x="218.5" y="142.5188172043011" font-size="10.053763440860214" text-anchor="middle">ECE</text><rect x="230" y="124" width="23" height="30" fill="#fff" stroke="#555"/><text x="241.5" y="142.5188172043011" font-size="10.053763440860214" text-anchor="middle">URG</text><rect x="253" y="124" width="23" height="30" fill="#fff" stroke="#555"/><text x="264.5" y="142.5188172043011" font-size="10.053763440860214" text-anchor="middle">ACK</text><rect x="276" y="124" width="23" height="30" fill="#fff" stroke="#555"/><text x="287.5" y="142.5188172043011" font-size="10.053763440860214" text-anchor="middle">PSH</text><rect x="299" y="124" width="23" height="30" fill="#fff" stroke="#555"/><text x="310.5" y="142.5188172043011" font-size="10.053763440860214" text-anchor="middle">RST</text><rect x="322" y="124" width="23" height="30" fill="#fee2e2" stroke="#555"/><text x="333.5" y="142.5188172043011" font-size="10.053763440860214" text-anchor="middle">SYN</text><rect x="345" y="124" width="23" height="30" fill="#fee2e2" stroke="#555"/><text x="356.5" y="142.5188172043011" font-size="10.053763440860214" text-anchor="middle">FIN</text><rect x="368" y="124" width="368" height="30" fill="#fff" stroke="#555"/><text x="552" y="142.85" font-size="11" text-anchor="middle">Window</text><title>receive window size in bytes (subject to window scaling option)</title><rect x="0" y="154" width="368" height="30" fill="#fff" stroke="#555"/><text x="184" y="172.85" font-size="11" text-anchor="middle">Checksum</text><rect x="368" y="154" width="368" height="30" fill="#fff" stroke="#555"/><text x="552" y="172.85" font-size="11" text-anchor="middle">Urgent Pointer</text><rect x="0" y="184" width="736" height="30" fill="#fff" stroke="#555" stroke-dasharray="5 3"/><text x="368" y="202.85" font-size="11" text-anchor="middle">Options</text><title>present iff Data Offset > 5; padded to a 32-bit boundary</title><rect x="0" y="214" width="736" height="30" fill="#fff" stroke="#555"/><text x="368" y="232.85" font-size="11" text-anchor="middle">Data</text><title>variable-length payload; length derived from the IP datagram, not carried in the TCP header</title></g><metadata id="figdown-source" data-sha256="f1ce5b6b0b129a760a826f9bc81e4fa8417a571929d9e3b0adc5480e3fb1445f"><![CDATA[
|
|
2
|
+
figdown 0.1 bitfield
|
|
3
|
+
# TCP Header — RFC 9293 §3.1, IETF MSB-0 bit numbering (bit 0 = leftmost).
|
|
4
|
+
# The .fd is the machine-readable truth: field ORDER + WIDTH give every
|
|
5
|
+
# bit its absolute offset, so a reader answers "which bits carry X?" from
|
|
6
|
+
# text alone — no pixels, no OCR.
|
|
7
|
+
title TCP Header
|
|
8
|
+
|
|
9
|
+
bitfield tcp "TCP Header (RFC 9293)" unit=32 numbering=msb0
|
|
10
|
+
|
|
11
|
+
# Row 1: Source Port (16) + Destination Port (16) = 32 bits
|
|
12
|
+
field "Source Port" 16
|
|
13
|
+
field "Destination Port" 16
|
|
14
|
+
|
|
15
|
+
# Row 2: Sequence Number = 32 bits
|
|
16
|
+
field "Sequence Number" 32
|
|
17
|
+
|
|
18
|
+
# Row 3: Acknowledgment Number = 32 bits
|
|
19
|
+
field "Acknowledgment Number" 32
|
|
20
|
+
|
|
21
|
+
# Row 4: Data Offset (4) + Reserved (4) + 8 control flags (1 bit each) + Window (16)
|
|
22
|
+
field "Data Offset" 4 note="header length in 32-bit words; min 5 (=20 bytes), max 15 (=60 bytes)"
|
|
23
|
+
field Reserved 4 note="must be zero"
|
|
24
|
+
# The eight control bits are declared as individual 1-bit fields so a reader
|
|
25
|
+
# can address each flag's exact bit position, not just the byte that holds them.
|
|
26
|
+
field CWR 1
|
|
27
|
+
field ECE 1
|
|
28
|
+
field URG 1
|
|
29
|
+
field ACK 1
|
|
30
|
+
field PSH 1
|
|
31
|
+
field RST 1
|
|
32
|
+
field SYN 1 color=#fee2e2
|
|
33
|
+
field FIN 1 color=#fee2e2
|
|
34
|
+
field Window 16 note="receive window size in bytes (subject to window scaling option)"
|
|
35
|
+
|
|
36
|
+
# Row 5: Checksum (16) + Urgent Pointer (16) = 32 bits
|
|
37
|
+
field Checksum 16
|
|
38
|
+
field "Urgent Pointer" 16
|
|
39
|
+
|
|
40
|
+
# Row 6+: Options — present only when Data Offset > 5 (dashed border marks
|
|
41
|
+
# conditional presence; a reader computing offsets past here MUST branch, R48)
|
|
42
|
+
field Options 32 optional note="present iff Data Offset > 5; padded to a 32-bit boundary"
|
|
43
|
+
|
|
44
|
+
# Payload — variable length, inferred from the IP total length, not a TCP field
|
|
45
|
+
field Data * note="variable-length payload; length derived from the IP datagram, not carried in the TCP header"
|
|
46
|
+
|
|
47
|
+
]]></metadata></svg>
|