mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-11-04 06:21:15 +02:00
feat: cross-compute VXLAN kernel datapath
Cross-compute links can ride kernel VXLAN tunnels instead of the uBridge
UDP relay: each endpoint creates one VXLAN device (uBridge's rtnetlink
vxlan module) enslaved into the same per-link Linux bridge the same-host
datapath uses, so filters, markers, capture and suspend keep running on
the anchor unchanged. Opt-in (Server.enable_vxlan_cross_compute, default
off) because the tunnel caps the usable MTU at the underlay minus the
outer headers; the relay stays the default and the fallback.
The controller derives what the pair must agree on: one VNI per link
(upper VNI space, per-link random salt) and deterministic device names
(gvl{link}{node}) that make crashed-run leftovers claimable
(show -> delete -> create). Same-host compute pairs, switch endpoints
and serial/unix-socket containers stay on the relay.
A VNI the kernel refuses self-heals on every path it can surface:
interactive create retries a fresh salt then degrades to the relay;
project open re-dispatches refused batch entries the same way; node
start recognises the refused device, stops the half-started node,
re-wires both ends on a fresh VNI (or degrades the link) and retries
the start. The device MTU is derived from the lower device (dev=) and
the per-link bridge inherits it - no configuration. The capability
probe (ubridge_vxlan in /capabilities) runs one scratch create/delete
on a scratch port that never equals the configured dstport.
The e2e scenario runs two computes on one machine (a network namespace
joined by a veth pair as the fabric) and needs root.
This commit is contained in:
24 files changed
+2107
-59
No files matched your search
@@ -31,6 +31,13 @@ veth host end (marker add_kernel / capture start_kernel).
|
||||
Ethernet switch absorbed it into the switch's own kernel bridge — and this
|
||||
node applies only the link state the anchor carries (carrier, markers,
|
||||
impairments), never bridge membership.
|
||||
|
||||
A NIO may additionally carry ``vxlan`` (a BridgeVxlan spec): the link
|
||||
crosses computes through a VXLAN device this end creates (uBridge's
|
||||
``vxlan`` module) and enslaves into the same per-link bridge next to the
|
||||
anchor. The kernel encapsulates/decapsulates the frames; everything else —
|
||||
filters, markers, capture, carrier, suspend — still runs on the anchor, so
|
||||
the datapath behaves exactly like a same-host kernel link.
|
||||
"""
|
||||
|
||||
from .nio import NIO
|
||||
@@ -42,12 +49,16 @@ class NIOBridge(NIO):
|
||||
|
||||
:param bridge: name of the per-link Linux kernel bridge, or None when
|
||||
the anchor is bridged by an Ethernet switch (see module docstring)
|
||||
:param vxlan: cross-compute tunnel spec (dict: name/vni/remote/dstport)
|
||||
this end creates and enslaves into the bridge, or None for a
|
||||
same-host kernel link
|
||||
"""
|
||||
|
||||
def __init__(self, bridge):
|
||||
def __init__(self, bridge, vxlan=None):
|
||||
|
||||
super().__init__()
|
||||
self._bridge = bridge
|
||||
self._vxlan = vxlan
|
||||
|
||||
@property
|
||||
def bridge(self):
|
||||
@@ -60,6 +71,17 @@ class NIOBridge(NIO):
|
||||
|
||||
return self._bridge
|
||||
|
||||
@property
|
||||
def vxlan(self):
|
||||
"""
|
||||
Returns the cross-compute VXLAN tunnel spec, or None when the link
|
||||
is wired on this host alone.
|
||||
|
||||
:returns: dict (name/vni/remote/dstport) or None
|
||||
"""
|
||||
|
||||
return self._vxlan
|
||||
|
||||
def __str__(self):
|
||||
|
||||
return "NIO bridge"
|
||||
@@ -69,6 +91,7 @@ class NIOBridge(NIO):
|
||||
return {
|
||||
"type": "nio_bridge",
|
||||
"bridge": self._bridge,
|
||||
"vxlan": self._vxlan,
|
||||
"suspend": self._suspended,
|
||||
"filters": self._filters,
|
||||
"markers": self._markers,
|
||||
|
||||
Reference in new issue
Block a user