8 Commits

Author SHA1 Message Date
YueGuobin
96006dcf58
docs(features): give packet filters their own doc with the evaluation-order diagram
The Packet filters section of docker-kernel-datapath.md was the de-facto
filter documentation every other datapath doc pointed at; move it to
features/packet-filters.md as the node-type-neutral home (veth or TAP
anchor), centered on a mermaid walkthrough of all 13 types through the
anchor's egress chain: clsact first (the eBPF stateful classifier's nth /
quota / window modes at prio 1, then the bpf expression lines at 10-99,
first drop wins), the single netem qdisc behind it (enqueue draws, one
time_to_send drained by the delay queue).

Clarify a naming trap the table verbs invite: uBridge's tc module only
borrows the iproute2 vocabulary — the tc ... tokens are its own hypervisor
command names over hand-built netlink messages (RTM_NEWQDISC /
RTM_NEWTFILTER), raw bpf() syscalls, embedded distribution tables and
instruction array, libpcap as a library only; the tc binary is never
invoked outside the test suite's oracles. Verified against the uBridge
sources (hypervisor_tc.c, tc_impair.bpf.c, tc_ebpf.c), not just the
commands gns3-server sends.

docker-kernel-datapath.md keeps a pointer section; the iol doc's filter
reference and docs/README.md's tree and catalog point at the new doc.
2026-10-07 22:39:39 +08:00
YueGuobin
7a9a514ea3
docs: kernel-datapath family review pass — accuracy fixes and pinned claims
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).
2026-10-06 00:21:10 +08:00
YueGuobin
74010b9abd
docs: dynamips kernel-datapath diagram suite, unified frame-path form across the family
The dynamips doc gets the full suite: anatomy (anchors reached by the
hypervisors' TAP fds, uBridge's AF_PACKET-tap / tc-qdisc sidebands), a
one-way copy-numbered relay comparison (six kernel/user crossings per
way against the kernel datapath's two TAP-fd legs), a staged walkthrough
(reserved-range diamond, egress clsact chain, capture/markers observation
sideband, copies 1-2) and a control sequence of real commands in real
order (hypervisor fd first, capture before markers, carrier last; router
handlers, not computes, as the per-node participants).

The four sibling frame paths are unified on the same form: netem qdisc
node labels, one capture/markers node outside the stages with AF_PACKET
tap edges anchored at ingress and post-chain egress, copy numbering
wherever the trace crosses the kernel/user boundary (qemu's two TAP-fd
legs, iol-docker's six socket/TAP legs), stage subgraphs with role-noted
titles everywhere (iol-docker restructured from its flat chain, iou's
chA/tapA variants folded into the canonical shapes).

The documentation skill records the rules as v3.1.0: four diagram kinds
(anatomy / comparison / control sequence / walkthrough), one step per
node, dashed sidebands per role with meaningful direction, numbered
crossings when copies are the point, glossary before the first diagram.
2026-10-06 00:21:10 +08:00
YueGuobin
e04552cdb0
docs(iol): IOL runner kernel datapath — diagram suite and glossary
Replace the ASCII overview with mermaid diagrams per the documentation
standard: a glossary table first, then the two-container architecture
(port bridges inside their uBridge process blocks, the per-link Linux
bridge circled, dashed sidebands split by direction — frame copies flow
to uBridge, qdisc installs to the anchor), a copy-counted relay diagram
(six kernel/user crossings each way, datapath-invariant — swapping
datapaths only changes the middle two), the frame path with the
reserved-range diamond, and the link creation sequence. Details moved
from the old bullets into per-diagram prose; paragraphs reflowed to one
per line.
2026-10-06 00:21:10 +08:00
YueGuobin
f03c94db6d
docs: link-local frame transparency on kernel links — spec and per-datapath sections
A Linux bridge standing in for a cable does not forward the IEEE 802.1D
reserved range (01:80:c2:00:00:00-0f) by default, so LACP/LLDP/802.1X never
crossed a kernel-datapath link while the UDP relay carried them fine. uBridge
now opens every enslave'd port's IFLA_BRPORT_GROUP_FWD_MASK to 0xfffd at
brctl addif time (branch feature/bridge-tap-l2only, commits 0284500/03a18f1/
cf4e494), which the six kernel-datapath feature docs now document as a
section: STP, LACP, 802.1X and LLDP/DCBX cross; 802.3x PAUSE / PFC stays
dropped — br_handle_frame()'s case 0x01 discards it unconditionally, no mask
can enable it, and PFC labs must use a relay link. The full contract, kernel
references and requirements live in the new design spec, marked landed.
2026-10-06 00:21:10 +08:00
YueGuobin
ff41a54364
test(e2e): assert the §E.2 idle-silence window in every kernel scenario
The L2-anchor spec's behavioral guarantee — an idle link stays silent for
5 s once the enslavement burst settles — only ran in the Dynamips and
Docker suites. It now also runs in QEMU, IOU, the IOL container, the
switch fast path and the switch cascade, which covers every host-device
creation path:

* tap create (Dynamips/QEMU/IOU anchors), docker create_veth (Docker host
  ends; the cascade's race-loser end is hardened after create by the
  server), bridge add_nio_tap (the IOL container anchor, the fifth
  creator), and the brctl switch bridges, whose multicast snooping is off
  precisely so the bridge role can reach silence;
* each scenario silences its guests first (IOS interfaces shut through
  the console; Docker guests' links down) and re-verifies the ping after;
* the cascade measures 8 devices at once (four absorbed router anchors,
  both cascade ends, both switch bridges).

IOL 158 s, cascade 293 s, ESW fast path 378 s, QEMU 428 s, IOU 308 s —
all green.
2026-10-06 00:21:10 +08:00
YueGuobin
1f544c96a5
test(e2e): classifier spot check and filter persistence on TAP anchors
The filter matrix (cls_bpf, the eBPF classifier) only ran on Docker veth
host ends; the IOU and IOL-container scenarios now spot-check it on their
TAP anchors and prove a filter survives a node restart:

* bpf "icmp" drops everything with clsact on the anchor, both ends, and
  clears back to an empty qdisc;
* frequency_drop 3 (the eBPF every-nth mode) measured 56 % round-trip
  loss (1 - (2/3)^2 = 55.6 % expected) in both scenarios;
* the IOU test applies delay 100 before a router stop/start: the fresh
  anchor gets netem back (tc level) and the restarted router's pings
  measure RTT >= 150 ms until the filter is cleared (a re-attach that
  dropped the filter would show ~100 ms).

IOU file 492 s, IOL file 182 s, both green.
2026-10-06 00:21:10 +08:00
YueGuobin
02340f2ed3
docs(iol): record the IOL runner container kernel datapath
The feature doc covers the architecture (one irreducible userspace hop
on the unix-socket leg; the link segment kernelized through the port
bridge's swappable TAP leg), the capability gate, the anchor lifecycle,
the swap flow, the inherited capture/markers/filters, the relay
fallback and the live verification — including the ensure-then-add
lesson (tap create is strictly create-only).

The other datapath docs' roadmaps catch up: the IOL runner container
has landed (and the ethernet-switch doc's stale 'cascade deferred'
exclusion from d2f8aba58 is corrected while there); the docker doc's
adapter table no longer rejects IOLDockerVM.
2026-10-06 00:21:09 +08:00