]> git.proxmox.com Git - pve-common.git/commitdiff
net: add get reachable networks: fix sorter closure
authorThomas Lamprecht <t.lamprecht@proxmox.com>
Fri, 17 Sep 2021 15:47:14 +0000 (17:47 +0200)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Fri, 17 Sep 2021 16:38:47 +0000 (18:38 +0200)
argh, perl sorters and nested greps are weird!

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
src/PVE/CLIHandler.pm
src/PVE/Network.pm

index 9955d77e06395c85dd219dac7d9f322bc1824992..64c3f95d120a5d97e9ff24b620098b360323df09 100644 (file)
@@ -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}};
index e44648bb56e48bae40386039200f4e66f9949e7f..948e059d1eb905d0921357a3c994b8768402edb2 100644 (file)
@@ -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;