Files
bf-infra/docs/tp6-praemisse-messrunbook.md

276 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 <csv> --markers <csv>`.
---
## 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.