mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-10-12 13:35:31 +03:00
docs(features): quantify the kernel netem correl bias that collapses small rates
The kernel's correlated-random generator (get_crandom, sch_netem.c) truncates instead of wrapping, starving both edges of the stationary distribution: an event threshold below the correlation value is almost never reached. Measured with stock iproute2 on this kernel — uBridge's netlink encoding is identical: loss 1% + correl 25% drops nothing over 2000 pings (expected ~2%), 10%/25% measures ~1.8% one way, only the 50% symmetry point survives. duplicate and reorder correl share the same comparison structure and collapse the same way; gemodel is immune (Markov chain over plain uniform draws) and is the honest tool for bursty loss at a chosen mean rate. Documented in the packet-filters correlation-bias bullet, and surfaced in the two machine-facing descriptions (MCP link_update packet_loss note, controller filter schema) so agents and clients stop walking into the trap.
This commit is contained in:
parent
5238bd3b39
commit
d640050d4b
@ -70,7 +70,7 @@ On the kernel datapath the 13 types ride three kernel objects on the anchor. The
|
||||
| GNS3 filter | kernel implementation | Notes |
|
||||
|---|---|---|
|
||||
| `delay [ms, jitter, dist]` | netem `delay X jitter Y [distribution D]` | jitter 0 omitted; dist ∈ uniform/normal/pareto/paretonormal (kernel-only parameter) |
|
||||
| `packet_loss [%, correl]` | netem `loss P [correl C]` | per direction (see below); correlation is a kernel-only parameter |
|
||||
| `packet_loss [%, correl]` | netem `loss P [correl C]` | per direction (see below); correlation is a kernel-only parameter — and collapses small rates, see the correlation-bias bullet |
|
||||
| `corrupt [%]` | netem `corrupt P` | |
|
||||
| `duplicate [%, correl]` | netem `dup P [correl C]` | kernel-only type |
|
||||
| `rate ["512kbit"]` | netem `rate B` | tc-style integer+unit (bit/kbit/mbit/gbit/bps/kbps/mbps, ≤100gbit); kernel-only type |
|
||||
@ -86,6 +86,7 @@ On the kernel datapath the 13 types ride three kernel objects on the anchor. The
|
||||
## Semantics
|
||||
|
||||
* **Both endpoints** receive the filter dict and attach one qdisc to *their* anchor. The qdisc's egress covers traffic entering that node, so every direction of the link is impaired exactly once — the same net effect as the relay, where both directions cross the single filtered bridge. A `delay 100` link measures ≈200 ms RTT; `packet_loss 30` measures ≈51 % round-trip (1 − 0.7²); `rate 512kbit` adds ≈2× the per-packet serialization time to the RTT.
|
||||
* **Correlation collapses small rates (kernel netem defect, quantified).** netem's correlated draw mixes `answer = (value·(2³²−ρ) + last·ρ) >> 32` — truncated, never wrapped modulo 2³² — so the stationary distribution is starved at both edges: a draw almost never lands in the bottom ρ slice of the range. The effective rate of nominal P under correl C collapses toward zero whenever P ≲ C. Reproduced with stock iproute2 `tc` on this kernel (uBridge's netlink encoding is identical — GNS3 shows the same numbers): `1% 25%` → measured 0/1000 pings (theoretical ≈0.0002 %), `5% 25%` → ≈0.2 %, `10% 25%` → ≈1.8 % one-way (3.8 % round-trip measured), `25% 25%` → ≈16.7 %; nominal 50 % stays 50 % under every correl (the distribution's symmetry point). The same edge-starvation suppresses small `duplicate`/`reorder` rates under their correl and thins the tails of correlated jitter. `gemodel` is immune — a Markov chain over plain uniform draws — and is the honest tool for bursty loss at a chosen mean rate (p/(p+r)×(1-h)). Not fixable server- or uBridge-side without deviating from stock `tc` behavior; the kernel fix would be to wrap the mixing modulo 2³².
|
||||
* **Reconcile = reset + full re-apply.** The kernel's netem replace MERGES optional attributes (rate, correlation, reorder, corrupt, gemodel, distribution: an absent attr keeps its previous value), so re-applying a filter set with a parameter *removed* would silently keep the old value. Every apply therefore starts with `tc reset` (also drops clsact and its bpf_drop filters — re-added right after in the same flow) followed by one `netem set` built from the current filters; no per-parameter diffing. An empty filter set is the reset alone (ENOENT-tolerated).
|
||||
* **Extension gating.** The netem-extension keywords (rate, reorder, gemodel, dist, seed, limit — plus the correl suffixes, which gate on the `rate` token as the extension-build marker) probe `tc capabilities` once per uBridge process and require the tokens; a plain delay/loss/corrupt/dup filter never probes — an old uBridge serves the original surface untouched.
|
||||
* **kernel-only vs relay-available.** The extension types, `quota` and `window_drop` have no uBridge relay equivalent: `available_filters` hides them on relay links, setting one on a created relay link returns 409, and a project loaded with such filters on a link that cannot be kernel-wired drops them with a warning (invalid filters are dropped the same way at load). `frequency_drop` runs on both datapaths (relay userspace filter / eBPF every-Nth).
|
||||
|
||||
@ -808,7 +808,10 @@ async def link_update(
|
||||
* frequency_drop: [N] - Drop every Nth packet (N: -1 to 32767; -1 = drop
|
||||
everything). Exact on kernel links (eBPF counter)
|
||||
* packet_loss: [chance, correl?] - Loss percentage (0-100); correl (K)
|
||||
makes consecutive losses dependent (bursty)
|
||||
makes consecutive losses dependent (bursty). CAVEAT: the kernel netem
|
||||
correl suppresses small rates — a chance below ~the correl value drops
|
||||
almost nothing (1% + correl 25% ≈ zero loss); use gemodel for bursty
|
||||
loss at a known mean rate
|
||||
* delay: [ms, jitter?, distribution?] - Latency 1-32767 ms, jitter 0-32767
|
||||
ms; distribution (K) one of uniform|normal|pareto|paretonormal, needs
|
||||
jitter > 0
|
||||
|
||||
@ -54,7 +54,9 @@ FILTERS = [
|
||||
"type": "packet_loss",
|
||||
"name": "Packet loss",
|
||||
"description": "The percentage represents the chance for a packet to be lost. The optional correlation "
|
||||
"(kernel-datapath links only) makes consecutive losses dependent, like a bursty real network",
|
||||
"(kernel-datapath links only) makes consecutive losses dependent, like a bursty real network. "
|
||||
"Kernel caveat: a chance at or below the correlation value collapses toward zero effective loss "
|
||||
"(netem correlated-RNG bias) — use gemodel for bursty loss at a known mean rate",
|
||||
"parameters": [
|
||||
{"name": "Chance", "minimum": 0, "maximum": 100, "type": "int", "unit": "%"},
|
||||
{"name": "Correlation", "minimum": 0, "maximum": 100, "type": "int", "unit": "%"},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user