TP6.1 live: NAS-Sync weicht zurueck -- 40,8 auf 11,0 ms unter Last

Christophs Einwand beim TP6-Abschluss war berechtigt, und er kippt die Erklaerung,
die ich einen Tag lang vertreten habe.

ABNAHME (gleiche NAS-Last, gleicher Messclient, Kontrolle inklusive):
  Priorisierung aus    40,8 ms avg / 53,4 max
  Priorisierung an     11,0 ms avg / 14,6 max     -73 %

Die Last war echt, nicht behauptet: wan-up-total fuhr 9,0 Mbit (max-limit greift
exakt), wan-up-bulk 8,87 Mbit mit 1581 Drops, vlan100 tx 9,0 Mbps. Die Kontrolle
mit abgeschalteter Markierung war noetig, um auszuschliessen, dass die Verbesserung
bloss daher kommt, dass Bulk und Ping jetzt von verschiedenen Hosts stammen.

KORREKTUR AN TP6: dort steht, die 30 ms entstuenden im DOCSIS-Uplink und seien
unabaenderlich. Das ist widerlegt. Der Fehler lag in der METHODE dieser Messung:
Bulk und Messverkehr kamen vom SELBEN Host, also gab es fuer CAKEs triple-isolate
nichts zu trennen -- alles lag in derselben Klasse, und Shapen allein aendert keine
Reihenfolge. Was CAKE nicht schaffte, schafft explizite Klassentrennung.
TP6 traegt jetzt einen Warnhinweis und ist als Messprotokoll zu lesen, nicht als
Ursachenanalyse. Weiter gueltig bleibt: CAKE als EINE Queue ueber allem brachte
nichts (dreimal gemessen), und Interface-HTB ist auf diesem Geraet tot.

GEBAUT (Template [11a], via GC):
  2x mangle postrouting (VOR src-nat -- nur dort ist die LAN-Quelle sichtbar):
     NAS 10.40.20.10 -> bulkup, alles andere -> restup
  wan-up-total (parent=global, max-limit=9M)
     wan-up-rest  priority=1 limit-at=6M
     wan-up-bulk  priority=8 limit-at=1M

Drei Entscheidungen, begruendet im Template:
  - Prioritaet statt Cap: ein Limit haette die NAS auch nachts gebremst und
    Bandbreite verschenkt (DSM drosselt nicht, User-bestaetigt). limit-at=1M
    sorgt dafuer, dass der Sync nie ganz verhungert.
  - src-address=10.40.20.10, NICHT VLAN20: dort haengen auch HA, Nautobot, pve.
  - parent=global, nicht vlan100: Interface-HTB ist hier wirkungslos.

GOVERNANCE: ComplianceRule ip-firewall-mangle angelegt (ingest-mangle-rule.py),
config_ordered=True -- die NAS-Regel muss vor dem Catch-all stehen, sonst waere die
Priorisierung STILL wirkungslos. 26 Rules x 4 Geraete = 104 Checks, 104/104 gruen.

Formatfalle nebenbei: priority=8 ist Default und wird von /export weggelassen --
explizit im Template erzeugt es Dauer-Drift, bei dem das Geraet recht hat.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-23 06:38:39 +02:00
parent f15dea6d16
commit 890c9f4869
3 changed files with 215 additions and 42 deletions

View File

