fix: derive per-node IOL app id so linked routers get distinct MACs

IOL derives interface MACs from its application ID. With a constant
local-app every node shared the same MACs, and linked routers dropped
each other's frames as MAC loops — ARP never resolved and pings were
100% lost even though the whole uBridge datapath was forwarding.

Derive local-app from the node UUID (stable across restarts, kept in
1..1022) and align remote-app with the netiomux convention CML uses
(1023). Verified end to end: two iol-xe nodes, Ethernet0/0 link,
ARP resolves both ways, ping 4/5 (first loss = ARP), graceful
stop/start keeps the NVRAM config.
This commit is contained in:
YueGuobin committed 2026-09-05 21:54:51 +08:00
1 parent 0ca9ccc637
commit b17d021bf6
3 files changed
+26 -8

No files matched your search

+9 -5
View File
@@ -29,9 +29,8 @@ netiomux exposes per-interface AF_UNIX datagram sockets in the container's
``/tmp`` (``s%02d.sock`` receive, ``c%02d.sock`` send — raw Ethernet frames),
wired by the generic ``GNS3_UNIX_SOCKET_NIO`` capability of VendorDockerVM
(uBridge reaches them through a per-node runtime directory bound at /tmp —
see ``VendorDockerVM._unix_socket_host_dir``). Because the netio bus
directory is private to the node, the application IDs are fixed constants
with no cross-node collisions.
see ``VendorDockerVM._unix_socket_host_dir``). The local application ID is
derived from the node ID so that linked nodes get distinct MACs.
This class is selected by the ``GNS3_IOL_RUNNER=1`` environment marker.
"""
@@ -194,8 +193,13 @@ class IOLDockerVM(VendorDockerVM):
"memory": self._iol_memory,
"num-eth": self.adapters * 4, # every adapter is a 4-port unit
"num-serial": 0, # GNS3 docker adapters are ethernet-only
"local-app": 1,
"remote-app": 2,
# IOL derives interface MACs from the local application ID
# (aabb.cc00.0<app><iface>0); every node needs a distinct one or
# linked routers share MACs and drop each other's frames as loops.
# Derived from the node ID: stable across restarts, unique enough
# (CML allocates per-lab sequential IDs for the same reason).
"local-app": int(self.id.replace("-", ""), 16) % 1022 + 1,
"remote-app": 1023, # netiomux's fake peer application ID
"user-id": os.getuid(),
"group-id": os.getgid(),
}