From 7c569812debad6d9b200f910c5863a27d062608c Mon Sep 17 00:00:00 2001 From: Marco Supino Date: Wed, 18 Mar 2026 09:10:48 +0200 Subject: [PATCH] fix: exclude eth0 from InterfaceCount for meshnet eth0 is the management interface and is skipped by meshnet (node.GetNodeLinks). When users explicitly define eth0 in their topology (e.g. to map it to Management1), len(Interfaces) over-counts and the init container waits for an interface that never appears. Made-with: Cursor --- topo/node/drivenets/drivenets.go | 13 ++++++- topo/node/drivenets/drivenets_test.go | 51 +++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/topo/node/drivenets/drivenets.go b/topo/node/drivenets/drivenets.go index 96be93b0..e52425c4 100644 --- a/topo/node/drivenets/drivenets.go +++ b/topo/node/drivenets/drivenets.go @@ -232,7 +232,7 @@ func (n *Node) cdnosCreate(ctx context.Context) error { ConfigFile: config.ConfigFile, InitImage: config.InitImage, Ports: ports, - InterfaceCount: len(nodeSpec.Interfaces), + InterfaceCount: meshnetInterfaceCount(nodeSpec.Interfaces), InitSleep: int(config.Sleep), Resources: node.ToResourceRequirements(nodeSpec.Constraints), Labels: nodeSpec.Labels, @@ -587,6 +587,17 @@ func (n *Node) DefaultNodeConstraints() node.Constraints { return defaultConstraints } +// meshnetInterfaceCount returns the number of interfaces that meshnet will +// actually create. eth0 is the management interface and is excluded from +// meshnet links (see node.GetNodeLinks), so it must not be counted. +func meshnetInterfaceCount(ifaces map[string]*tpb.Interface) int { + n := len(ifaces) + if _, ok := ifaces["eth0"]; ok { + n-- + } + return n +} + func init() { node.Vendor(tpb.Vendor_DRIVENETS, New) } diff --git a/topo/node/drivenets/drivenets_test.go b/topo/node/drivenets/drivenets_test.go index a6d1e8a6..934b87f0 100644 --- a/topo/node/drivenets/drivenets_test.go +++ b/topo/node/drivenets/drivenets_test.go @@ -108,6 +108,57 @@ func TestCdnosDefaults(t *testing.T) { } } +func TestMeshnetInterfaceCount(t *testing.T) { + tests := []struct { + name string + ifaces map[string]*tpb.Interface + want int + }{ + { + name: "nil map", + ifaces: nil, + want: 0, + }, + { + name: "empty map", + ifaces: map[string]*tpb.Interface{}, + want: 0, + }, + { + name: "only meshnet interfaces", + ifaces: map[string]*tpb.Interface{ + "eno0": {IntName: "eno0"}, + "eno1": {IntName: "eno1"}, + }, + want: 2, + }, + { + name: "eth0 excluded", + ifaces: map[string]*tpb.Interface{ + "eth0": {IntName: "eth0", Name: "Management1"}, + "eno0": {IntName: "eno0"}, + "eno1": {IntName: "eno1"}, + }, + want: 2, + }, + { + name: "only eth0", + ifaces: map[string]*tpb.Interface{ + "eth0": {IntName: "eth0", Name: "Management1"}, + }, + want: 0, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := meshnetInterfaceCount(tt.ifaces) + if got != tt.want { + t.Errorf("meshnetInterfaceCount() = %d, want %d", got, tt.want) + } + }) + } +} + func TestDefaultNodeConstraints(t *testing.T) { n := &Node{} constraints := n.DefaultNodeConstraints()