# TP6 — Prämissen-Messung: hat dieses Netz überhaupt ein Bufferbloat-Problem? > **Stand 2026-08-21 · AUSGEFÜHRT, Ergebnis in §5.** Dieses Runbook ändert **nichts** am Netz. > Es misst, und es sagt vorher, was das Ergebnis bedeutet. > > **Der Deliverable dieses Runbooks ist eine Entscheidung, keine Queue.** --- ## 1. Warum gemessen wird, bevor gebaut wird TP6 wird seit Monaten als „DAS Ziel" des Projekts geführt. Gleichzeitig liegt seit dem 2026-06-16 eine Messung im Repo, die zum gegenteiligen Schluss kommt — [`call-quality-diagnosis.md`](call-quality-diagnosis.md) sagt im Kopf, TP6 habe sich als **Nicht-QoS-Problem** entpuppt, und in der Ergebnistabelle wörtlich: ``` CAKE / QoS | kein Bufferbloat-Spielraum | ❌ nicht deployt (wäre marginal) ``` **Die Zahlen von damals:** | Größe | Wert | |---|---| | Upload gesättigt (3 Flows) | **10,3 Mbit** sustained | | Latenz idle | **12 ms** | | Latenz unter Vollast | avg **17,5 ms** / max **26 ms** (24 Pings) | | Bufferbloat-Grade | **A / A+** | Bei einem Latenzanstieg von 12 → 17,5 ms unter Sättigung holt CAKE nichts mehr. Das ist der Grund, warum dieses Runbook existiert: **es wäre falsch, eine Queue zu bauen, ohne diesen Befund zu widerlegen.** ### Was den Befund relativiert Die Messung stammt aus der **FritzBox-Ära**. Seither ist der Edge komplett getauscht: | damals (2026-06-16) | heute | |---|---| | FritzBox 6660 macht NAT + Queuing | **`crs326-core`** macht NAT + Queuing (ARM 2×800 MHz) | | FB am Liwest-Anschluss | **Arris im Bridge-Mode**, Public-IP direkt auf `vlan100` | | Double-NAT | kein Double-NAT | | 2× Cudy als AP | 2× hAP ax² als CAPs unter CAPsMAN | **Die Leitung ist dieselbe. Das Pufferverhalten des neuen Edge ist ungemessen.** Genau diese Lücke schließt die Messung. --- ## 2. Methodengleichheit ist die halbe Messung ⚠️ **Wer anders misst als 2026-06-16, kann die beiden Zahlen nicht vergleichen** — und ohne Vergleich ist die Messung wertlos, weil die Kernfrage lautet „hat sich seit dem Edge-Tausch etwas verschlechtert?". Deshalb: **dieselbe Methode zuerst**, die bequemere danach. ### 2.1 Primärmessung — reproduziert 2026-06-16 Von einem **kabelgebundenen** Client in VLAN10 (WLAN würde die Messung mit Funk-Jitter verseuchen). > 🔴 **Zwei Client-Vorbedingungen, ohne die die Messung wertlos ist** (nachgetragen 2026-08-19): > > 1. **WARP MUSS AUS SEIN.** Ein aktiver WARP-Client schickt den Verkehr durch Cloudflares > QUIC-Tunnel — gemessen würde dann der Tunnel, nicht die Liwest-Strecke, und ICMP geht > gar nicht erst durch. Das ist in diesem Projekt schon zweimal aufgeschlagen > (`ref_warp_local_icmp_trap`; zuletzt am 2026-08-18, als `dig`-Tests vom MacBook stumm > ins Leere liefen, während dieselben Abfragen aus VLAN20 sofort antworteten). > **Vor der ersten Zahl prüfen, nicht danach.** > 2. **Nicht dual-homed messen.** Das MacBook hält zeitweise Leases in **VLAN10 und VLAN20** > gleichzeitig (dokumentiert in `project_dual_homing_slowness_incident`). Dann ist unklar, > über welches Interface die Flows laufen und welchen Weg die Pings nehmen. Vor der Messung > sicherstellen, dass genau **ein** Interface aktiv ist — sonst misst man eine Mischung. Ablauf: 1. **Baseline idle** — 24 Pings gegen ein stabiles externes Ziel, Netz ansonsten ruhig. ```bash ping -c 24 1.1.1.1 ``` Notieren: min / avg / max. 2. **Sättigung aufbauen** — 3 parallele Upload-Flows, bis die Rate steht (das war 2026-06-16 der Aufbau: 3 Flows × ~430 KB/s = 1,28 MB/s = 10,3 Mbit). Sättigung heißt: die Summenrate ist über ≥30 s stabil, nicht der Peak der ersten Sekunden. 3. **Ping unter Last** — dieselbe Ping-Reihe **während** die Flows laufen. ```bash ping -c 24 1.1.1.1 ``` 4. **Dasselbe für Download.** 🔴 **Die Download-Seite wurde 2026-06-16 nie gemessen** — das ist die größte Lücke im Altbefund. Kabelanschlüsse sind asymmetrisch, und der Down-Puffer sitzt beim ISP, wo ein Router ihn nur per Ingress-Shaping erreicht. Wenn dieses Netz irgendwo Bufferbloat hat, dann am wahrscheinlichsten hier. ### 2.2 Sekundärmessung — waveform als unabhängige Zahl `https://www.waveform.com/tools/bufferbloat` vom selben Client. Liefert den Buchstaben-Grade und trennt Up/Down sauber. **Dient der Gegenprobe, nicht als alleinige Grundlage** — die Ping-Reihe aus 2.1 ist die vergleichbare Zahl. ### 2.3 Was am Core mitläuft (read-only, parallel) Während der Sättigung, damit die Zahl nicht ohne Kontext dasteht: - **CPU-Last:** `/system resource print` — der Core ist ein **Switch mit 800-MHz-ARM-CPU**, kein Router-Boliden. Geht die CPU unter 10 Mbit schon hoch, ist das ein eigener Befund. - **Interface-Rate:** `/interface monitor-traffic vlan100` — bestätigt, dass die Sättigung wirklich am WAN ankommt und nicht vorher im LAN hängt. - **Tatsächliche Linerate:** aus der gemessenen Sättigung ableiten. ⚠️ Die im Projekt kolportierten „~10 Mbit Upload" stammen aus der Diagnose-Session; **der aktuelle Liwest-Tarif ist nirgends im Repo dokumentiert.** Wenn die Messung deutlich mehr zeigt, gehört die Zahl nachgetragen — sie ist die Grundlage jeder späteren Prozent-Vorgabe. --- ## 3. Das Abbruchkriterium — steht VOR der Messung fest > Dieser Abschnitt ist der eigentliche Zweck des Runbooks. Eine Schwelle, die erst nach dem Ergebnis > festgelegt wird, ist keine Schwelle. | Ergebnis unter Last | Entscheidung | |---|---| | **Grade A oder A+** (Latenzanstieg ≲ 30 ms über idle, beide Richtungen) | **TP6 wird geschlossen, nicht gebaut.** | | **Grade B oder schlechter** in mindestens einer Richtung | **CAKE ist die Antwort** — dann mit einer Zahl als Begründung. | ### Fall A — es bleibt A/A+ Das ist der wahrscheinliche Ausgang, und er ist **kein Misserfolg**: 1. TP6 bekommt einen datierten Eintrag „✅ geschlossen — gemessen statt gebaut", mit beiden Messreihen (2026-06-16 und heute) nebeneinander. 2. Der **kritische Pfad wird leer.** Das Projekt ist in seinem Kern fertig — deny-by-default steht, Golden Config steht, WLAN steht, VLAN1 ist weg. 3. **Christoph entscheidet, was das neue Ziel ist.** Kandidaten aus der bestehenden Liste: TP24 (USV), TP11 (Monitoring), TP16.2 (Härtung), TP12 (IPv6). 4. `call-quality-diagnosis.md` bekommt eine Bestätigungszeile — der Befund von damals hat gehalten. ### Fall B — es ist schlechter geworden Dann ist **die Ursache neu**, denn 2026-06-16 war es gut. Vor jeder Queue erst die Ursache eingrenzen: - Neuer Edge (Arris-Puffer) · CPU-Deckel am Core · gestiegene Grundlast (7 VLANs statt flach) - Erst danach CAKE — und dann als Antwort auf eine benannte Ursache, nicht als Ritual. --- ## 4. Kontext für den Bau-Fall (damit er später nicht neu recherchiert wird) Beides ist am 2026-08-18/19 live erhoben und muss nicht erneut ermittelt werden. ### 4.1 `/queue` fehlt im Golden-Config-Template [`nautobot/mikrotik_routeros.j2`](../nautobot/mikrotik_routeros.j2) hat **keinen `/queue`-Block**, und es gibt keine ComplianceRule dafür. Eine von Hand gesetzte CAKE-Queue wäre damit: - **unsichtbar für die Compliance** (sie meldet weiter „compliant", während die Queue driftet), und - **beim nächsten Deploy nicht geschützt.** → CAKE braucht **Template-Block + ComplianceRule**, nicht nur die Queue. Das ist exakt dieselbe Lücke, die **TP26** für `/ip firewall filter` geschlossen hat — dort war der blinde Fleck 25 Firewallregeln groß. ### 4.2 Fasttrack ist auf dem Core faktisch tot — Entscheid: **so lassen** Live gezählt (2026-08-18/19): ``` 2 accept | defconf: accept est,rel,untracked | 32.979.171 Pakete 3 fasttrack-connection | defconf: fasttrack | 0 Pakete 0 von 445 Verbindungen fasttracked ``` Die `accept`-Regel steht **vor** der Fasttrack-Regel, also wird Fasttrack nie erreicht. **Herkunft:** `ap1` hatte die Reihenfolge vor dem Cutover richtig (Fasttrack zuerst, MikroTik-defconf); umgedreht wurde sie beim handgebauten Core-Aufbau in TP21.1. **Entscheidung (Christoph, 2026-08-19): der Zustand bleibt — und zwar als Absicht, nicht als Unfall.** - **Für CAKE ist er günstig.** Fasttrack umgeht die Queues; CAKE braucht sie. Der Konflikt, den man sonst erst auflösen müsste, existiert hier gar nicht. - **Bei ~10 Mbit WAN kostet er nichts.** Die Core-CPU trägt den Forward-Pfad ohnehin schon — 32,9 Mio Pakete sind der Beweis, nicht die Vermutung. - ⚠️ **Gegenbedingung, unter der neu bewertet wird:** wenn **Inter-VLAN** je auf Gigabit soll (NAS ↔ MAIN läuft geroutet über dieselbe CPU), ist der Verzicht auf Fasttrack teuer. **Diese Messung steht aus** und ist die Vorbedingung jeder Neubewertung — nicht die WAN-Zahl aus diesem Runbook. --- ## 5. Ergebnis der Messung (2026-08-20/21) > **Ausgeführt.** Drei Messreihen von einem kabelgebundenen Client in VLAN10 (MacBook, `en5`, > 10.40.10.183, am Dock an `crs326-branch`). Vorbedingungen vor jeder Reihe geprüft: WARP > `Disconnected`, Wi-Fi aus, genau eine 10.40er-Adresse, WAN im Leerlauf (114 kbit rx / 97 kbit tx). ### 5.1 Die Linerate — erstmals dokumentiert | Richtung | gemessen | Beleg | |---|---|---| | **Upload** | **9,6 Mbit** (1.199.317 B/s) | 10-s-Vollast-Probe | | **Download** | **54,6 Mbit** sustained | `vlan100` rx über die gesamte Sättigungsphase | Die im Repo kolportierten „~10 Mbit" stimmen für den Upload. Für den Download gab es bisher **gar keine** Zahl. ### 5.2 Die drei Messreihen Alle Werte ms, `min/avg/max`, 24 Pings gegen 1.1.1.1. | | idle bzw. C0 | Upload-Last | Download-Last | danach (C1) | |---|---|---|---|---| | **Durchlauf 1** — ohne Call | 10,4 / **12,9** / 53,6 | 32,5 / **60,4** / 115,2 | 11,1 / **41,3** / 67,3 | — | | **Ort 1 (Küche)** — mit Videocall | 10,2 / **13,2** / 22,3 | 30,2 / **42,8** / 66,6 | 16,1 / **37,1** / 43,7 | 10,4 / 13,4 / 23,7 | | **Ort 2 (Terrasse)** — mit Videocall | 10,4 / **12,8** / 18,9 | 29,7 / **40,4** / 63,5 | 15,4 / **36,3** / 49,6 | 10,3 / 13,0 / 18,5 | | Referenz **2026-06-16** | 12 | **17,5** / max 26 | *nie gemessen* | — | **Core-CPU:** unter Upload-Last ~10 % — die CPU ist nicht der Engpass. Unter Download-Last dagegen **33,6 % avg / 41 % max** bei 55 Mbit; für die Bufferbloat-Frage irrelevant, für die offene Inter-VLAN-Frage (§4.2) ein Datenpunkt. ### 5.3 waveform als Gegenprobe: Grade A — und warum das kein Widerspruch ist | | unloaded | ↓ aktiv | ↑ aktiv | |---|---|---|---| | Median | 15,8 ms | 33,4 ms | 36,0 ms | | 95. Perzentil | 20,7 ms | 41,2 ms | **57,0 ms** | | Jitter | **2,0 ms** | 3,8 ms | **15,3 ms** | Der Grade kommt aus dem **Median**. Die Verteilung des Upload-Tests ist aber zweigipflig — 25. Perzentil **14,5 ms**, 75. Perzentil **47,5 ms** —, also stammt ein Teil der Messpunkte aus der Zeit, *bevor* der Puffer voll war. Genau das erwartet man bei einem kurz anrampenden Test. Die Ping-Reihe hält die Sättigung 55 s bei 10,3 Mbit angebotener Last auf einer 9,6-Mbit-Leitung und misst deshalb den **eingeschwungenen** Zustand. Beide Messungen zeigen dasselbe Verhalten an verschiedenen Punkten der Kurve; der Jitter-Sprung von 2 auf 15,3 ms bestätigt die Richtung. ### 5.4 Die Entscheidung: Fall B — aber „messbar, nicht hörbar" Gegen die Tabelle aus §3: der Anstieg über idle beträgt in der **Senderichtung +28 bis +47 ms** und liegt damit über der Schwelle von ≲30 ms. **Formal ist das Fall B: CAKE ist begründet.** 🔴 **Die Einschränkung gehört zur Zahl:** durch alle sechs Lastphasen an zwei Orten lief ein Telegram-Videocall, und es wurde **kein einziger Problem-Button gedrückt** — weder von Christoph noch nach Gelis Rückmeldung. Der Anstieg ist messbar, war aber in dem Anwendungsfall, für den TP6 überhaupt existiert, **nicht wahrnehmbar**. Wer daraus eine Queue baut, baut sie gegen ein reales, aber leises Problem: den Fall „jemand lädt dauerhaft hoch, während telefoniert wird". **Was dagegen laut war, hat mit TP6 nichts zu tun:** die WLAN-Übergaben. Siehe [`tp25-wlan-roaming-messung-20260820.md`](tp25-wlan-roaming-messung-20260820.md). ### 5.5 Zwei Messfehler, die dokumentiert bleiben, weil sie die Methode betreffen 1. **Die erste Download-Reihe war eine Nicht-Messung.** `speed.cloudflare.com/__down` beantwortet ein `curl` mit Default-User-Agent mit **403 und einem Byte**; die drei Flows waren sofort tot, die Ping-Reihe zeigte saubere 12,1 ms — und das hätte als „kein Bufferbloat im Download" im Runbook gestanden. Aufgefallen ist es **nur am Core-Sampler**: 164 kbit statt 50 Mbit auf `vlan100`. → Skript schickt jetzt User-Agent + Referer. 2. **Ein Call lief 5,5 Minuten ohne Treiber.** Der Start-Klick schrieb einen Marker, aber es lief keine Sättigung und kein Sampler; „kein einziges Problem" war deshalb kein Ergebnis, sondern die Abwesenheit einer Messung. → Der Treiber meldet sich jetzt im 5-s-Takt, die Konsole warnt sichtbar, wenn keiner läuft. Beide sind derselbe Fehlertyp: **die Anzeige war grün, die Wirkung fehlte** (`feedback_abnahme_wirkung_nicht_anzeige`). ### 5.6 Rohdaten `docs/messdaten/tp6-20260820/` — Sampler-CSVs (Core: CPU, WAN-Rate, Client-Funkwerte im 2-s-Takt), Marker, Ping-Reihen und der durchgehende Latenz-Mitschnitt. Auswertung mit `python3 docs/tp6-auswertung.py --sampler --markers `. --- ## 6. Abnahme dieses Runbooks 1. Beide Messreihen (Up **und** Down, idle **und** Last) liegen als Zahlen vor, nicht als Eindruck. 2. Die Entscheidung ist gegen die Tabelle aus §3 gefallen — **nicht** gegen ein Bauchgefühl. 3. Das Ergebnis steht datiert in TP6, und der kritische Pfad ist entsprechend nachgezogen. 4. Die tatsächliche Linerate ist dokumentiert (sie fehlte bisher im ganzen Repo). 5. **Kein Netz-Eingriff** im Fall A. Im Fall B entsteht ein *zweites* Runbook, das gebaut wird — dieses hier bleibt die Begründung dafür.