mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-08-27 12:30:13 +03:00
marker: incremental apply, clear bridge map on uBridge stop
_ubridge_apply_markers now installs only markers not already on the bridge (uBridge's reset_packet_filters preserves mark filters), so an NIO update no longer re-adds — and reopens — sibling markers' pcaps. _stop_ubridge clears _marker_filter_bridges so a node restart re-installs everything (the map would otherwise keep stale entries pointing at a fresh, empty uBridge).
This commit is contained in:
parent
caec71aa71
commit
95824b1861
@ -990,6 +990,10 @@ class BaseNode:
|
||||
log.info(f"Stopping uBridge hypervisor at {self._ubridge_hypervisor.endpoint}")
|
||||
await self._ubridge_hypervisor.stop()
|
||||
self._ubridge_hypervisor = None
|
||||
# uBridge is gone, so every marker filter (and its in-bridge state) is
|
||||
# gone too — clear the map so the next apply re-installs them all rather
|
||||
# than skipping them as "already installed".
|
||||
self._marker_filter_bridges.clear()
|
||||
|
||||
async def add_ubridge_udp_connection(self, bridge_name, source_nio, destination_nio):
|
||||
"""
|
||||
@ -1187,11 +1191,13 @@ class BaseNode:
|
||||
|
||||
async def _ubridge_apply_markers(self, bridge_name, nio):
|
||||
"""
|
||||
(Re-)apply every traffic-insight marker carried by *nio* to the uBridge
|
||||
bridge *bridge_name*. Called from ``add_ubridge_udp_connection`` (bridge
|
||||
creation / node restart) and ``update_ubridge_udp_connection`` (NIO update
|
||||
— the preceding ``_ubridge_apply_filters`` has already issued
|
||||
``reset_packet_filters``, so we must re-add markers to survive the reset).
|
||||
Install the traffic-insight markers carried by *nio* onto bridge
|
||||
*bridge_name* that aren't already there. uBridge's ``reset_packet_filters``
|
||||
preserves mark filters (contract), so on an NIO update we add only the new
|
||||
ones — re-adding an existing marker would either duplicate it or
|
||||
close/reopen its pcap. Called from ``add_ubridge_udp_connection`` (fresh
|
||||
bridge, empty map → installs all) and ``update_ubridge_udp_connection``
|
||||
(incremental).
|
||||
"""
|
||||
from gns3server.compute.marker.marker_manager import MarkerManager
|
||||
|
||||
@ -1202,9 +1208,14 @@ class BaseNode:
|
||||
manager = MarkerManager.instance()
|
||||
markers_dir = self.project.markers_working_directory()
|
||||
for name, spec in markers.items():
|
||||
link_id = spec.get("link_id", "")
|
||||
# Incremental: skip markers already on this bridge. uBridge keeps mark
|
||||
# filters across reset_packet_filters, so re-adding would duplicate (or
|
||||
# reopen the pcap). A fresh bridge has an empty map → installs all.
|
||||
if (name, link_id) in self._marker_filter_bridges:
|
||||
continue
|
||||
bpf = spec.get("bpf", "")
|
||||
tag = spec.get("tag")
|
||||
link_id = spec.get("link_id", "")
|
||||
pcap_path = os.path.join(
|
||||
markers_dir, f"{self._id}_{link_id}_{name}.pcap"
|
||||
)
|
||||
|
||||
@ -289,3 +289,29 @@ async def test_rebuild_marker_filter_delete_then_add(compute_project, manager):
|
||||
assert any("delete_packet_filter VPCS-10 m" in c for c in cmds)
|
||||
assert any("add_packet_filter VPCS-10 m mark" in c and "tcp" in c for c in cmds)
|
||||
assert any("enable_packet_filter VPCS-10 m off" in c for c in cmds)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_apply_markers_skips_already_installed(compute_project, manager):
|
||||
# Incremental apply: a marker already in _marker_filter_bridges is not
|
||||
# re-added (uBridge keeps it across reset), so its pcap isn't reopened.
|
||||
node = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", compute_project, manager)
|
||||
node._ubridge_send = AsyncioMagicMock()
|
||||
node._marker_filter_bridges["m", "L1"] = "VPCS-10" # already installed
|
||||
nio = NIOUDP(1234, "127.0.0.1", 4321)
|
||||
nio.markers = {"m": {"bpf": "icmp", "tag": None, "link_id": "L1", "direction": None, "enabled": True}}
|
||||
with patch("gns3server.compute.marker.marker_manager.MarkerManager") as mm:
|
||||
mm.instance.return_value.register = MagicMock()
|
||||
await node._ubridge_apply_markers("VPCS-10", nio)
|
||||
cmds = [c.args[0] for c in node._ubridge_send.call_args_list]
|
||||
assert not any("add_packet_filter" in c for c in cmds) # skipped, not re-added
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_stop_ubridge_clears_marker_bridges(compute_project, manager):
|
||||
# uBridge stopping drops every marker filter — the map must clear so the next
|
||||
# apply re-installs them instead of skipping as "already installed".
|
||||
node = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", compute_project, manager)
|
||||
node._marker_filter_bridges["m", "L1"] = "VPCS-10"
|
||||
await node._stop_ubridge()
|
||||
assert node._marker_filter_bridges == {}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user