From 1136fd342c1ec770ae37b1befb94bff08214dd7c Mon Sep 17 00:00:00 2001 From: Dmitrii Andreev Date: Wed, 8 Oct 2025 17:30:14 +0300 Subject: [PATCH] client: fix IPv6-only CNI interface support Fix a regression introduced in Nomad 1.9.0 where CNI bridge networking with IPv6-only interfaces would fail with 'no interface with an address' error. The issue was that while the code correctly populated the AddressIPv6 field for IPv6 addresses, several validation checks only examined the Address field (IPv4), causing IPv6-only configurations to be rejected. Changes: - Update interface selection logic in cniToAllocNet to accept interfaces with either IPv4 or IPv6 addresses (not just IPv4) - Update fallback logic to check both Address and AddressIPv6 fields - Update error check to only fail when both IPv4 and IPv6 are missing - Update AllocNetworkStatus.IsZero() to check AddressIPv6 field This allows CNI configurations with IPv6-only interfaces to work correctly, restoring functionality from Nomad 1.8.x. Fixes #26905 --- client/allocrunner/networking_cni.go | 10 +++++----- nomad/structs/structs.go | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/client/allocrunner/networking_cni.go b/client/allocrunner/networking_cni.go index ae31d68ec..60a5ec451 100644 --- a/client/allocrunner/networking_cni.go +++ b/client/allocrunner/networking_cni.go @@ -480,8 +480,8 @@ func (c *cniNetworkConfigurator) cniToAllocNet(res *cni.Result) (*structs.AllocN } } - // found a good interface, so we're done - if netStatus.Address != "" { + // found a good interface (with either IPv4 or IPv6), so we're done + if netStatus.Address != "" || netStatus.AddressIPv6 != "" { netStatus.InterfaceName = name return } @@ -493,7 +493,7 @@ func (c *cniNetworkConfigurator) cniToAllocNet(res *cni.Result) (*structs.AllocN // If no IP address was found, use the first interface with an address // found as a fallback - if netStatus.Address == "" { + if netStatus.Address == "" && netStatus.AddressIPv6 == "" { setStatus(false) c.logger.Debug("no sandbox interface with an address found CNI result, using first available", "interface", netStatus.InterfaceName, @@ -501,8 +501,8 @@ func (c *cniNetworkConfigurator) cniToAllocNet(res *cni.Result) (*structs.AllocN ) } - // If no IP address could be found, return an error - if netStatus.Address == "" { + // If no IP address (IPv4 or IPv6) could be found, return an error + if netStatus.Address == "" && netStatus.AddressIPv6 == "" { return nil, fmt.Errorf("failed to configure network: no interface with an address") } diff --git a/nomad/structs/structs.go b/nomad/structs/structs.go index d8cbf921c..4f99b92dd 100644 --- a/nomad/structs/structs.go +++ b/nomad/structs/structs.go @@ -12292,7 +12292,7 @@ func (a *AllocNetworkStatus) IsZero() bool { if a == nil { return true } - if a.InterfaceName != "" || a.Address != "" { + if a.InterfaceName != "" || a.Address != "" || a.AddressIPv6 != "" { return false } if !a.DNS.IsZero() {