2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2026-09-04 20:17:55 +00:00

fix(networkutils): OnlyV4 is answered from the cache whatever family it holds

getipaddr returns a cached address before it resolves, and the bypass tests
OnlyV6 and GetAllAddresses only. A caller asking OnlyV4 therefore receives
whatever the first lookup stored. An unrestricted lookup asks for AF_UNSPEC, so
on a dual-stack management node it stores the AAAA record, and %::hostiphash is
a global in a long-lived xcatd.

debian.pm resolves the install server with OnlyV4 and writes
nfsroot=<address>:/install. Given the cached IPv6 that renders
nfsroot=2001:db8::1:/install, which does not parse, so the Subiquity installer
never mounts and the node never completes. dhcp.pm and mknb.pm hold four more
OnlyV4 callers with the same exposure.

Skip the cache when OnlyV4 is asked for and the cached address is IPv6. The
lookup that follows requests AF_INET and replaces the entry with the IPv4
address, so the next caller of either kind gets a usable one. An IPv4 entry is
still served from the cache: the bypass is about the family of the cached
answer, not about disabling the cache for OnlyV4.

networkutils_getipaddr_onlyv4.t fails without this change.

Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
This commit is contained in:
Daniel Hilst
2026-09-03 17:17:04 -03:00
parent 2b6337d67d
commit a3e16d83f9
+13 -1
View File
@@ -288,8 +288,20 @@ sub getipaddr
#print "============================\n";
#cache, do not lookup DNS each time
#
# An unrestricted lookup asks for AF_UNSPEC and caches whatever came back, which
# on a dual-stack host is the AAAA record. Serving that to an OnlyV4 caller gives
# it an IPv6 address it cannot use: debian.pm renders nfsroot=<address>:<path>,
# and nfsroot=2001:db8::1:/install does not parse.
my $cached_v6 =
defined($::hostiphash{$iporhost})
&& $::hostiphash{$iporhost}
&& $::hostiphash{$iporhost}{hostip}
&& $::hostiphash{$iporhost}{hostip} =~ /:/;
if (
((not $extraarguments{OnlyV6}) and (not $extraarguments{GetAllAddresses})) and defined($::hostiphash{$iporhost}) and $::hostiphash{$iporhost})
((not $extraarguments{OnlyV6}) and (not $extraarguments{GetAllAddresses}))
and (not($extraarguments{OnlyV4} and $cached_v6))
and defined($::hostiphash{$iporhost}) and $::hostiphash{$iporhost})
{
if($extraarguments{GetNumber} ) {