mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-11-06 07:11:13 +02:00
feat(docker): expose netem-extension packet filters on kernel links
Surface the netem extensions delivered in uBridge feature/tc-netem-ext as GNS3 filter types: rate (tc-style bandwidth string), reorder (needs delay), gemodel (Gilbert-Elliot bursty loss, exclusive with packet_loss), duplicate, seed and limit, plus the delay jitter distribution and the loss/dup correlation parameters. All are kernel-datapath only — the relay's packet-filter registry has no equivalent, so available_filters hides them on relay links, setting one on a created relay link returns 409, and the project-load path drops them with a warning (update_filters runs before the datapath is decided, so it cannot reject there). Validation mirrors the tc grammar: reorder requires delay, gemodel and packet_loss are mutually exclusive, a distribution requires jitter > 0, rate is integer+unit capped at 100gbit. The translation in DockerVM._netem_command_parts emits the frozen grammar order and gates extension keywords on the 'tc capabilities' netem token list (probed once per uBridge process; a plain delay/loss/corrupt/dup filter never probes, keeping old uBridge builds untouched; the correl suffix has no token and gates on 'rate' as the extension-build marker). Reconcile became reset-before-set: the kernel's netem change merges optional attributes (rate, correlation, reorder, corrupt, gemodel, distribution, seed keep their previous value when the new message omits them), so removing a parameter needs an explicit 'tc reset' — the bpf_drop filters are re-added right after in the same flow, so the clsact churn is invisible. The capability check runs before the reset so a failed update leaves the previous qdisc in place. e2e (isolated instance, kernel link): 24/24 — rate 512kbit adds exactly 2x the per-packet serialization to the RTT (45.5 ms for 1400-byte pings), paretonormal jitter + rate-cleared leak check, reorder gap 5, gemodel 50% bursty loss, duplicate, loss 30% correl 50%, seed 42 + limit 5000 visible in the qdisc dump, suspend/resume and node restart keep the filters, relay link rejects rate with 409, teardown leaves no netem. Full unit suite: 1916 passed.
This commit is contained in:
13 files changed
+1012
-108
No files matched your search
@@ -35,7 +35,11 @@ class UDPNIO(BaseModel):
|
||||
rhost: str = Field(..., description="Remote host")
|
||||
rport: int = Field(..., gt=0, le=65535, description="Remote port")
|
||||
suspend: Optional[bool] = Field(None, description="Suspend the NIO")
|
||||
filters: Optional[dict] = Field(None, description="Packet filters")
|
||||
filters: Optional[dict] = Field(
|
||||
None,
|
||||
description="Packet filters (relay-supported types only: delay/packet_loss/corrupt/frequency_drop/bpf — "
|
||||
"the netem extensions need a kernel-datapath NIO)",
|
||||
)
|
||||
markers: Optional[dict] = Field(None, description="Traffic-insight markers")
|
||||
|
||||
|
||||
@@ -74,10 +78,12 @@ class BridgeNIO(BaseModel):
|
||||
Kernel-datapath bridge Network Input/Output properties. The NIO tells the
|
||||
node to enslave its veth host end into the named kernel bridge instead of
|
||||
wiring a uBridge UDP relay. Impairment filters run on the veth host end:
|
||||
delay/packet_loss/corrupt as one tc netem qdisc, bpf as cls_bpf match-drop
|
||||
classifiers (needs a uBridge reporting cbpf). frequency_drop still has no
|
||||
kernel equivalent and is rejected. Markers and packet capture are served
|
||||
by uBridge's AF_PACKET modules on the veth host end.
|
||||
delay/packet_loss/corrupt and the netem extensions (rate, reorder,
|
||||
gemodel, duplicate, seed, limit, jitter distributions, loss correlation)
|
||||
as one tc netem qdisc, bpf as cls_bpf match-drop classifiers (needs a
|
||||
uBridge reporting cbpf). frequency_drop still has no kernel equivalent
|
||||
and is rejected. Markers and packet capture are served by uBridge's
|
||||
AF_PACKET modules on the veth host end.
|
||||
"""
|
||||
|
||||
type: BridgeNIOType
|
||||
@@ -85,7 +91,8 @@ class BridgeNIO(BaseModel):
|
||||
suspend: Optional[bool] = Field(None, description="Suspend the NIO")
|
||||
filters: Optional[dict] = Field(
|
||||
None,
|
||||
description="Packet filters served on the veth host end (delay/packet_loss/corrupt via netem, bpf via cls_bpf)",
|
||||
description="Packet filters served on the veth host end (delay/packet_loss/corrupt and the netem extensions "
|
||||
"via one tc netem qdisc, bpf via cls_bpf)",
|
||||
)
|
||||
markers: Optional[dict] = Field(None, description="Traffic-insight markers (attached to the veth host end)")
|
||||
|
||||
|
||||
Reference in new issue
Block a user