From 014ec1af1d6decfc5e0f022eb3de0b384117ed75 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Sun, 12 Jul 2015 10:54:48 -0700 Subject: [PATCH] First phase of producing consistent scripts with Perl >= 5.18.0 Beginning with Perl 5.18.0, the order of elements returned by the 'keys' and 'each' iterators is no longer deterministic. This is the first wave of Shorewall changes to compensate for this irrational behavior. Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Chains.pm | 20 +++++++++++++------- Shorewall/Perl/Shorewall/Misc.pm | 2 +- Shorewall/Perl/Shorewall/Providers.pm | 11 +++++++---- Shorewall/Perl/Shorewall/Zones.pm | 10 +++++++--- 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index abe0a6a6f..e8aa6de7d 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -6816,22 +6816,28 @@ sub set_global_variables( $$ ) { my ( $setall, $conditional ) = @_; if ( $conditional ) { - my ( $interface, $code ); + my ( $interface, @interfaces ); - while ( ( $interface, $code ) = each %interfaceaddr ) { - emit( qq([ -z "\$interface" -o "\$interface" = "$interface" ] && $code) ); + @interfaces = sort keys %interfaceaddr; + + for $interface ( @interfaces ) { + emit( qq([ -z "\$interface" -o "\$interface" = "$interface" ] && $interfaceaddr{$interface}) ); } - while ( ( $interface, $code ) = each %interfacegateways ) { + @interfaces = sort keys %interfacegateways; + + for $interface ( @interfaces ) { emit( qq(if [ -z "\$interface" -o "\$interface" = "$interface" ]; then) ); push_indent; - emit( $code ); + emit( $interfacegateways{$interface} ); pop_indent; emit( qq(fi\n) ); } - while ( ( $interface, $code ) = each %interfacemacs ) { - emit( qq([ -z "\$interface" -o "\$interface" = "$interface" ] && $code) ); + @interfaces = sort keys %interfacemacs; + + for $interface ( @interfaces ) { + emit( qq([ -z "\$interface" -o "\$interface" = "$interface" ] && $interfacemacs{$interface}) ); } } else { emit $_ for values %interfaceaddr; diff --git a/Shorewall/Perl/Shorewall/Misc.pm b/Shorewall/Perl/Shorewall/Misc.pm index 93f790bc1..330eda0bd 100644 --- a/Shorewall/Perl/Shorewall/Misc.pm +++ b/Shorewall/Perl/Shorewall/Misc.pm @@ -1579,7 +1579,7 @@ sub add_interface_jumps { our %input_jump_added; our %output_jump_added; our %forward_jump_added; - my @interfaces = grep $_ ne '%vserver%', @_; + my @interfaces = sort grep $_ ne '%vserver%', @_; my $dummy; my $lo_jump_added = interface_zone( loopback_interface ) && ! get_interface_option( loopback_interface, 'destonly' ); # diff --git a/Shorewall/Perl/Shorewall/Providers.pm b/Shorewall/Perl/Shorewall/Providers.pm index 32f771e6f..e50ac99a5 100644 --- a/Shorewall/Perl/Shorewall/Providers.pm +++ b/Shorewall/Perl/Shorewall/Providers.pm @@ -374,7 +374,7 @@ sub start_provider( $$$$$ ) { emit "\n#\n# Add $what $table ($number)\n#"; - if ( $number ) { + if ( $number >= 0 ) { emit "start_provider_$table() {"; } else { emit "start_interface_$table() {"; @@ -384,7 +384,7 @@ sub start_provider( $$$$$ ) { emit $test; push_indent; - if ( $number ) { + if ( $number >= 0 ) { emit "qt ip -$family route flush table $id"; emit "echo \"\$IP -$family route flush table $id > /dev/null 2>&1\" > \${VARDIR}/undo_${table}_routing"; } else { @@ -1442,10 +1442,13 @@ sub process_providers( $ ) { # # Treat optional interfaces as pseudo-providers # + my $num = -65536; + for ( grep interface_is_optional( $_ ) && ! $provider_interfaces{ $_ }, all_real_interfaces ) { + $num++; # - # TABLE NUMBER MARK DUPLICATE INTERFACE GATEWAY OPTIONS COPY - $currentline = var_base($_) ." 0 - - $_ - - -"; + # TABLE NUMBER MARK DUPLICATE INTERFACE GATEWAY OPTIONS COPY + $currentline = var_base($_) . " $num - - $_ - - -"; # $pseudoproviders += process_a_provider(1); } diff --git a/Shorewall/Perl/Shorewall/Zones.pm b/Shorewall/Perl/Shorewall/Zones.pm index db15a4458..6521ca16c 100644 --- a/Shorewall/Perl/Shorewall/Zones.pm +++ b/Shorewall/Perl/Shorewall/Zones.pm @@ -2170,8 +2170,10 @@ sub find_hosts_by_option( $ ) { } for my $zone ( grep ! ( $zones{$_}{type} & FIREWALL ) , @zones ) { - while ( my ($type, $interfaceref) = each %{$zones{$zone}{hosts}} ) { - while ( my ( $interface, $arrayref) = ( each %{$interfaceref} ) ) { + for my $type (keys %{$zones{$zone}{hosts}} ) { + my $interfaceref = $zones{$zone}{hosts}->{$type}; + for my $interface ( keys %$interfaceref ) { + my $arrayref = $interfaceref->{$interface}; for my $host ( @{$arrayref} ) { my $ipsec = $host->{ipsec}; unless ( $done{$interface} ) { @@ -2210,7 +2212,9 @@ sub find_zone_hosts_by_option( $$ ) { } } - \@hosts; + my @sorted = sort { $a->[0] cmp $b->[0] } @hosts; + + \@sorted } #