controller: allow markers and packet filters on Ethernet switch links

The brctl Ethernet switch runs a per-port uBridge relay, so it can host
the mark filter and packet filters like any uBridge-backed node. Add
ethernet_switch to _MARKER_CAPABLE_TYPES and _get_filter_node, narrow the
UDPLink.update() NIO-PUT skip down to the Dynamips-hosted ethernet_hub,
and expose the matching compute endpoints: PUT nio (filter/marker
reapply) plus the per-marker toggle/pause/resume/delete/rebuild routes.

The ethernet_hub keeps its exclusion: its routes still wire into the
Dynamips hub, which has no uBridge of its own.
This commit is contained in:
YueGuobin committed 2026-08-21 21:41:51 +08:00
1 parent 210103058f
commit 72dc10a669
9 files changed
+282 -17

No files matched your search

+2
View File
@@ -624,6 +624,8 @@ class Link:
"nat",
"virtualbox",
"docker",
# the brctl Ethernet switch applies filters on its per-port uBridge relays
"ethernet_switch",
):
return node["node"]
return None
+9 -5
View File
@@ -24,12 +24,13 @@ from .link import Link, _UNSET
from .node_types import BUILTIN_NODE_TYPES
from gns3server.utils.packet_filter_validation import validate_bpf_syntax, FilterValidationError
# Node types without a uBridge bridge — a marker filter has nothing to attach to.
# Node types that can host a marker (have a uBridge bridge to attach the
# `mark` filter to). Mirrors _get_filter_node in link.py, minus "nat"
# (which has no uBridge).
# (which has no uBridge) and "ethernet_hub" (still Dynamips-hosted, no
# uBridge of its own). "ethernet_switch" hosts markers on the per-port
# uBridge relays of its brctl kernel-bridge backend.
_MARKER_CAPABLE_TYPES = frozenset({
"vpcs", "qemu", "docker", "iou", "dynamips", "cloud",
"vpcs", "qemu", "docker", "iou", "dynamips", "cloud", "ethernet_switch",
})
@@ -234,7 +235,10 @@ class UDPLink(Link):
self._link_data[0]["filters"] = node1_filters
self._link_data[0]["markers"] = node1_markers
self._link_data[0]["suspend"] = self._suspended
if node1.node_type not in ("ethernet_switch", "ethernet_hub"):
# The Ethernet hub is still Dynamips-hosted (no uBridge of its own and
# no PUT NIO route) — keep skipping its side. Every other node type,
# including the brctl Ethernet switch, re-applies via the NIO update.
if node1.node_type != "ethernet_hub":
await node1.put(
f"/adapters/{adapter_number1}/ports/{port_number1}/nio", data=self._link_data[0], timeout=120
)
@@ -244,7 +248,7 @@ class UDPLink(Link):
self._link_data[1]["filters"] = node2_filters
self._link_data[1]["markers"] = node2_markers
self._link_data[1]["suspend"] = self._suspended
if node2.node_type not in ("ethernet_switch", "ethernet_hub"):
if node2.node_type != "ethernet_hub":
await node2.put(
f"/adapters/{adapter_number2}/ports/{port_number2}/nio", data=self._link_data[1], timeout=221
)