From d3527c00de2330aa09e189ef18a5e730350fc829 Mon Sep 17 00:00:00 2001 From: YueGuobin Date: Mon, 13 Jul 2026 15:12:08 +0800 Subject: [PATCH] fix(marker): extend marker support to dynamips and cloud nodes Dynamips needed its own NIO base class extended with a `_markers` attribute and `markers` property (mirroring the existing `filters` pattern), plus marker propagation from the controller-supplied NIO settings through NIOUDP.create/update to the common destination NIO that base_node._ubridge_apply_markers reads. Cloud simply needed the missing _ubridge_apply_markers calls after _ubridge_apply_filters in its two ubridge connection methods, same pattern as the earlier docker fix. Both types are now added back to _MARKER_CAPABLE_TYPES. --- gns3server/compute/builtin/nodes/cloud.py | 2 ++ gns3server/compute/dynamips/__init__.py | 1 + gns3server/compute/dynamips/nios/nio.py | 21 +++++++++++++++++++++ gns3server/compute/dynamips/nios/nio_udp.py | 2 ++ gns3server/controller/udp_link.py | 2 +- 5 files changed, 27 insertions(+), 1 deletion(-) diff --git a/gns3server/compute/builtin/nodes/cloud.py b/gns3server/compute/builtin/nodes/cloud.py index 50bf11084..d71669198 100644 --- a/gns3server/compute/builtin/nodes/cloud.py +++ b/gns3server/compute/builtin/nodes/cloud.py @@ -312,6 +312,7 @@ class Cloud(BaseNode): ) await self._ubridge_apply_filters(bridge_name, nio.filters) + await self._ubridge_apply_markers(bridge_name, nio) if port_info["type"] in ("ethernet", "tap"): if not self.manager.has_privileged_access(self.ubridge_path): @@ -452,6 +453,7 @@ class Cloud(BaseNode): bridge_name = f"{self._id}-{port_number}" if self._ubridge_hypervisor and self._ubridge_hypervisor.is_running(): await self._ubridge_apply_filters(bridge_name, nio.filters) + await self._ubridge_apply_markers(bridge_name, nio) async def _delete_ubridge_connection(self, port_number): """ diff --git a/gns3server/compute/dynamips/__init__.py b/gns3server/compute/dynamips/__init__.py index 3d620b6a2..eeb4ed91f 100644 --- a/gns3server/compute/dynamips/__init__.py +++ b/gns3server/compute/dynamips/__init__.py @@ -376,6 +376,7 @@ class Dynamips(BaseManager): raise DynamipsError(f"Could not create an UDP connection to {rhost}:{rport}: {e}") nio = NIOUDP(node, lport, rhost, rport) nio.filters = nio_settings.get("filters", {}) + nio.markers = nio_settings.get("markers", {}) nio.suspend = nio_settings.get("suspend", False) elif nio_settings["type"] == "nio_generic_ethernet": ethernet_device = nio_settings["ethernet_device"] diff --git a/gns3server/compute/dynamips/nios/nio.py b/gns3server/compute/dynamips/nios/nio.py index 2872b89eb..5c5c9ec6d 100644 --- a/gns3server/compute/dynamips/nios/nio.py +++ b/gns3server/compute/dynamips/nios/nio.py @@ -40,6 +40,7 @@ class NIO: self._hypervisor = hypervisor self._name = name self._filters = {} + self._markers = {} self._suspended = False self._capturing = False self._pcap_output_file = "" @@ -303,6 +304,26 @@ class NIO: assert isinstance(new_filters, dict) self._filters = new_filters + @property + def markers(self): + """ + Returns the list of traffic-insight markers for this NIO. + + :returns: markers (dictionary) + """ + + return self._markers + + @markers.setter + def markers(self, new_markers): + """ + Set markers for this NIO. + + :param new_markers: markers (dictionary) + """ + + self._markers = new_markers + @property def capturing(self): """ diff --git a/gns3server/compute/dynamips/nios/nio_udp.py b/gns3server/compute/dynamips/nios/nio_udp.py index 47faacc43..d849a37bf 100644 --- a/gns3server/compute/dynamips/nios/nio_udp.py +++ b/gns3server/compute/dynamips/nios/nio_udp.py @@ -82,10 +82,12 @@ class NIOUDP(NIO): self._source_nio = nio_udp.NIOUDP(self._local_tunnel_rport, "127.0.0.1", self._local_tunnel_lport) self._destination_nio = nio_udp.NIOUDP(self._lport, self._rhost, self._rport) self._destination_nio.filters = self._filters + self._destination_nio.markers = self._markers await self._node.add_ubridge_udp_connection(self._bridge_name, self._source_nio, self._destination_nio) async def update(self): self._destination_nio.filters = self._filters + self._destination_nio.markers = self._markers await self._node.update_ubridge_udp_connection(self._bridge_name, self._source_nio, self._destination_nio) async def close(self): diff --git a/gns3server/controller/udp_link.py b/gns3server/controller/udp_link.py index da08c5f6b..c52ec650f 100644 --- a/gns3server/controller/udp_link.py +++ b/gns3server/controller/udp_link.py @@ -26,7 +26,7 @@ from gns3server.utils.packet_filter_validation import validate_bpf_syntax, Filte # `mark` filter to). Mirrors _get_filter_node in link.py, minus "nat" # (which has no uBridge). _MARKER_CAPABLE_TYPES = frozenset({ - "vpcs", "qemu", "docker", "iou", + "vpcs", "qemu", "docker", "iou", "dynamips", "cloud", })