mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-11-03 05:51:15 +02:00
refactor(marker): converge to filter single-path model, remove dual-apply endpoints
Markers now follow exactly the same apply pattern as packet filters: state lives in Link._markers, application goes through NIO (update() -> PUT /nio -> _ubridge_apply_markers). The former immediate-apply REST endpoints (/markers/start, /markers/stop on the compute side) and the per-node start_marker/stop_marker methods are removed — they were a legacy of the original capture-inspired design and have been superseded by the NIO flow. Changes: - controller/udp_link: start_marker/stop_marker/update_marker now set _markers state + call self.update() (mirrors update_filters). Removed _marker_capture_nodes runtime dict and its helpers. - controller/project: _create_link_from_topology_data restores _markers directly from persisted data (with BPF validation, like filter reload). No long calls start_marker during load. - compute: _ubridge_apply_markers swallows BPF compile errors (warn+skip), matching _ubridge_apply_filters behaviour so a single bad expression cannot break link creation / node restart. - Removed: /markers/start,stop endpoints (6 handlers across vpcs/qemu/docker route files), node start_marker/stop_marker methods (3 VM files), _ubridge_delete_marker_filter, _marker_capture_nodes, MarkerDelete schema. Net: ~280 lines of dead code removed; marker and packet filter now share a single, unified apply path via the NIO.
This commit is contained in:
11 files changed
+73
-412
No files matched your search
@@ -29,8 +29,6 @@ from typing import Union
|
||||
from gns3server import schemas
|
||||
from gns3server.compute.docker import Docker
|
||||
from gns3server.compute.docker.docker_vm import DockerVM
|
||||
from gns3server.compute.marker.marker_manager import MarkerManager
|
||||
|
||||
from .dependencies.authentication import compute_authentication, ws_compute_authentication
|
||||
|
||||
responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find project or Docker node"}}
|
||||
@@ -355,60 +353,6 @@ async def stop_docker_node_capture(
|
||||
await node.stop_capture(adapter_number)
|
||||
|
||||
|
||||
@router.post(
|
||||
"/{node_id}/adapters/{adapter_number}/ports/{port_number}/markers/start",
|
||||
dependencies=[Depends(compute_authentication)]
|
||||
)
|
||||
async def start_docker_node_marker(
|
||||
*,
|
||||
project_id: UUID,
|
||||
adapter_number: int,
|
||||
port_number: int,
|
||||
marker_data: schemas.MarkerCreate,
|
||||
node: DockerVM = Depends(dep_node)
|
||||
) -> dict:
|
||||
"""
|
||||
Attach a traffic-insight ``mark`` filter to the Docker node's uBridge bridge.
|
||||
"""
|
||||
|
||||
pcap_path = os.path.join(
|
||||
node.project.markers_working_directory(),
|
||||
f"{node.id}_{marker_data.link_id}_{marker_data.name}.pcap"
|
||||
)
|
||||
await node.start_marker(adapter_number, marker_data.name, marker_data.bpf, pcap_path, marker_data.tag)
|
||||
MarkerManager.instance().register(
|
||||
str(project_id), node.id, marker_data.name, marker_data.link_id, marker_data.tag
|
||||
)
|
||||
nio = node.get_nio(adapter_number)
|
||||
if nio:
|
||||
nio.markers[marker_data.name] = {
|
||||
"bpf": marker_data.bpf, "tag": marker_data.tag, "link_id": marker_data.link_id
|
||||
}
|
||||
return {"pcap_file_path": str(pcap_path)}
|
||||
|
||||
|
||||
@router.post(
|
||||
"/{node_id}/adapters/{adapter_number}/ports/{port_number}/markers/stop",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
dependencies=[Depends(compute_authentication)]
|
||||
)
|
||||
async def stop_docker_node_marker(
|
||||
adapter_number: int,
|
||||
port_number: int,
|
||||
marker_data: schemas.MarkerDelete,
|
||||
node: DockerVM = Depends(dep_node)
|
||||
) -> None:
|
||||
"""
|
||||
Remove a traffic-insight ``mark`` filter from the Docker node's uBridge bridge.
|
||||
"""
|
||||
|
||||
await node.stop_marker(adapter_number, marker_data.name)
|
||||
MarkerManager.instance().unregister(node.id, marker_data.name)
|
||||
nio = node.get_nio(adapter_number)
|
||||
if nio:
|
||||
nio.markers.pop(marker_data.name, None)
|
||||
|
||||
|
||||
@router.get(
|
||||
"/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream",
|
||||
dependencies=[Depends(compute_authentication)]
|
||||
|
||||
@@ -30,8 +30,6 @@ from gns3server import schemas
|
||||
from gns3server.compute import qemu
|
||||
from gns3server.compute.qemu import Qemu
|
||||
from gns3server.compute.qemu.qemu_vm import QemuVM
|
||||
from gns3server.compute.marker.marker_manager import MarkerManager
|
||||
|
||||
from .dependencies.authentication import compute_authentication, ws_compute_authentication
|
||||
|
||||
import logging
|
||||
@@ -384,60 +382,6 @@ async def stop_qemu_node_capture(
|
||||
await node.stop_capture(adapter_number)
|
||||
|
||||
|
||||
@router.post(
|
||||
"/{node_id}/adapters/{adapter_number}/ports/{port_number}/markers/start",
|
||||
dependencies=[Depends(compute_authentication)]
|
||||
)
|
||||
async def start_qemu_node_marker(
|
||||
*,
|
||||
project_id: UUID,
|
||||
adapter_number: int,
|
||||
marker_data: schemas.MarkerCreate,
|
||||
port_number: int = Path(..., ge=0, le=0),
|
||||
node: QemuVM = Depends(dep_node)
|
||||
) -> dict:
|
||||
"""
|
||||
Attach a traffic-insight ``mark`` filter to the QEMU node's uBridge bridge.
|
||||
"""
|
||||
|
||||
pcap_path = os.path.join(
|
||||
node.project.markers_working_directory(),
|
||||
f"{node.id}_{marker_data.link_id}_{marker_data.name}.pcap"
|
||||
)
|
||||
await node.start_marker(adapter_number, marker_data.name, marker_data.bpf, pcap_path, marker_data.tag)
|
||||
MarkerManager.instance().register(
|
||||
str(project_id), node.id, marker_data.name, marker_data.link_id, marker_data.tag
|
||||
)
|
||||
nio = node.get_nio(adapter_number)
|
||||
if nio:
|
||||
nio.markers[marker_data.name] = {
|
||||
"bpf": marker_data.bpf, "tag": marker_data.tag, "link_id": marker_data.link_id
|
||||
}
|
||||
return {"pcap_file_path": str(pcap_path)}
|
||||
|
||||
|
||||
@router.post(
|
||||
"/{node_id}/adapters/{adapter_number}/ports/{port_number}/markers/stop",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
dependencies=[Depends(compute_authentication)]
|
||||
)
|
||||
async def stop_qemu_node_marker(
|
||||
adapter_number: int,
|
||||
marker_data: schemas.MarkerDelete,
|
||||
port_number: int = Path(..., ge=0, le=0),
|
||||
node: QemuVM = Depends(dep_node)
|
||||
) -> None:
|
||||
"""
|
||||
Remove a traffic-insight ``mark`` filter from the QEMU node's uBridge bridge.
|
||||
"""
|
||||
|
||||
await node.stop_marker(adapter_number, marker_data.name)
|
||||
MarkerManager.instance().unregister(node.id, marker_data.name)
|
||||
nio = node.get_nio(adapter_number)
|
||||
if nio:
|
||||
nio.markers.pop(marker_data.name, None)
|
||||
|
||||
|
||||
@router.get(
|
||||
"/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream",
|
||||
dependencies=[Depends(compute_authentication)]
|
||||
|
||||
@@ -29,8 +29,6 @@ from uuid import UUID
|
||||
from gns3server import schemas
|
||||
from gns3server.compute.vpcs import VPCS
|
||||
from gns3server.compute.vpcs.vpcs_vm import VPCSVM
|
||||
from gns3server.compute.marker.marker_manager import MarkerManager
|
||||
|
||||
from .dependencies.authentication import compute_authentication, ws_compute_authentication
|
||||
|
||||
responses = {404: {"model": schemas.ErrorMessage, "description": "Could not find project or VMware node"}}
|
||||
@@ -305,65 +303,6 @@ async def stop_vpcs_node_capture(
|
||||
await node.stop_capture(port_number)
|
||||
|
||||
|
||||
@router.post(
|
||||
"/{node_id}/adapters/{adapter_number}/ports/{port_number}/markers/start",
|
||||
dependencies=[Depends(compute_authentication)]
|
||||
)
|
||||
async def start_vpcs_node_marker(
|
||||
*,
|
||||
project_id: UUID,
|
||||
port_number: int,
|
||||
marker_data: schemas.MarkerCreate,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
node: VPCSVM = Depends(dep_node)
|
||||
) -> dict:
|
||||
"""
|
||||
Attach a traffic-insight ``mark`` filter to the VPCS node's uBridge bridge.
|
||||
On BPF match uBridge emits a MARK signal and appends the packet to the pcap.
|
||||
"""
|
||||
|
||||
pcap_path = os.path.join(
|
||||
node.project.markers_working_directory(),
|
||||
f"{node.id}_{marker_data.link_id}_{marker_data.name}.pcap"
|
||||
)
|
||||
await node.start_marker(port_number, marker_data.name, marker_data.bpf, pcap_path, marker_data.tag)
|
||||
MarkerManager.instance().register(
|
||||
str(project_id), node.id, marker_data.name, marker_data.link_id, marker_data.tag
|
||||
)
|
||||
# Mirror the marker spec onto the NIO so it survives a node restart (the NIO
|
||||
# persists across stop/start and _ubridge_apply_markers re-applies its markers).
|
||||
nio = node.get_nio(port_number)
|
||||
if nio:
|
||||
nio.markers[marker_data.name] = {
|
||||
"bpf": marker_data.bpf,
|
||||
"tag": marker_data.tag,
|
||||
"link_id": marker_data.link_id,
|
||||
}
|
||||
return {"pcap_file_path": pcap_path}
|
||||
|
||||
|
||||
@router.post(
|
||||
"/{node_id}/adapters/{adapter_number}/ports/{port_number}/markers/stop",
|
||||
status_code=status.HTTP_204_NO_CONTENT,
|
||||
dependencies=[Depends(compute_authentication)]
|
||||
)
|
||||
async def stop_vpcs_node_marker(
|
||||
*,
|
||||
port_number: int,
|
||||
marker_data: schemas.MarkerDelete,
|
||||
adapter_number: int = Path(..., ge=0, le=0),
|
||||
node: VPCSVM = Depends(dep_node)
|
||||
) -> None:
|
||||
"""
|
||||
Remove a traffic-insight ``mark`` filter from the VPCS node's uBridge bridge.
|
||||
"""
|
||||
|
||||
await node.stop_marker(port_number, marker_data.name)
|
||||
MarkerManager.instance().unregister(node.id, marker_data.name)
|
||||
nio = node.get_nio(port_number)
|
||||
if nio:
|
||||
nio.markers.pop(marker_data.name, None)
|
||||
|
||||
|
||||
@router.get(
|
||||
"/{node_id}/adapters/{adapter_number}/ports/{port_number}/capture/stream",
|
||||
|
||||
Reference in new issue
Block a user