mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-10-22 19:02:23 +03:00
feat(controller): offer Dynamips the kernel datapath
A Dynamips Ethernet port can anchor a kernel link whenever its compute's uBridge has the tap module — the anchors are uBridge-created TAPs the hypervisor merely opens, the same capability QEMU gates on, so no Dynamips-specific capability is needed. Serial, ATM and POS ports are excluded per port by the existing link-type check (the controller's port matrix decides), keeping them on the relay whatever the capabilities. Eligibility tests cover the mixed pairs (docker/qemu/iou endpoints on the same compute), the strict tap-capability requirement, and the serial exclusion.
This commit is contained in:
parent
7201a870da
commit
e5f65a510a
@ -182,9 +182,12 @@ class UDPLink(Link):
|
|||||||
datapath and cannot carry a kernel link at all. IOU's Ethernet
|
datapath and cannot carry a kernel link at all. IOU's Ethernet
|
||||||
bays anchor on persistent TAPs too, bound to its IOL fabric
|
bays anchor on persistent TAPs too, bound to its IOL fabric
|
||||||
(``iol_bridge add_nio_tap``) — a separate capability, since it can
|
(``iol_bridge add_nio_tap``) — a separate capability, since it can
|
||||||
be present or absent independently of the tap module. A kernel link
|
be present or absent independently of the tap module. Dynamips
|
||||||
is an Ethernet segment, so non-Ethernet ports (IOU serial) stay on
|
Ethernet slot ports anchor on persistent TAPs the hypervisor opens
|
||||||
the relay whatever the node's capabilities.
|
(the tap module again — the Dynamips binary itself creates nothing),
|
||||||
|
so it gates like QEMU. A kernel link is an Ethernet segment, so
|
||||||
|
non-Ethernet ports (IOU serial, Dynamips serial/ATM/POS adapters)
|
||||||
|
stay on the relay whatever the node's capabilities.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not Config.instance().settings.Server.enable_kernel_datapath:
|
if not Config.instance().settings.Server.enable_kernel_datapath:
|
||||||
@ -214,6 +217,11 @@ class UDPLink(Link):
|
|||||||
return capabilities.get("ubridge_tap") is True
|
return capabilities.get("ubridge_tap") is True
|
||||||
if node.node_type == "iou":
|
if node.node_type == "iou":
|
||||||
return capabilities.get("ubridge_iol_tap") is True
|
return capabilities.get("ubridge_iol_tap") is True
|
||||||
|
if node.node_type == "dynamips":
|
||||||
|
# The anchors are uBridge-created TAPs the Dynamips hypervisor
|
||||||
|
# merely opens (nio create_tap) — the same tap-module capability
|
||||||
|
# QEMU needs, not a Dynamips-specific one.
|
||||||
|
return capabilities.get("ubridge_tap") is True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
async def _prepare(self):
|
async def _prepare(self):
|
||||||
|
|||||||
@ -169,6 +169,70 @@ async def test_iou_eligibility_is_its_own_capability(project):
|
|||||||
assert link._kernel_datapath_eligible(node1, node2) is False
|
assert link._kernel_datapath_eligible(node1, node2) is False
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_kernel_datapath_eligible_for_dynamips_with_tap_support(project):
|
||||||
|
"""
|
||||||
|
Dynamips Ethernet slot ports anchor on persistent TAPs the hypervisor
|
||||||
|
opens (nio create_tap on a uBridge-created device), so they gate on the
|
||||||
|
tap module like QEMU — no Dynamips-specific capability — and mix with
|
||||||
|
docker/qemu/iou endpoints on the same compute.
|
||||||
|
"""
|
||||||
|
|
||||||
|
compute = MagicMock()
|
||||||
|
compute.id = "compute-1"
|
||||||
|
compute.capabilities = {"ubridge_tap": True, "ubridge_iol_tap": True}
|
||||||
|
node1 = _node(project, compute, "r1", node_type="dynamips")
|
||||||
|
node2 = _node(project, compute, "r2", node_type="dynamips")
|
||||||
|
link = await _link(project, node1, node2)
|
||||||
|
assert link._kernel_datapath_eligible(node1, node2) is True
|
||||||
|
|
||||||
|
for peer in (
|
||||||
|
_node(project, compute, "docker1"),
|
||||||
|
_node(project, compute, "qemu1", node_type="qemu"),
|
||||||
|
_node(project, compute, "iou1", node_type="iou"),
|
||||||
|
):
|
||||||
|
link = await _link(project, node1, peer)
|
||||||
|
assert link._kernel_datapath_eligible(node1, peer) is True
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_dynamips_eligibility_follows_the_tap_capability(project):
|
||||||
|
"""
|
||||||
|
A compute whose uBridge cannot create persistent TAPs keeps Dynamips on
|
||||||
|
the relay (the hypervisor would have nothing to open), and so does an
|
||||||
|
unreported/failed probe.
|
||||||
|
"""
|
||||||
|
|
||||||
|
node2 = _node(project, _tap_capable_compute(), "docker1")
|
||||||
|
for tap_support in (None, False):
|
||||||
|
compute = _tap_capable_compute(tap_support=tap_support)
|
||||||
|
node1 = _node(project, compute, "r1", node_type="dynamips")
|
||||||
|
link = await _link(project, node1, node2)
|
||||||
|
assert link._kernel_datapath_eligible(node1, node2) is False
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_kernel_datapath_not_eligible_for_dynamips_serial_ports(project):
|
||||||
|
"""
|
||||||
|
A Dynamips serial port (NM-4T, WIC-2T, ...) stays on the relay whatever
|
||||||
|
the compute's capabilities — the same per-port exclusion as IOU serial,
|
||||||
|
decided by the controller's port matrix.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from gns3server.controller.ports.serial_port import SerialPort
|
||||||
|
|
||||||
|
compute = MagicMock()
|
||||||
|
compute.id = "compute-1"
|
||||||
|
compute.capabilities = {"ubridge_tap": True}
|
||||||
|
|
||||||
|
node1 = _node(project, compute, "r1", node_type="dynamips")
|
||||||
|
node1._ports = [SerialPort("Serial0/0", 0, 0, 0)]
|
||||||
|
node2 = _node(project, compute, "r2", node_type="dynamips")
|
||||||
|
node2._ports = [SerialPort("Serial0/0", 0, 0, 0)]
|
||||||
|
link = await _link(project, node1, node2)
|
||||||
|
assert link._kernel_datapath_eligible(node1, node2) is False
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_kernel_datapath_not_eligible_for_serial_ports(project):
|
async def test_kernel_datapath_not_eligible_for_serial_ports(project):
|
||||||
"""
|
"""
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user