From d2be0c386539b821418a9c310670b30d75a71f82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Ferr=C3=A3o?= <2031761+viniciusferrao@users.noreply.github.com> Date: Wed, 22 Jul 2026 19:17:17 -0300 Subject: [PATCH 1/4] fix(networks): exclude every link-local address from the networks table donets() only skips the exact address 'fe80::/64' when scanning routes, so a link-local route with any other prefix (e.g. a longer fe80:: subnet) is added to the networks table as a bogus network. Match any fe80:: prefix instead of the single literal value. Recovered from the unmerged lenovobuild branch (original 8b79cf85). Co-authored-by: Jarrod Johnson <10814490+jjohnson42@users.noreply.github.com> --- xCAT-server/lib/xcat/plugins/networks.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xCAT-server/lib/xcat/plugins/networks.pm b/xCAT-server/lib/xcat/plugins/networks.pm index 4a906e778..e8e1e9bf2 100644 --- a/xCAT-server/lib/xcat/plugins/networks.pm +++ b/xCAT-server/lib/xcat/plugins/networks.pm @@ -388,7 +388,7 @@ sub donets foreach (@ip6table) { my @ent = split /\s+/, $_; - if ($ent[0] eq 'fe80::/64' or $ent[0] eq 'unreachable' or + if ($ent[0] =~ m/^fe80::/ or $ent[0] eq 'unreachable' or $ent[1] eq 'via' or $ent[2] eq 'lo') { #Do not contemplate link-local, unreachable, gatewayed networks, From c97e973f36e446fa725ab831299f11ff34ba0510 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Ferr=C3=A3o?= <2031761+viniciusferrao@users.noreply.github.com> Date: Wed, 22 Jul 2026 19:18:48 -0300 Subject: [PATCH 2/4] fix(networks): skip nexthop and default lines when parsing IPv6 routes `ip -6 route` output for ECMP/multipath routes carries `nexthop` continuation lines, and a `default` route has no network prefix. donets() treated both as networks and added bogus entries to the networks table. Skip them alongside the existing link-local/unreachable/via/lo filtering. Recovered from the unmerged lenovobuild branch (original 7094ba0c). Co-authored-by: Jarrod Johnson <10814490+jjohnson42@users.noreply.github.com> --- xCAT-server/lib/xcat/plugins/networks.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xCAT-server/lib/xcat/plugins/networks.pm b/xCAT-server/lib/xcat/plugins/networks.pm index e8e1e9bf2..7ada4db2a 100644 --- a/xCAT-server/lib/xcat/plugins/networks.pm +++ b/xCAT-server/lib/xcat/plugins/networks.pm @@ -388,7 +388,7 @@ sub donets foreach (@ip6table) { my @ent = split /\s+/, $_; - if ($ent[0] =~ m/^fe80::/ or $ent[0] eq 'unreachable' or + if ($ent[0] =~ m/^fe80::/ or $ent[0] eq 'unreachable' or $ent[1] eq 'nexthop' or $ent[0] eq 'default' or $ent[1] eq 'via' or $ent[2] eq 'lo') { #Do not contemplate link-local, unreachable, gatewayed networks, From f8548ceeb9e8c8c50f06c6d5780178bde51a2937 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Ferr=C3=A3o?= <2031761+viniciusferrao@users.noreply.github.com> Date: Fri, 24 Jul 2026 13:07:37 -0300 Subject: [PATCH 3/4] fix(networks): validate IPv6 route filtering --- xCAT-server/lib/xcat/plugins/networks.pm | 22 +++++---- .../autotest/testcase/makenetworks/cases0 | 9 ++++ xCAT-test/unit/networks_ipv6_route_filter.t | 48 +++++++++++++++++++ 3 files changed, 71 insertions(+), 8 deletions(-) create mode 100644 xCAT-test/unit/networks_ipv6_route_filter.t diff --git a/xCAT-server/lib/xcat/plugins/networks.pm b/xCAT-server/lib/xcat/plugins/networks.pm index 7ada4db2a..29b60ea78 100644 --- a/xCAT-server/lib/xcat/plugins/networks.pm +++ b/xCAT-server/lib/xcat/plugins/networks.pm @@ -132,6 +132,19 @@ sub process_request =cut #----------------------------------------------------------------------------- +sub _ignore_ipv6_route +{ + my $route = shift; + my @ent = split ' ', $route; + + return 1 unless @ent; + return 1 if $ent[0] =~ m/^fe80::/; + return 1 if $ent[0] eq 'unreachable' or $ent[0] eq 'nexthop' or $ent[0] eq 'default'; + return 1 if defined($ent[1]) and $ent[1] eq 'via'; + return 1 if defined($ent[2]) and $ent[2] eq 'lo'; + return 0; +} + sub donets { my $callback = shift; @@ -387,15 +400,8 @@ sub donets #get ipv6 routes and in fact *cannot* dictate router via DHCPv6 at this specific moment. foreach (@ip6table) { + next if _ignore_ipv6_route($_); my @ent = split /\s+/, $_; - if ($ent[0] =~ m/^fe80::/ or $ent[0] eq 'unreachable' or $ent[1] eq 'nexthop' or $ent[0] eq 'default' or - $ent[1] eq 'via' or $ent[2] eq 'lo') { - - #Do not contemplate link-local, unreachable, gatewayed networks, - # or networks connected to loopback interface - #DHCPv6 relay will be manually entered into networks as was the case for IPv4 - next; - } my $net = shift @ent; my $dev = shift @ent; if ($dev eq 'dev') { diff --git a/xCAT-test/autotest/testcase/makenetworks/cases0 b/xCAT-test/autotest/testcase/makenetworks/cases0 index 7a91e86d4..c2de00aa7 100644 --- a/xCAT-test/autotest/testcase/makenetworks/cases0 +++ b/xCAT-test/autotest/testcase/makenetworks/cases0 @@ -22,6 +22,15 @@ check:rc==0 check:output=~Version end +start:makenetworks_ipv6_route_filter_unit +description:Run the makenetworks IPv6 route-filter unit test through xcattest. +os:Linux +label:mn_only,ci_test,network,unit,makenetworks_unit +cmd:prove -I/opt/xcat/lib/perl /opt/xcat/share/xcat/tools/autotest/unit/networks_ipv6_route_filter.t +check:rc==0 +check:output=~All tests successful +end + start:makenetworks_d os:Linux description:makenetworks_d diff --git a/xCAT-test/unit/networks_ipv6_route_filter.t b/xCAT-test/unit/networks_ipv6_route_filter.t new file mode 100644 index 000000000..307cf52e1 --- /dev/null +++ b/xCAT-test/unit/networks_ipv6_route_filter.t @@ -0,0 +1,48 @@ +#!/usr/bin/env perl +use strict; +use warnings; +## no critic (Modules::RequireFilenameMatchesPackage) + +use FindBin; +use Test::More; + +BEGIN { + package xCAT::Table; + $INC{'xCAT/Table.pm'} = __FILE__; + + package xCAT::Utils; + $INC{'xCAT/Utils.pm'} = __FILE__; + + package xCAT::TableUtils; + $INC{'xCAT/TableUtils.pm'} = __FILE__; + + package xCAT::NetworkUtils; + $INC{'xCAT/NetworkUtils.pm'} = __FILE__; + + package xCAT::ServiceNodeUtils; + $INC{'xCAT/ServiceNodeUtils.pm'} = __FILE__; +} + +my $plugin = "$FindBin::Bin/../../xCAT-server/lib/xcat/plugins/networks.pm"; +$plugin = "$ENV{XCATROOT}/lib/perl/xcat/plugins/networks.pm" unless -f $plugin; +require $plugin; + +ok( + !xCAT_plugin::networks::_ignore_ipv6_route('2001:db8:1::/64 dev eth0 proto kernel'), + 'a directly connected global IPv6 network is considered', +); + +my @ignored_routes = ( + [ 'fe80::/128 dev eth0 proto kernel', 'link-local prefix' ], + [ 'unreachable 2001:db8:2::/64 metric 1024', 'unreachable route' ], + [ 'default via 2001:db8::1 dev eth0', 'default route' ], + [ ' nexthop via fe80::1 dev eth0 weight 1', 'multipath nexthop continuation' ], + [ '2001:db8:3::/64 via 2001:db8::1 dev eth0', 'gatewayed route' ], + [ '::1 dev lo proto kernel metric 256', 'loopback route' ], +); + +for my $case (@ignored_routes) { + ok(xCAT_plugin::networks::_ignore_ipv6_route($case->[0]), "$case->[1] is ignored"); +} + +done_testing(); From 3aff408657eb20c36cc5ea8d5c4b48fd802d3534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Ferr=C3=A3o?= <2031761+viniciusferrao@users.noreply.github.com> Date: Fri, 24 Jul 2026 13:35:35 -0300 Subject: [PATCH 4/4] fix(test): load the installed networks plugin --- xCAT-test/unit/networks_ipv6_route_filter.t | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xCAT-test/unit/networks_ipv6_route_filter.t b/xCAT-test/unit/networks_ipv6_route_filter.t index 307cf52e1..739178211 100644 --- a/xCAT-test/unit/networks_ipv6_route_filter.t +++ b/xCAT-test/unit/networks_ipv6_route_filter.t @@ -24,7 +24,7 @@ BEGIN { } my $plugin = "$FindBin::Bin/../../xCAT-server/lib/xcat/plugins/networks.pm"; -$plugin = "$ENV{XCATROOT}/lib/perl/xcat/plugins/networks.pm" unless -f $plugin; +$plugin = "$ENV{XCATROOT}/lib/perl/xCAT_plugin/networks.pm" unless -f $plugin; require $plugin; ok(