276 lines
14 KiB
Markdown
276 lines
14 KiB
Markdown
# 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.
|