mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-11-03 05:51:15 +02:00
fix: reconcile marker filters in _ubridge_apply_markers (delete/update)
The batch marker-def fan-out (PR #2848) routed create/update/delete marker_definition through memory_only + a batch PUT /nios/batch that re-applies markers via _ubridge_apply_markers. But _ubridge_apply_markers was strictly add-only: it skipped any (name, link_id) already in _marker_filter_bridges, and reset_packet_filters preserves mark filters (contract). So: * delete_marker_definition left the deleted marker's filter alive in uBridge (still matching / signalling / writing pcap) until node restart. * update_marker_definition (bpf/tag/direction change) never reached uBridge — the live filter kept the old expression until node restart. Make _ubridge_apply_markers a real reconcile against the desired nio.markers: - installed but no longer desired → delete_packet_filter + unlink pcap + unregister - desired with changed filter field → rebuild (delete + re-add) - desired with only enabled changed → instant toggle (pcap preserved) - desired and unchanged → skip - desired and new → add Track installed specs in a parallel _marker_specs dict so changes can be detected. Both base_node and the IOU iol_bridge override are updated. Added tests for the delete-removed and rebuild-changed-bpf paths.
This commit is contained in:
3 files changed
+153
-56
No files matched your search
@@ -367,6 +367,49 @@ async def test_apply_markers_skips_already_installed(compute_project, manager):
|
||||
assert not any("add_packet_filter" in c for c in cmds) # skipped, not re-added
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_apply_markers_deletes_removed(compute_project, manager):
|
||||
# Reconcile: a marker no longer in nio.markers is deleted from uBridge
|
||||
# (filter + registry), not left as an orphan still matching packets.
|
||||
node = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", compute_project, manager)
|
||||
node._ubridge_send = AsyncioMagicMock()
|
||||
node._ubridge_hypervisor = MagicMock()
|
||||
node._ubridge_hypervisor.is_running.return_value = True
|
||||
node._marker_filter_bridges["m", "L1"] = "VPCS-10"
|
||||
node._marker_specs["m", "L1"] = {"bpf": "icmp", "enabled": True}
|
||||
nio = NIOUDP(1234, "127.0.0.1", 4321)
|
||||
nio.markers = {} # marker removed
|
||||
with patch("gns3server.compute.marker.marker_manager.MarkerManager") as mm:
|
||||
mm.instance.return_value.unregister = MagicMock()
|
||||
await node._ubridge_apply_markers("VPCS-10", nio)
|
||||
cmds = [c.args[0] for c in node._ubridge_send.call_args_list]
|
||||
assert any("delete_packet_filter VPCS-10 m" in c for c in cmds)
|
||||
assert ("m", "L1") not in node._marker_filter_bridges
|
||||
assert ("m", "L1") not in node._marker_specs
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_apply_markers_rebuilds_changed_bpf(compute_project, manager):
|
||||
# Reconcile: a marker whose bpf changed is rebuilt (delete + re-add), so
|
||||
# uBridge ends up with the new expression — not the stale original.
|
||||
node = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", compute_project, manager)
|
||||
node._ubridge_send = AsyncioMagicMock()
|
||||
node._ubridge_hypervisor = MagicMock()
|
||||
node._ubridge_hypervisor.is_running.return_value = True
|
||||
node._marker_filter_bridges["m", "L1"] = "VPCS-10"
|
||||
node._marker_specs["m", "L1"] = {"bpf": "icmp", "tag": None, "direction": None,
|
||||
"data_link_type": None, "enabled": True}
|
||||
nio = NIOUDP(1234, "127.0.0.1", 4321)
|
||||
nio.markers = {"m": {"bpf": "tcp", "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 any("delete_packet_filter VPCS-10 m" in c for c in cmds) # old removed
|
||||
assert any("add_packet_filter VPCS-10 m mark" in c and "tcp" in c for c in cmds) # new 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
|
||||
|
||||
Reference in new issue
Block a user