Improve zone file parsing. Replace some uses of 'each' with 'values'

git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@5460 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
teastep 2007-03-08 17:20:09 +00:00
parent 7a491c5c9e
commit 023e409ab0

View File

@ -350,35 +350,37 @@ sub parse_zone_option_list($)
my $options = ''; my $options = '';
my $fmt; my $fmt;
for my $e ( split ',' , $list ) { if ( $list ne '-' ) {
my $val = undef; for my $e ( split ',' , $list ) {
my $invert = ''; my $val = undef;
my $invert = '';
if ( $e =~ /([\w-]+)!=(.+)/ ) { if ( $e =~ /([\w-]+)!=(.+)/ ) {
$val = $2; $val = $2;
$e = $1; $e = $1;
$invert = '! '; $invert = '! ';
} elsif ( $e =~ /([\w-]+)=(.+)/ ) { } elsif ( $e =~ /([\w-]+)=(.+)/ ) {
$val = $2; $val = $2;
$e = $1; $e = $1;
} }
$fmt = $validoptions{"$e"}; $fmt = $validoptions{"$e"};
fatal_error "Invalid Option ($e)" unless $fmt; fatal_error "Invalid Option ($e)" unless $fmt;
if ( $fmt eq NOTHING ) { if ( $fmt eq NOTHING ) {
fatal_error "Option $e does not take a value" if defined $val; fatal_error "Option $e does not take a value: Zone \"$line\"" if defined $val;
} else { } else {
fatal_error "Invalid value ($val) for option \"$e\"" unless $val =~ /^($fmt)$/; fatal_error "Invalid value ($val) for option \"$e\" in Zone \"$line\"" unless $val =~ /^($fmt)$/;
} }
if ( $key{$e} ) { if ( $key{$e} ) {
$h{$e} = $val; $h{$e} = $val;
} else { } else {
$options .= $invert; $options .= $invert;
$options .= "--$e "; $options .= "--$e ";
$options .= "$val "if defined $val; $options .= "$val "if defined $val;
}
} }
} }
@ -425,7 +427,8 @@ sub determine_zones()
} }
} }
fatal_error "Invalid zone name: $zone" unless "\L$zone" =~ /^[a-z]\w*$/ and length $zone <= $env{MAXZONENAMELENGTH}; fatal_error "Invalid zone name: $zone" unless "\L$zone" =~ /^[a-z]\w*$/ && length $zone <= $env{MAXZONENAMELENGTH};
fatal_error "Invalid zone name: $zone" if $zone =~ /^all2|2all$/;
$zone_parents{$zone} = \@parents; $zone_parents{$zone} = \@parents;
$zone_exclusions{$zone} = []; $zone_exclusions{$zone} = [];
@ -443,6 +446,8 @@ sub determine_zones()
fatal_error "Only one firewall zone may be defined: $zone" if $firewall_zone; fatal_error "Only one firewall zone may be defined: $zone" if $firewall_zone;
$firewall_zone = $zone; $firewall_zone = $zone;
$zones{"$zone"} = "firewall"; $zones{"$zone"} = "firewall";
} elsif ( $type eq '-' ) {
$type = 'ipv4';
} else { } else {
fatal_error "Invalid zone type ($type)" ; fatal_error "Invalid zone type ($type)" ;
} }
@ -454,7 +459,9 @@ sub determine_zones()
$zone_hash{out} = parse_zone_option_list( $out_options || ''); $zone_hash{out} = parse_zone_option_list( $out_options || '');
$zone_hash{complex} = ($type eq 'ipsec4' || $options || $in_options || $out_options ? 1 : 0); $zone_hash{complex} = ($type eq 'ipsec4' || $options || $in_options || $out_options ? 1 : 0);
$zone_options{"$zone"} = \%zone_hash; $zone_options{$zone} = \%zone_hash;
$zone_interfaces{$zone} = {};
push @z, $zone; push @z, $zone;
} }
@ -4671,7 +4678,7 @@ sub activate_rules() {
# #
# Take care of PREROUTING, INPUT and OUTPUT jumps # Take care of PREROUTING, INPUT and OUTPUT jumps
# #
while ( my ( $grouptype, $typeref ) = each %$source_hosts_ref ) { for my $typeref ( values %$source_hosts_ref ) {
while ( my ( $interface, $arrayref ) = each %$typeref ) { while ( my ( $interface, $arrayref ) = each %$typeref ) {
for my $hostref ( @$arrayref ) { for my $hostref ( @$arrayref ) {
my $ipsec_in_match = match_ipsec_in $zone , $hostref; my $ipsec_in_match = match_ipsec_in $zone , $hostref;
@ -4715,23 +4722,25 @@ sub activate_rules() {
if ( $config{OPTIMIZE} > 0 ) { if ( $config{OPTIMIZE} > 0 ) {
my @temp_zones; my @temp_zones;
ZONE1:
for my $zone1 ( grep $zones{$_} ne 'firewall' , @zones ) { for my $zone1 ( grep $zones{$_} ne 'firewall' , @zones ) {
my $policy = ( get_chainref 'filter' , "${zone}2${zone1}" )->{policy}; my $policy = ( get_chainref 'filter' , "${zone}2${zone1}" )->{policy};
next if $policy eq 'NONE'; next if $policy eq 'NONE';
my $chain = rules_chain $zone, $zone1; my $chain = rules_chain $zone, $zone1;
next unless $chain; next unless $chain;
if ( $zone eq $zone1 ) { if ( $zone eq $zone1 )
my $routeback = $zone_options{$zone}{routeback}; {
my @a = keys %{ $zone_interfaces{$zone} || {} }; #
my $interfaces = @a ; # One thing that the Llamma doesn't tell you is that evaluating a hash in a numeric context produces a warning.
#
next if $interfaces < 2 && ! ( $routeback || @$exclusions ); no warnings;
next if ( %{ $zone_interfaces{$zone}} < 2 ) && ! ( $zone_options{$zone}{routeback} || @$exclusions );
} }
$chain = rules_chain $zone, $zone1;
if ( $chain =~ /2all$/ ) { if ( $chain =~ /2all$/ ) {
if ( $chain ne $last_chain ) { if ( $chain ne $last_chain ) {
$last_chain = $chain; $last_chain = $chain;
@ -4763,6 +4772,7 @@ sub activate_rules() {
# We now loop through the destination zones creating jumps to the rules chain for each source/dest combination. # We now loop through the destination zones creating jumps to the rules chain for each source/dest combination.
# $dest_zones is the list of destination zones that we need to handle from this source zone # $dest_zones is the list of destination zones that we need to handle from this source zone
# #
ZONE1:
for my $zone1 ( @dest_zones ) { for my $zone1 ( @dest_zones ) {
my $policy = ( get_chainref 'filter' , "${zone}2${zone1}" )->{policy}; my $policy = ( get_chainref 'filter' , "${zone}2${zone1}" )->{policy};
next if $policy eq 'NONE'; next if $policy eq 'NONE';
@ -4774,10 +4784,11 @@ sub activate_rules() {
my $num_ifaces = 0; my $num_ifaces = 0;
if ( $zone eq $zone1 ) { if ( $zone eq $zone1 ) {
$routeback = $zone_options{$zone}{routeback}; #
my @a = keys %{$zone_interfaces{$zone}}; # One thing that the Llamma doesn't tell you is that evaluating a hash in a numeric context produces a warning.
$num_ifaces = @a; #
next if $num_ifaces < 2 && ! ( $routeback || @$exclusions ); no warnings;
next ZONE1 if ( $num_ifaces = %{$zone_interfaces{$zone}} ) < 2 && ! ( $zone_options{$zone}{routeback} || @$exclusions );
} }
my $chainref = get_chainref 'filter', $chain; my $chainref = get_chainref 'filter', $chain;
@ -4810,7 +4821,7 @@ sub activate_rules() {
} }
if ( $complex ) { if ( $complex ) {
while ( my ( $grouptype, $typeref ) = each %$dest_hosts_ref ) { for my $typeref ( values %$dest_hosts_ref ) {
while ( my ( $interface , $arrayref ) = each %$typeref ) { while ( my ( $interface , $arrayref ) = each %$typeref ) {
for my $hostref ( @$arrayref ) { for my $hostref ( @$arrayref ) {
if ( $zone ne $zone1 || $num_ifaces > 1 || $hostref->{options}{routeback} ) { if ( $zone ne $zone1 || $num_ifaces > 1 || $hostref->{options}{routeback} ) {
@ -4823,13 +4834,13 @@ sub activate_rules() {
} }
} }
} else { } else {
while ( my ( $grouptype, $typeref ) = each %$source_hosts_ref ) { for my $typeref ( values %$source_hosts_ref ) {
while ( my ( $interface , $arrayref ) = each %$typeref ) { while ( my ( $interface , $arrayref ) = each %$typeref ) {
my $chain3ref = get_chainref 'filter' , forward_chain $interface; my $chain3ref = get_chainref 'filter' , forward_chain $interface;
for my $hostref ( @$arrayref ) { for my $hostref ( @$arrayref ) {
for my $net ( @{$hostref->{hosts}} ) { for my $net ( @{$hostref->{hosts}} ) {
my $source_match = match_source_net $net; my $source_match = match_source_net $net;
while ( my ( $group1type , $type1ref ) = each %$dest_hosts_ref ) { for my $type1ref ( values %$dest_hosts_ref ) {
while ( my ( $interface1, $array1ref ) = each %$type1ref ) { while ( my ( $interface1, $array1ref ) = each %$type1ref ) {
for my $host1ref ( @$array1ref ) { for my $host1ref ( @$array1ref ) {
my $ipsec_out_match = match_ipsec_out $zone1 , $host1ref; my $ipsec_out_match = match_ipsec_out $zone1 , $host1ref;
@ -4855,7 +4866,7 @@ sub activate_rules() {
if ( $complex ) { if ( $complex ) {
add_rule $frwd_ref , "-j $last_chain"; add_rule $frwd_ref , "-j $last_chain";
} else { } else {
while ( my ( $grouptype , $typeref ) = each %$source_hosts_ref ) { for my $typeref ( values %$source_hosts_ref ) {
while ( my ( $interface , $arrayref ) = each %$typeref ) { while ( my ( $interface , $arrayref ) = each %$typeref ) {
my $chain2ref = get_chainref 'filter' , forward_chain $interface; my $chain2ref = get_chainref 'filter' , forward_chain $interface;
for my $hostref ( @$arrayref ) { for my $hostref ( @$arrayref ) {