mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-11-06 07:11:13 +02:00
fix: hide kernel-datapath interfaces from the cloud node
The cloud node offered the kernel datapath's host-side interfaces — node anchors (gv/gq/gi/gd/gx/gp), switch cascade veth ends (gs) and cross-compute VXLAN devices (gvl) — in its interface list and even pre-filled them as ports on a freshly created cloud: none of them is flagged special and only "gns3*" names were filtered. These interfaces belong to the link or node that created them for the project's whole lifetime, so bridging a cloud to one would race its owner. Add is_kernel_datapath_interface() next to the naming contract in utils/kernel_anchor.py: exact-shape matching (prefix plus its fixed-length id-derived tail), so a user interface that merely starts with "gv" is never swallowed. The cloud keeps managed names out of its host-interface list and default ports mapping, while saved mappings keep working (the existence checks still see the full interface list).
This commit is contained in:
4 files changed
+108
-4
No files matched your search
@@ -36,6 +36,7 @@ is what makes links to stopped nodes wireable.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import re
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -113,3 +114,36 @@ def kernel_cascade_names(link_id):
|
||||
|
||||
stem = str(link_id).replace("-", "")[:10]
|
||||
return f"gs{stem}0", f"gs{stem}1"
|
||||
|
||||
|
||||
# Host-side interfaces the kernel datapath owns outright, recognised by
|
||||
# exact shape — the prefix plus its fixed-length id-derived tail — never by
|
||||
# bare prefix, so a user interface that merely starts with "gv" or "gs" is
|
||||
# not swallowed. Consumers keep these out of human-facing interface lists:
|
||||
# each belongs to the link or node that created it for as long as the
|
||||
# project exists (the names are deterministic, valid whether it runs or
|
||||
# not), so nothing else may bridge to it.
|
||||
_MANAGED_ANCHOR_PREFIXES = frozenset(ANCHOR_PREFIX.values())
|
||||
_MANAGED_ANCHOR_SUFFIX_SHAPE = re.compile(r"[0-9a-f]{8}e\d{1,2}p\d{1,2}")
|
||||
_MANAGED_CASCADE_SHAPE = re.compile(r"gs[0-9a-f]{10}[01]")
|
||||
# a cross-compute VXLAN device: "gvl" + 8 hex of the link id + 4 hex of the
|
||||
# endpoint node id (the cross-compute VXLAN naming keeps its devices out of
|
||||
# the anchor and "gns3" namespaces the same deterministic way)
|
||||
_MANAGED_VXLAN_SHAPE = re.compile(r"gvl[0-9a-f]{12}")
|
||||
|
||||
|
||||
def is_kernel_datapath_interface(name):
|
||||
"""
|
||||
Whether *name* is a host interface the kernel datapath manages by name —
|
||||
a node anchor, a switch cascade veth end, or a cross-compute VXLAN
|
||||
device. True for exactly the names the naming contract above can
|
||||
produce: the cloud node (and any other interface picker) uses this to
|
||||
refuse offering them, since bridging to one would race whatever link or
|
||||
node already owns it.
|
||||
"""
|
||||
|
||||
# "gvl" begins with the docker anchor prefix "gv", so an anchor miss must
|
||||
# still fall through to the VXLAN shape
|
||||
if name[:2] in _MANAGED_ANCHOR_PREFIXES and _MANAGED_ANCHOR_SUFFIX_SHAPE.fullmatch(name[2:]):
|
||||
return True
|
||||
return _MANAGED_CASCADE_SHAPE.fullmatch(name) is not None or _MANAGED_VXLAN_SHAPE.fullmatch(name) is not None
|
||||
Reference in new issue
Block a user