mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-10-13 14:05:36 +03:00
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
69 lines
1.9 KiB
Python
69 lines
1.9 KiB
Python
#
|
|
# Copyright (C) 2026 GNS3 Technologies Inc.
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
|
|
"""
|
|
Interface for kernel-datapath bridge NIOs.
|
|
|
|
A NIO of this type instructs the node to enslave its adapter's veth host end
|
|
into the named Linux kernel bridge instead of wiring a uBridge UDP relay.
|
|
Frames then flow entirely in the kernel (veth -> bridge -> veth). Impairment
|
|
filters ride the NIO and run as one tc netem qdisc per veth host end (the
|
|
types without a netem equivalent — frequency_drop, bpf — stay relay-only);
|
|
markers and packet capture are served by uBridge's AF_PACKET modules on the
|
|
veth host end (marker add_kernel / capture start_kernel).
|
|
"""
|
|
|
|
from .nio import NIO
|
|
|
|
|
|
class NIOBridge(NIO):
|
|
|
|
"""
|
|
Kernel-bridge NIO.
|
|
|
|
:param bridge: name of the per-link Linux kernel bridge
|
|
"""
|
|
|
|
def __init__(self, bridge):
|
|
|
|
super().__init__()
|
|
self._bridge = bridge
|
|
|
|
@property
|
|
def bridge(self):
|
|
"""
|
|
Returns the kernel bridge name.
|
|
|
|
:returns: bridge name
|
|
"""
|
|
|
|
return self._bridge
|
|
|
|
def __str__(self):
|
|
|
|
return "NIO bridge"
|
|
|
|
def asdict(self):
|
|
|
|
return {
|
|
"type": "nio_bridge",
|
|
"bridge": self._bridge,
|
|
"suspend": self._suspended,
|
|
"filters": self._filters,
|
|
"markers": self._markers,
|
|
}
|