Make zone type numeric for faster comparison

Signed-off-by: Tom Eastep <teastep@shorewall.net>

git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@9684 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
teastep 2009-03-13 22:59:49 +00:00
parent e75789d894
commit 229e573c3c
4 changed files with 64 additions and 54 deletions

View File

@ -265,11 +265,11 @@ sub validate_policy()
fatal_error "NONE policy not allowed with \"all\""
if $clientwild || $serverwild;
fatal_error "NONE policy not allowed to/from firewall zone"
if ( zone_type( $client ) eq 'firewall' ) || ( zone_type( $server ) eq 'firewall' );
if ( zone_type( $client ) == FIREWALL ) || ( zone_type( $server ) == FIREWALL );
}
unless ( $clientwild || $serverwild ) {
if ( zone_type( $server ) eq 'bport' ) {
if ( zone_type( $server ) == BPORT ) {
fatal_error "Invalid policy - DEST zone is a Bridge Port zone but the SOURCE zone is not associated with the same bridge"
unless find_zone( $client )->{bridge} eq find_zone( $server)->{bridge} || single_interface( $client ) eq find_zone( $server )->{bridge};
}

View File

@ -1201,7 +1201,7 @@ sub process_rule1 ( $$$$$$$$$$$$$ ) {
#
# Check for illegal bridge port rule
#
if ( $destref->{type} eq 'bport' ) {
if ( $destref->{type} == BPORT ) {
unless ( $sourceref->{bridge} eq $destref->{bridge} || single_interface( $sourcezone ) eq $destref->{bridge} ) {
return 1 if $wildcard;
fatal_error "Rules with a DESTINATION Bridge Port zone must have a SOURCE zone on the same bridge";
@ -1356,7 +1356,7 @@ sub process_rule1 ( $$$$$$$$$$$$$ ) {
#
# And generate the nat table rule(s)
#
expand_rule ( ensure_chain ('nat' , $sourceref->{type} eq 'firewall' ? 'OUTPUT' : dnat_chain $sourcezone ),
expand_rule ( ensure_chain ('nat' , $sourceref->{type} == FIREWALL ? 'OUTPUT' : dnat_chain $sourcezone ),
PREROUTE_RESTRICT ,
$rule ,
$source ,
@ -1394,7 +1394,7 @@ sub process_rule1 ( $$$$$$$$$$$$$ ) {
$origdest = $interfaces ? "detect:$interfaces" : ALLIP;
}
expand_rule( ensure_chain ('nat' , $sourceref->{type} eq 'firewall' ? 'OUTPUT' : dnat_chain $sourcezone) ,
expand_rule( ensure_chain ('nat' , $sourceref->{type} == 'FIREWALL' ? 'OUTPUT' : dnat_chain $sourcezone) ,
PREROUTE_RESTRICT ,
$rule ,
$source ,
@ -1500,10 +1500,10 @@ sub process_rule ( $$$$$$$$$$$$ ) {
if ( $source eq 'all' ) {
for my $zone ( all_zones ) {
if ( $includesrcfw || ( zone_type( $zone ) ne 'firewall' ) ) {
if ( $includesrcfw || ( zone_type( $zone ) != FIREWALL ) ) {
if ( $dest eq 'all' ) {
for my $zone1 ( all_zones ) {
if ( $includedstfw || ( zone_type( $zone1 ) ne 'firewall' ) ) {
if ( $includedstfw || ( zone_type( $zone1 ) != FIREWALL ) ) {
if ( $intrazone || ( $zone ne $zone1 ) ) {
process_rule1 $target, $zone, $zone1 , $proto, $ports, $sports, $origdest, $ratelimit, $user, $mark, $connlimit, $time, 1;
}
@ -1521,7 +1521,7 @@ sub process_rule ( $$$$$$$$$$$$ ) {
} elsif ( $dest eq 'all' ) {
for my $zone ( all_zones ) {
my $sourcezone = ( split( /:/, $source, 2 ) )[0];
if ( ( $includedstfw || ( zone_type( $zone ) ne 'firewall') ) && ( ( $sourcezone ne $zone ) || $intrazone) ) {
if ( ( $includedstfw || ( zone_type( $zone ) != FIREWALL ) ) && ( ( $sourcezone ne $zone ) || $intrazone) ) {
process_rule1 $target, $source, $zone , $proto, $ports, $sports, $origdest, $ratelimit, $user, $mark, $connlimit, $time, 1;
}
}
@ -1901,7 +1901,7 @@ sub generate_matrix() {
next if ( scalar ( keys( %{ $zoneref->{interfaces}} ) ) < 2 ) && ! $zoneref->{options}{in_out}{routeback};
}
if ( $zone1ref->{type} eq 'bport' ) {
if ( $zone1ref->{type} == BPORT ) {
next unless $zoneref->{bridge} eq $zone1ref->{bridge};
}
@ -1953,7 +1953,7 @@ sub generate_matrix() {
next ZONE1 if ( $num_ifaces = scalar( keys ( %{$zoneref->{interfaces}} ) ) ) < 2 && ! $zoneref->{options}{in_out}{routeback};
}
if ( $zone1ref->{type} eq 'bport' ) {
if ( $zone1ref->{type} == BPORT ) {
next ZONE1 unless $zoneref->{bridge} eq $zone1ref->{bridge};
}

View File

@ -82,7 +82,7 @@ sub setup_tunnels() {
unless ( $gatewayzones eq '-' ) {
for my $zone ( split_list $gatewayzones, 'zone' ) {
my $type = zone_type( $zone );
fatal_error "Invalid zone ($zone) for GATEWAY ZONE" if $type eq 'firewall' || $type eq 'bport';
fatal_error "Invalid zone ($zone) for GATEWAY ZONE" if $type == FIREWALL || $type == BPORT;
$inchainref = ensure_filter_chain "${zone}2${fw}", 1;
$outchainref = ensure_filter_chain "${fw}2${zone}", 1;
@ -237,7 +237,7 @@ sub setup_tunnels() {
my $zonetype = zone_type( $zone );
fatal_error "Invalid tunnel ZONE ($zone)" if $zonetype eq 'firewall' || $zonetype eq 'bport';
fatal_error "Invalid tunnel ZONE ($zone)" if $zonetype == FIREWALL || $zonetype == BPORT;
my $inchainref = ensure_filter_chain "${zone}2${fw}", 1;
my $outchainref = ensure_filter_chain "${fw}2${zone}", 1;

View File

@ -36,6 +36,10 @@ our @EXPORT = qw( NOTHING
NETWORK
IPSECPROTO
IPSECMODE
FIREWALL
IP
BPORT
IPSEC
determine_zones
zone_report
@ -85,7 +89,7 @@ use constant { NOTHING => 'NOTHING',
#
# @zones contains the ordered list of zones with sub-zones appearing before their parents.
#
# %zones{<zone1> => {type = > <zone type> 'firewall', 'ip', 'ipsec', 'bport';
# %zones{<zone1> => {type = > <zone type> FIREWALL, IP, IPSEC, BPORT;
# options => { complex => 0|1
# nested => 0|1
# in_out => < policy match string >
@ -145,13 +149,19 @@ our @bport_zones;
our %ipsets;
our $family;
use constant { FIREWALL => 1,
IP => 2,
BPORT => 3,
IPSEC => 4 };
#
# Initialize globals -- we take this novel approach to globals initialization to allow
# the compiler to run multiple times in the same process. The
# initialize() function does globals initialization for this
# module and is called from an INIT block below. The function is
# also called by Shorewall::Compiler::compiler at the beginning of
# the second and subsequent calls to that function.
# the second and subsequent calls to that function or when compiling
# for IPv6.
#
sub initialize( $ ) {
@ -226,7 +236,7 @@ sub parse_zone_option_list($$)
if ( $key{$e} ) {
$h{$e} = $val;
} else {
fatal_error "The \"$e\" option may only be specified for ipsec zones" unless $zonetype eq 'ipsec';
fatal_error "The \"$e\" option may only be specified for ipsec zones" unless $zonetype == IPSEC;
$options .= $invert;
$options .= "--$e ";
$options .= "$val "if defined $val;
@ -265,7 +275,7 @@ sub determine_zones()
for my $p ( @parents ) {
fatal_error "Invalid Parent List ($2)" unless $p;
fatal_error "Unknown parent zone ($p)" unless $zones{$p};
fatal_error 'Subzones of firewall zone not allowed' if $zones{$p}{type} eq 'firewall';
fatal_error 'Subzones of firewall zone not allowed' if $zones{$p}{type} == FIREWALL;
push @{$zones{$p}{children}}, $zone;
}
}
@ -274,32 +284,32 @@ sub determine_zones()
fatal_error "Invalid zone name ($zone)" if $reservedName{$zone} || $zone =~ /^all2|2all$/;
fatal_error( "Duplicate zone name ($zone)" ) if $zones{$zone};
$type = "ip" unless $type;
$type = IP unless $type;
if ( $type =~ /ipv4/i ) {
fatal_error "Invalid zone type ($type)" if $family == F_IPV6;
$type = 'ip';
$type = IP;
$ip = 1;
} elsif ( $type =~ /ipv6/i ) {
fatal_error "Invalid zone type ($type)" if $family == F_IPV4;
$type = 'ip';
$type = IP;
$ip = 1;
} elsif ( $type =~ /^ipsec([46])?$/i ) {
fatal_error "Invalid zone type ($type)" if $1 && (($1 == 4 && $family == F_IPV6 ) || ( $1 == 6 && $family == F_IPV4 ));
$type = 'ipsec';
$type = IPSEC;
} elsif ( $type =~ /^bport([46])?$/i ) {
fatal_error "Invalid zone type ($type)" if $1 && (( $1 == 4 && $family == F_IPV6 ) || ( $1 == 6 && $family == F_IPV4 ));
warning_message "Bridge Port zones should have a parent zone" unless @parents;
$type = 'bport';
$type = BPORT;
push @bport_zones, $zone;
} elsif ( $type eq 'firewall' ) {
fatal_error 'Firewall zone may not be nested' if @parents;
fatal_error "Only one firewall zone may be defined ($zone)" if $firewall_zone;
$firewall_zone = $zone;
$ENV{FW} = $zone;
$type = "firewall";
$type = FIREWALL;
} elsif ( $type eq '-' ) {
$type = 'ip';
$type = IP;
$ip = 1;
} else {
fatal_error "Invalid zone type ($type)" ;
@ -315,7 +325,7 @@ sub determine_zones()
options => { in_out => parse_zone_option_list( $options || '', $type ) ,
in => parse_zone_option_list( $in_options || '', $type ) ,
out => parse_zone_option_list( $out_options || '', $type ) ,
complex => ($type eq 'ipsec' || $options || $in_options || $out_options ? 1 : 0) ,
complex => ($type == IPSEC || $options || $in_options || $out_options ? 1 : 0) ,
nested => @parents > 0 } ,
interfaces => {} ,
children => [] ,
@ -353,7 +363,7 @@ sub determine_zones()
#
sub haveipseczones() {
for my $zoneref ( values %zones ) {
return 1 if $zoneref->{type} eq 'ipsec';
return 1 if $zoneref->{type} == IPSEC;
}
0;
@ -366,7 +376,13 @@ sub zone_report()
{
progress_message2 "Determining Hosts in Zones...";
my $ipzone = $family == F_IPV4 ? 'ipv4' : 'ipv6';
my @translate;
if ( $family == F_IPV4 ) {
@translate = ( undef, 'firewall', 'ipv4', 'bport4', 'ipsec4' );
} else {
@translate = ( undef, 'firewall', 'ipv6', 'bport6', 'ipsec6' );
}
for my $zone ( @zones )
{
@ -375,9 +391,7 @@ sub zone_report()
my $type = $zoneref->{type};
my $optionref = $zoneref->{options};
$type = $ipzone if $type eq 'ip';
progress_message_nocompress " $zone ($type)";
progress_message_nocompress " $zone ($translate[$type])";
my $printed = 0;
@ -407,8 +421,8 @@ sub zone_report()
}
unless ( $printed ) {
fatal_error "No bridge has been associated with zone $zone" if $type eq 'bport' && ! $zoneref->{bridge};
warning_message "*** $zone is an EMPTY ZONE ***" unless $type eq 'firewall';
fatal_error "No bridge has been associated with zone $zone" if $type == BPORT && ! $zoneref->{bridge};
warning_message "*** $zone is an EMPTY ZONE ***" unless $type == FIREWALL;
}
}
@ -416,16 +430,12 @@ sub zone_report()
sub dump_zone_contents()
{
my %xlate;
my @xlate;
if ( $family == F_IPV4 ) {
%xlate = ( ip => 'ipv4' ,
bport => 'bport4' ,
ipsec => 'ipsec4' )
} else {
%xlate = ( ip => 'ipv6' ,
bport => 'bport6' ,
ipsec => 'ipsec6' )
@xlate = ( undef, 'firewall', 'ipv4', 'bport4', 'ipsec4' );
} else {
@xlate = ( undef, 'firewall', 'ipv6', 'bport6', 'ipsec6' );
}
for my $zone ( @zones )
@ -435,11 +445,9 @@ sub dump_zone_contents()
my $type = $zoneref->{type};
my $optionref = $zoneref->{options};
$type = $xlate{$type} if $xlate{$type};
my $entry = "$zone $xlate[$type]";
my $entry = "$zone $type";
$entry .= ":$zoneref->{bridge}" if $type =~ /^bport/;
$entry .= ":$zoneref->{bridge}" if $type == BPORT;
if ( $hostref ) {
for my $type ( sort keys %$hostref ) {
@ -517,7 +525,7 @@ sub add_group_to_zone($$$$$)
}
unless ( $switched ) {
if ( $type eq $zonetype ) {
if ( $type == $zonetype ) {
fatal_error "Duplicate Host Group ($interface:$host) in zone $zone" if $ifacezone eq $zone;
$ifacezone = $zone if $host eq ALLIP;
}
@ -535,15 +543,17 @@ sub add_group_to_zone($$$$$)
$zoneref->{options}{in_out}{routeback} = 1 if $options->{routeback};
my $gtype = $type == IPSEC ? 'ipsec' : 'ip';
$hostsref = ( $zoneref->{hosts} || ( $zoneref->{hosts} = {} ) );
$typeref = ( $hostsref->{$type} || ( $hostsref->{$type} = {} ) );
$typeref = ( $hostsref->{$gtype} || ( $hostsref->{$gtype} = {} ) );
$interfaceref = ( $typeref->{$interface} || ( $typeref->{$interface} = [] ) );
$zoneref->{options}{complex} = 1 if @$interfaceref || ( @newnetworks > 1 ) || ( @exclusions );
push @{$interfaceref}, { options => $options,
hosts => \@newnetworks,
ipsec => $type eq 'ipsec' ? 'ipsec' : 'none' ,
ipsec => $type == IPSEC ? 'ipsec' : 'none' ,
exclusions => \@exclusions };
}
@ -578,7 +588,7 @@ sub all_zones() {
}
sub non_firewall_zones() {
grep ( $zones{$_}{type} ne 'firewall' , @zones );
grep ( $zones{$_}{type} != FIREWALL , @zones );
}
sub complex_zones() {
@ -675,7 +685,7 @@ sub validate_interfaces_file( $ )
$zoneref = $zones{$zone};
fatal_error "Unknown zone ($zone)" unless $zoneref;
fatal_error "Firewall zone not allowed in ZONE column of interface record" if $zoneref->{type} eq 'firewall';
fatal_error "Firewall zone not allowed in ZONE column of interface record" if $zoneref->{type} == FIREWALL;
}
$networks = '' if $networks eq '-';
@ -691,7 +701,7 @@ sub validate_interfaces_file( $ )
fatal_error "Your iptables is not recent enough to support bridge ports" unless $capabilities{KLUDGEFREE};
fatal_error "Duplicate Interface ($port)" if $interfaces{$port};
fatal_error "$interface is not a defined bridge" unless $interfaces{$interface} && $interfaces{$interface}{options}{bridge};
fatal_error "Bridge Ports may only be associated with 'bport' zones" if $zone && $zoneref->{type} ne 'bport';
fatal_error "Bridge Ports may only be associated with 'bport' zones" if $zone && $zoneref->{type} != BPORT;
if ( $zone ) {
if ( $zoneref->{bridge} ) {
@ -709,7 +719,7 @@ sub validate_interfaces_file( $ )
$interface = $port;
} else {
fatal_error "Duplicate Interface ($interface)" if $interfaces{$interface};
fatal_error "Zones of type 'bport' may only be associated with bridge ports" if $zone && $zoneref->{type} eq 'bport';
fatal_error "Zones of type 'bport' may only be associated with bridge ports" if $zone && $zoneref->{type} == BPORT;
$bridge = $interface;
}
@ -1054,7 +1064,7 @@ sub validate_hosts_file()
my $type = $zoneref->{type};
fatal_error "Unknown ZONE ($zone)" unless $type;
fatal_error 'Firewall zone not allowed in ZONE column of hosts record' if $type eq 'firewall';
fatal_error 'Firewall zone not allowed in ZONE column of hosts record' if $type == FIREWALL;
my $interface;
@ -1078,7 +1088,7 @@ sub validate_hosts_file()
}
}
if ( $type eq 'bport' ) {
if ( $type == BPORT ) {
if ( $zoneref->{bridge} eq '' ) {
fatal_error 'Bridge Port Zones may only be associated with bridge ports' unless $interfaces{$interface}{options}{port};
$zoneref->{bridge} = $interfaces{$interface}{bridge};
@ -1096,7 +1106,7 @@ sub validate_hosts_file()
for my $option ( @options )
{
if ( $option eq 'ipsec' ) {
$type = 'ipsec';
$type = IPSEC;
$zoneref->{options}{complex} = 1;
$ipsec = 1;
} elsif ( $validoptions{$option}) {
@ -1148,7 +1158,7 @@ sub find_hosts_by_option( $ ) {
my $option = $_[0];
my @hosts;
for my $zone ( grep $zones{$_}{type} ne 'firewall' , @zones ) {
for my $zone ( grep $zones{$_}{type} != FIREWALL , @zones ) {
while ( my ($type, $interfaceref) = each %{$zones{$zone}{hosts}} ) {
while ( my ( $interface, $arrayref) = ( each %{$interfaceref} ) ) {
for my $host ( @{$arrayref} ) {