mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-11-04 22:41:12 +02:00
feat(docker): packet filters on kernel-datapath links via tc netem
Impairment filters with a netem equivalent (delay, packet_loss, corrupt) now run on the kernel datapath as one tc netem qdisc per veth host end, pushed through uBridge's netlink tc module (tc netem set / tc reset). This removes the relay delay filter's nanosleep bottleneck (upstream Both link endpoints carry the filters: each end's qdisc egress covers the traffic entering that container, so every direction is impaired exactly once -- the same net effect as the relay, where both directions cross the single filtered bridge. - controller: eligibility keys on relay-only types (frequency_drop, bpf) instead of any filter; kernel links push the real filters (the synthetic suspend frequency_drop no longer flips a suspended link to relay on reopen/reset); update_filters 409s only relay-only types; available_filters hides them on kernel links - compute: create_nio whitelists netem-capable filter types; the NIO update path keeps its own guard (PUT mutates the NIO in place); _ubridge_apply_netem translates the filter dict into one atomic netem-set (full re-apply IS the reconcile); node restart restores the qdisc, link deletion detaches it (the veth survives the link) - e2e (27/27): delay 100 -> 200.2 ms RTT, atomic replace 50 -> 100.2 ms, clear -> baseline, packet_loss 30 -> 48 % round-trip (expected 51 %), suspend/resume and node restart keep the qdisc, link delete leaves no residual impairment
This commit is contained in:
11 files changed
+459
-95
No files matched your search
@@ -361,8 +361,18 @@ class BaseManager:
|
||||
nio.suspend = nio_settings.get("suspend", False)
|
||||
elif nio_settings["type"] == "nio_bridge":
|
||||
nio = NIOBridge(nio_settings["bridge"])
|
||||
if nio_settings.get("filters"):
|
||||
raise ComputeError("Packet filters are not supported on kernel-datapath links")
|
||||
# Impairment filters with a tc netem equivalent run on the veth
|
||||
# host end; the relay-only types are rejected here (the controller
|
||||
# already keeps them off kernel links — this is the second guard).
|
||||
from gns3server.utils.packet_filter_validation import KERNEL_UNSUPPORTED_FILTERS
|
||||
|
||||
unsupported = KERNEL_UNSUPPORTED_FILTERS.intersection(nio_settings.get("filters") or {})
|
||||
if unsupported:
|
||||
raise ComputeError(
|
||||
"Packet filter(s) {} cannot run on a kernel-datapath link "
|
||||
"(no uBridge relay in the forwarding path)".format(", ".join(sorted(unsupported)))
|
||||
)
|
||||
nio.filters = nio_settings.get("filters", {})
|
||||
# Markers ride the NIO and attach to the veth host interface via
|
||||
# uBridge's AF_PACKET marker module (marker add_kernel).
|
||||
nio.markers = nio_settings.get("markers", {})
|
||||
|
||||
Reference in new issue
Block a user