mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-10-12 21:45:41 +03:00
A correctness read-through of the five delivered datapath documents, plus
the two code comments that carried the same stale vocabulary.
Datapath selection: the VendorDockerVM selector is `console_type=docker_exec`
alone (`GNS3_SKIP_INIT` and friends are behavior knobs of the chosen class);
the cross-compute and anchor-less fallbacks are named for what they are; the
Ethernet-switch endpoint is the documented exception to the anchoring rule,
and the IOL runner container is called out as the Docker node that does not
anchor on a veth.
Filter vocabulary: the stateful eBPF program evaluates four modes
(nth → quota → window → flow), GNS3 exposes three of them, and window_drop
joins the kernel-only list; the correl suffixes gate on the `rate` token as
the extension-build marker.
group_fwd_mask: the 0xfffd port mask is applied inside uBridge's `brctl addif`
itself, not as a separate command — the link-creation sequences and the
operation tables no longer show an arrow the server never sends. Same class
of fix for `link set up` on the IOL anchor (addif already brought it up; the
command only pushes a suspended anchor back down) and for the QEMU carrier
replication (QMP `set_link`, gated by `replicate_network_connection_state`).
Lifecycles and stop orders re-worded around the invariant rather than the
node type: the fd holder must release before the devices are deleted, which
is QEMU's process-first order, IOU's uBridge-first order and Dynamips'
hypervisor-NIO-first order. Deferred wiring for a stopped endpoint is
documented as the common path it is, and the Dynamips "stop is not a close"
note now says what recovery from a dead hypervisor actually requires.
Dynamips specifics: a c7200 needs an adapter in slot 1 (slot 0 is the fixed
I/O slot), the tap-fd direction is stated correctly (writes inject into the
kernel, reads return what the kernel transmits), and the anchor registry is
name-keyed against the controller's port matrix by convention, not derivation.
IOL port bridge naming: `bridge{bay}` on unit 0, `bridge{bay}_{unit}`
elsewhere; the leg swap happens on link delete/re-create or a datapath
switch, while suspend is an in-place NIO update and a project reopen is a
fresh build.
Verified and Roadmap sections: the in-repo e2e suite is distinguished from
the isolated-instance development harness (IOU), assertions are stated with
their bounds and capability gates, and the roadmap entries collapse into the
one remaining project — VXLAN/GENEVE for cross-compute links.
Code comments: `flow` added to the documented mode order in the eBPF apply
path, and the `nio_bridge` module docstring corrected on which filter types
run on the kernel datapath (bpf via cls_bpf, frequency_drop/quota/window_drop
via the eBPF classifier — neither is relay-only any more).
76 lines
2.3 KiB
Python
76 lines
2.3 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 on the veth host end — one tc netem qdisc
|
|
(delay/loss/corrupt and the netem extensions), cls_bpf match-drop (bpf) and
|
|
the eBPF stateful classifier (frequency_drop, quota, window_drop); markers
|
|
and packet capture are served by uBridge's AF_PACKET modules on the
|
|
veth host end (marker add_kernel / capture start_kernel).
|
|
|
|
``bridge`` may be ``None``: the anchor is then bridged elsewhere — an
|
|
Ethernet switch absorbed it into the switch's own kernel bridge — and this
|
|
node applies only the link state the anchor carries (carrier, markers,
|
|
impairments), never bridge membership.
|
|
"""
|
|
|
|
from .nio import NIO
|
|
|
|
|
|
class NIOBridge(NIO):
|
|
"""
|
|
Kernel-bridge NIO.
|
|
|
|
:param bridge: name of the per-link Linux kernel bridge, or None when
|
|
the anchor is bridged by an Ethernet switch (see module docstring)
|
|
"""
|
|
|
|
def __init__(self, bridge):
|
|
|
|
super().__init__()
|
|
self._bridge = bridge
|
|
|
|
@property
|
|
def bridge(self):
|
|
"""
|
|
Returns the kernel bridge name, or None for an externally bridged
|
|
anchor.
|
|
|
|
: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,
|
|
}
|