@@ -421,7 +421,16 @@ FT kaschierte das bisher als „Roaming" statt „schwache Abdeckung".
- **(b) Live-Torch als Ad-hoc-Observability:** DNS ist bei direktem 1.1.1.1 blind, **Flows nicht** (NATen über ap1). `torch` auf `vlan30`/`vlan50` gefiltert auf die Geräte-IP zeigt Ziel-IPs live (Versuni → AWS `eu-west-1` IoT erkennbar). Voraussetzung: Gerät aktiv. Merkregel: Airfryer nur online wenn er kocht → Capture ans Einschalten koppeln.
- **Abh.:** UNTRUSTED-Move des Airfryers (Kandidat, s. VLAN50) + TP5-Deny-by-default. Kein Blocker.
### TP6 — QoS/CAKE + Call-Quality-A/B-Test ▸ ✅ **GESCHLOSSEN 2026-08-23 — gebaut, gemessen, wieder ausgebaut. CAKE wirkt, reicht aber nicht an die Ursache.**
### TP6 — QoS/CAKE + Call-Quality-A/B-Test ▸ ✅ **GESCHLOSSEN 2026-08-23 — CAKE gebaut, gemessen, wieder ausgebaut.** ⚠️ **Die Erklaerung darin ist von TP6.1 ueberholt: nicht DOCSIS, sondern fehlende Klassentrennung.**
> 🔴 **ZUERST LESEN — diese Analyse ist teilweise widerlegt (2026-08-23, durch TP6.1).**
> Unten steht, die ~30 ms entstuenden im DOCSIS-Uplink und seien unabaenderlich. **Sie sind es
> nicht.** TP6.1 holt dieselbe Strecke unter derselben Saettigung auf **11,0 ms** — allein durch
> Klassentrennung mit Prioritaet. Der Fehler lag in der **Methode** hier: Bulk und Messverkehr
> kamen vom **selben Host**, damit gab es fuer CAKEs `triple-isolate` nichts zu trennen, und
> blosses Shapen aendert keine Reihenfolge. **Weiter gueltig bleibt:** dass CAKE als *eine*
> Queue ueber allem nichts brachte (dreimal gemessen), und der Befund zur Queue-Platzierung
> (Interface-HTB tot, Global-HTB wirkt). Der Rest dieses Abschnitts ist als Messprotokoll zu
> lesen, nicht als Ursachenanalyse.
> 🔴 **A/B gemessen, gleicher Client, gleiche Methode, Minuten auseinander:**
>
> | Konfiguration | avg Latenz unter Upload-Last |
@@ -549,50 +558,54 @@ FT kaschierte das bisher als „Roaming" statt „schwache Abdeckung".
Ohne diese Zahl ist die übliche CAKE-Vorgabe „85–95 % Linerate" geraten.
- **Abh.:** TP5 ✅ (keine Blocker mehr). Vorgelagert: die Messung oben.
### TP6.1 — Saettigung vermeiden statt Bufferbloat bekaempfen (Bulk-Uploads zuruecknehmen) ▸ 🟠 **VORSCHLAG 2026-08-23, aus dem TP6-Abschluss heraus**
> **Der Gedanke kommt von Christoph** („dann koennten wir zumindest den Sync von der NAS
> zurueckhalten“) und er trifft eine Luecke im TP6-Urteil. TP6 hat gezeigt: die ~30 ms
> Zusatzlatenz sind **nicht** wegzushapen, weil sie im DOCSIS-Uplink entstehen. Aber sie
> treten **nur unter Saettigung** auf — im Leerlauf misst dieselbe Strecke **12,9 ms**.
### TP6.1 — Saettigung vermeiden statt Bufferbloat bekaempfen ▸ ✅ **LIVE UND GEMESSEN (2026-08-23): 40,8 → 11,0 ms unter Last**
> **Der Gedanke kam von Christoph** beim TP6-Abschluss („dann koennten wir zumindest den Sync
> von der NAS zurueckhalten“) — und er hat mein TP6-Urteil zu Recht angezweifelt.
>
> ⚖️ **Damit ist das Ziel ein anderes: nicht die Latenz unter Last senken, sondern die Last
> gar nicht erst entstehen lassen.** Ein NAS-Sync, der bei laufendem Call zurueckweicht,
> haelt die Leitung aus der Saettigung — und dann liegt der Call bei 12,9 statt 42 ms. Das
> ist die Verbesserung, die CAKE nicht liefern konnte, und sie ist **groesser** als alles, was
> Bufferbloat-Bekaempfung hier je gebracht haette.
> 🟢 **Abnahme, echte Saettigung, Kontrollmessung inklusive:**
>
> ✅ **Die Vorarbeit ist erledigt und bewiesen** (TP6): der **Global-HTB-Weg funktioniert** auf
> diesem Geraet — `mangle chain=postrouting out-interface=vlan100 action=mark-packet` plus
> `/queue tree parent=global packet-mark=…`. Gemessen: zaehlt 6 MB, drosselt 9,3 → 7,78 Mbit.
> Der Interface-Weg (`parent=<interface>`) ist dagegen tot, s. TP6.
> | gleiche NAS-Last, gleicher Messclient | avg | max |
> |---|---|---|
> | Priorisierung **aus** | **40,8 ms** | 53,4 ms |
> | Priorisierung **an** | **11,0 ms** | 14,6 ms |
>
> **Entwurf (zu bauen, nicht gebaut):** ein Parent-Tree mit `max-limit` knapp unter der
> Linerate — nur so muss HTB ueberhaupt entscheiden — und darunter zwei Klassen:
> - `priority=8` **Bulk**: Upload **von der NAS** (`src-address=10.40.20.10`). Bewusst die
> Host-IP, **nicht** ganz VLAN20 — dort haengen auch HA, Nautobot und pve, die nicht
> pauschal hinten anstehen sollen.
> - `priority=1` **Rest**: alles andere, insbesondere Calls.
> **−73 %.** Und die Last war echt, nicht behauptet: `wan-up-total` fuhr **9,0 Mbit**
> (das max-limit greift exakt), `wan-up-bulk` 8,87 Mbit mit **1581 Drops** — der Sync wurde
> aktiv gebremst, waehrend `wan-up-rest` frei durchlief. `vlan100 tx = 9,0 Mbps`.
> Die Kontrolle mit abgeschalteter Markierung war noetig, um auszuschliessen, dass die
> Verbesserung bloss daher kommt, dass Bulk und Ping jetzt von verschiedenen Hosts stammen.
>
> 🔴 **Priorisierung, kein hartes Limit.** Ein festes Cap wuerde den Sync auch dann bremsen,
> wenn die Leitung frei ist. Prioritaet nimmt ihm die Bandbreite nur, solange jemand anders
> sie braucht — das ist genau die Bedingung, unter der es hier ueberhaupt weh tut.
> 🔴 **Damit ist die DOCSIS-Erklaerung aus TP6 widerlegt.** Dort stand, die ~30 ms
> entstuenden stromabwaerts im Uplink und seien unabaenderlich. Sie sind es nicht — sie
> loesen sich auf, sobald der Verkehr in **getrennte Klassen** faellt. Der Fehler steckte in
> der TP6-**Methode**: Bulk und Messverkehr kamen vom **selben Host**, also gab es fuer CAKEs
> Host-Fairness (`triple-isolate`) nichts zu trennen — alles lag in derselben Klasse, und
> Shapen allein aendert an einer Reihenfolge nichts. Was CAKE nicht schaffte, schafft
> **explizite Klassentrennung mit Prioritaet**. Merkregel: nicht die Bandbreite ist das
> Problem, sondern **wer vor wem drankommt**.
>
> **Preis, ehrlich:** der Parent muss unter die Linerate shapen (~1 Mbit Spitze weniger,
> derselbe Preis wie bei CAKE), und Mangle kostet CPU pro Paket — bei 9,6 Mbit WAN irrelevant.
> **Was gebaut ist** (Template [11a], via GC, 104/104 compliant):
> - zwei `mangle`-Regeln in `postrouting` (**vor** src-nat — nur dort ist die LAN-Quelle noch
> sichtbar): NAS → `bulkup`, alles andere → `restup`
> - `wan-up-total` (`parent=global`, `max-limit=9M`) mit zwei Klassen darunter:
> `wan-up-rest` `priority=1 limit-at=6M` und `wan-up-bulk` `priority=8 limit-at=1M`
>
> 🔴 **Governance-Vorbedingung, dieselbe wie bei TP6:** `/ip firewall mangle` steht unter
> **keiner ComplianceRule**. Die Regeln waeren also unsichtbarer Drift. Vor dem Bau eine Rule
> `ip-firewall-mangle` anlegen — Muster liegt mit `nautobot/ingest-queue-rule.py` vor. Die
> Rule `queue` existiert bereits und deckt den Tree-Teil ab.
> **Drei Entscheidungen, die begruendet bleiben sollen:**
> 1. **Prioritaet statt hartem Cap** — ein Limit haette die NAS auch nachts gebremst und
> Bandbreite verschenkt (DSM drosselt von sich aus nicht, User-bestaetigt 2026-08-23).
> `limit-at=1M` sorgt dafuer, dass der Sync nie ganz verhungert.
> 2. **`src-address=10.40.20.10`, nicht VLAN20** — in INFRA haengen auch HA, Nautobot und
> pve. Wer das je auf `10.40.20.0/24` erweitert, verlangsamt seine eigenen Werkzeuge.
> 3. **`parent=global`, nicht `parent=vlan100`** — Interface-HTB ist auf diesem Geraet tot
> (hw-offloadetes out-interface, s. TP6).
>
> 🔴 **Abnahme misst den Call, nicht die Queue:** Ping-Latenz waehrend eines echten
> NAS-Syncs, gegen die 12,9 ms idle. Ein Queue-Zaehler beweist hier gar nichts — genau der
> Fehler, der in TP6 eine Nacht gekostet hat (`feedback_abnahme_wirkung_nicht_anzeige`).
> **Vorher pruefen, ob der Fall ueberhaupt auftritt:** laeuft der Synology-Sync tatsaechlich
> ins offene Messer, oder drosselt DSM ihn ohnehin schon? Ohne diesen Nachweis waere TP6.1
> eine Loesung auf Verdacht — und davon hatte TP6 genug.
> ✅ **Governance-Vorbedingung erfuellt:** ComplianceRule **`ip-firewall-mangle`** angelegt
> (`nautobot/ingest-mangle-rule.py`), **`config_ordered=True`** — die NAS-Regel muss vor dem
> Catch-all stehen, sonst waere die Priorisierung **still** wirkungslos. Zaehler jetzt
> **26 Rules x 4 Geraeten = 104 Checks**.
>
> **Abh.:** keine harten. Erbt die Erkenntnisse aus TP6; blockiert nichts.
> 💡 **Offen, klein:** ob weitere Bulk-Quellen dazugehoeren (pve-Backups? Time Machine?).
> Erst messen, ob sie ueberhaupt saettigen — die Regel dafuer ist eine Zeile.
### TP7 — Media-Discovery (mDNS) für VLAN 40 ▸ ✅ FERTIG (2026-07-02) — `docs/tp7-mdns.md`
- ✅ **Built-in mDNS-Repeater** aktiv — **Live-Stand `crs326-core` (verifiziert 2026-08-14):**
@@ -2120,9 +2133,8 @@ den Weg, über den man den Fehler zurücknehmen wollte.
Datenpfad (im TP5-Log mit 137 Zeilen belegt); Container braucht nur noch der **öffentliche** Ingress.
Vorschlag: `nautobot` als Probe aus dem CF-Ingress nehmen.
- ~~**DoH-Cloudflare auf `crs326-core`**~~ ✅ **erledigt 2026-08-18** (TP23 Stufe 1 = TP21.1 TODO 1).
- **TP6.1 — Saettigung vermeiden (NEU 2026-08-23):** NAS-Sync per Prioritaet zuruecknehmen,
damit ein Call gar nicht erst in die Saettigung geraet (12,9 statt 42 ms). Vorarbeit aus TP6
ist bewiesen; Vorbedingung ist eine ComplianceRule fuer `/ip firewall mangle`.
- ~~**TP6.1 — Saettigung vermeiden**~~ ✅ **LIVE 2026-08-23: 40,8 → 11,0 ms unter Last** (−73 %).
NAS-Sync weicht bei Last zurueck, ComplianceRule `ip-firewall-mangle` angelegt, 104/104.
- **TP24 — DC-USV** (seit 2026-08-16 eigener TP, aus TP15 herausgelöst).
- ~~**TP19 — VLAN1-Client-Retirement / cudy-Teardown**~~ ✅ **geschlossen 2026-08-18** (VLAN1-ARP = 0). Die zwei Reste sind dorthin verschoben, wo sie hingehören: tote CF-Tunnel → TP16, HA-Portainer `setup_retry` → TP11.
- ~~**TP3.3 — WLAN-Coverage-Kur**~~ → **in TP25 aufgegangen** (2026-08-17). 802.11k/v ist repariert (08-13);
@@ -2157,7 +2169,7 @@ steht unten unter „Durch". Nachfolger ist **TP16.3**, das oben unter Follow-up
TP1 · TP2 · TP2.1 · TP3 (Rebuild 2026-08-08) · TP3.1 · TP4 (Rolle seit 08-08 auf dem Core) · TP7 · TP7.2 ·
TP10 (Kern) · TP14 (+14.1/14.2/14.2a/14.3/14.5) · TP15 · TP16 (Kern) · TP17 · TP19.1 · TP20 · TP21 · TP21.1 ·
TP22 · TP-R · **TP3.2** (08-17) · **TP5** (08-18) · **TP7.1** (08-18) · **TP19** (08-18) · **TP23 Stufe 1** (08-18) · **TP6** (08-23, geschlossen statt gebaut) · **TP26** (08-17) · **TP27** (08-17/18) · **TP28** (08-17, GC-Modell 08-18). **Verworfen:** TP9 (Gateway-HA, User-Entscheid 2026-08-08). **Obsolet:** Omada-PVID-Fix
TP22 · TP-R · **TP3.2** (08-17) · **TP5** (08-18) · **TP7.1** (08-18) · **TP19** (08-18) · **TP23 Stufe 1** (08-18) · **TP6** (08-23, geschlossen statt gebaut) · **TP6.1** (08-23, Upload-Prio live) · **TP26** (08-17) · **TP27** (08-17/18) · **TP28** (08-17, GC-Modell 08-18). **Verworfen:** TP9 (Gateway-HA, User-Entscheid 2026-08-08). **Obsolet:** Omada-PVID-Fix
(User-Entscheid 2026-07-22 — „nie wieder aufgreifen").
<details><summary>📜 Historische Fassung dieses Abschnitts (bis 2026-08-14 fortgeschrieben, hier bewusst erhalten)</summary>