From 4e4059580aea0d2e58f7f0ca1f790b30ba184e16 Mon Sep 17 00:00:00 2001 From: Thomas Lamprecht Date: Fri, 17 Sep 2021 17:47:14 +0200 Subject: [PATCH] net: add get reachable networks: fix sorter closure argh, perl sorters and nested greps are weird! Signed-off-by: Thomas Lamprecht --- src/PVE/CLIHandler.pm | 2 +- src/PVE/Network.pm | 31 ++++++++++++------------------- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/src/PVE/CLIHandler.pm b/src/PVE/CLIHandler.pm index 9955d77..64c3f95 100644 --- a/src/PVE/CLIHandler.pm +++ b/src/PVE/CLIHandler.pm @@ -208,7 +208,7 @@ sub generate_usage_str { my $str = ''; if (ref($def) eq 'HASH') { my $oldclass = undef; - foreach my $cmd (&$sortfunc($def)) { + foreach my $cmd ($sortfunc->($def)) { if (ref($def->{$cmd}) eq 'ARRAY') { my ($class, $name, $arg_param, $fixed_param, undef, $formatter_properties) = @{$def->{$cmd}}; diff --git a/src/PVE/Network.pm b/src/PVE/Network.pm index e44648b..948e059 100644 --- a/src/PVE/Network.pm +++ b/src/PVE/Network.pm @@ -607,27 +607,20 @@ sub is_ip_in_cidr { sub get_reachable_networks { my $raw = ''; run_command([qw(ip -j addr show up scope global)], outfunc => sub { $raw .= shift }); - my $addrs = decode_json($raw); - - # sort by family (IPv4/IPv6) and then by addr, just for some stability - my $addrs_sorter = sub { - my ($a, $b) = @_; - my $family = $a->{family} cmp $b->{family}; - return $family if $family != 0; - return $a->{local} cmp $b->{local}; - }; + my $decoded = decode_json($raw); + my $addrs = []; # filter/transform first so that we can sort correctly more easily below + for my $e ($decoded->@*) { + next if !$e->{addr_info} || grep { $_ eq 'LOOPBACK' } $e->{flags}->@*; + push $addrs->@*, grep { scalar(keys $_->%*) } $e->{addr_info}->@* + } my $res = []; - for my $addr ($addrs->@*) { - next if !exists $addr->{addr_info}; - next if grep { $_ eq 'LOOPBACK' } $addr->{flags}->@*; - for my $info (sort $addrs_sorter grep { $_ && $_->{local}} $addr->{addr_info}->@*) { - push $res->@*, { - addr => $info->{local}, - cidr => "$info->{local}/$info->{prefixlen}", - family => $info->{family}, - }; - } + for my $info (sort { $a->{family} cmp $b->{family} || $a->{local} cmp $b->{local} } $addrs->@*) { + push $res->@*, { + addr => $info->{local}, + cidr => "$info->{local}/$info->{prefixlen}", + family => $info->{family}, + }; } return $res;