diff --git a/docs/features/iou-kernel-datapath.md b/docs/features/iou-kernel-datapath.md index b90efc673..8396f3998 100644 --- a/docs/features/iou-kernel-datapath.md +++ b/docs/features/iou-kernel-datapath.md @@ -152,6 +152,12 @@ Harmless on the relay, where suspend is emulated by the synthetic frequency_drop filter, but fatal for a kernel link, whose suspend *is* the anchor's admin state — a "suspended" link kept forwarding. +**Measuring seeded impairments on IOU**: IOL emits CDP/keepalive frames of +its own, and they draw from the netem RNG stream — a `seed`-reproducible run +never matches while they are on (measured: three rounds of mismatches, then +bit-identical pcaps after `no cdp run`). Turn the platform chatter off before +comparing seeded runs; the extra frames are visible in the capture. + ## Configuration ```ini diff --git a/gns3server/agent/gns3_copilot/gns3_client/api_handlers.py b/gns3server/agent/gns3_copilot/gns3_client/api_handlers.py index a7eb0e04d..ba3fca6c7 100644 --- a/gns3server/agent/gns3_copilot/gns3_client/api_handlers.py +++ b/gns3server/agent/gns3_copilot/gns3_client/api_handlers.py @@ -105,6 +105,10 @@ VALID_LINK_FIELDS = { "link_id", "project_id", "link_type", + # Runtime datapath fact (kernel bridge vs uBridge relay): the MCP tool + # descriptions have always advertised it, but it was missing here, so + # link_list could not return it at all. + "kernel_datapath", "nodes", "suspend", "link_style", diff --git a/tests/agent/mcp/test_handlers.py b/tests/agent/mcp/test_handlers.py index 9752c4422..cad7b89c0 100644 --- a/tests/agent/mcp/test_handlers.py +++ b/tests/agent/mcp/test_handlers.py @@ -425,6 +425,21 @@ class TestLink: result = get_links_handler({"project_id": "p1", "fields": ["link_id"]}, ctx) assert result["links"] == [{"link_id": "l1"}] + def test_list_can_ask_for_kernel_datapath(self, ctx): + """ + The datapath is a field the tool descriptions always advertised, so + it has to be requestable: a whitelist missing it rejected + fields=["kernel_datapath"] and made link_list unable to report which + links run on kernel interfaces. + """ + + from gns3server.agent.gns3_copilot.gns3_client.api_handlers import get_links_handler + + with patch(f"{AH}._get_connector") as m: + m.return_value = _mock_conn([{"link_id": "l1", "link_type": "ethernet", "kernel_datapath": True}]) + result = get_links_handler({"project_id": "p1", "fields": ["link_id", "kernel_datapath"]}, ctx) + assert result["links"] == [{"link_id": "l1", "kernel_datapath": True}] + def test_get(self, ctx): from gns3server.agent.gns3_copilot.gns3_client.api_handlers import get_link_handler