Keep rule arrays compressed during optimization

Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
Tom Eastep 2010-04-08 11:35:15 -07:00
parent 9126cc63d9
commit 3937c10251
3 changed files with 67 additions and 46 deletions

View File

@ -116,6 +116,7 @@ our %EXPORT_TAGS = (
new_nat_chain new_nat_chain
ensure_filter_chain ensure_filter_chain
finish_section finish_section
prepare_for_optimization
optimize_chain optimize_chain
check_optimization check_optimization
optimize_ruleset optimize_ruleset
@ -1364,6 +1365,36 @@ sub finish_section ( $ ) {
} }
} }
#
# Compress out undefined elements in rules
#
sub compress_rules( $ ) {
my $chainref = shift;
my @rules;
for ( @{$chainref->{rules}} ) {
push @rules, $_ if defined;
}
$chainref->{rules} = \@rules;
}
#
# Prepare chain table for optimization by squeezing out undefined rules array entries
#
sub prepare_for_optimization() {
for my $table ( qw/raw mangle nat filter/ ) {
next if $family == F_IPV6 && $table eq 'nat';
for my $chainref ( grep $_->{referenced}, values %{$chain_table{$table}} ) {
for ( @{$chainref->{rules}} ) {
compress_rules( $chainref ), last unless defined;
}
}
}
}
# #
# Delete redundant ACCEPT rules from the end of a policy chain whose policy is ACCEPT # Delete redundant ACCEPT rules from the end of a policy chain whose policy is ACCEPT
# #
@ -1391,7 +1422,7 @@ sub optimize_chain( $ ) {
my $rule = 0; my $rule = 0;
for ( @{$fromref->{rules}} ) { for ( @{$fromref->{rules}} ) {
$rule++; $rule++;
if ( defined && s/ -[jg] $chainref->{name}$/ -j ACCEPT/ ) { if ( s/ -[jg] $chainref->{name}$/ -j ACCEPT/ ) {
$count++; $count++;
trace( $chainref, 'R', $rule, $_ ) if $debug; trace( $chainref, 'R', $rule, $_ ) if $debug;
} }
@ -1417,15 +1448,20 @@ sub delete_references( $ ) {
for my $fromref ( map $chain_table{$table}{$_} , keys %{$chainref->{references}} ) { for my $fromref ( map $chain_table{$table}{$_} , keys %{$chainref->{references}} ) {
my $rule = 0; my $rule = 0;
my $deleted = 0;
for ( @{$fromref->{rules}} ) { for ( @{$fromref->{rules}} ) {
$rule++; $rule++;
if ( defined && / -[jg] $chainref->{name}$/ ) { if ( / -[jg] $chainref->{name}$/ ) {
trace( $fromref, 'D', $rule, $_ ) if $debug; trace( $fromref, 'D', $rule, $_ ) if $debug;
$_ = undef; $_ = undef;
$count++; $count++;
$deleted = 1;
} }
} }
compress_rules( $fromref ) if $deleted;
} }
if ( $count ) { if ( $count ) {
@ -1457,7 +1493,7 @@ sub replace_references( $$ ) {
my $rule = 0; my $rule = 0;
for ( @{$fromref->{rules}} ) { for ( @{$fromref->{rules}} ) {
$rule++; $rule++;
if ( defined && s/ -([jg]) $chainref->{name}(\b)/ -$1 ${target}$2/ ) { if ( s/ -([jg]) $chainref->{name}(\b)/ -$1 ${target}$2/ ) {
add_reference ( $fromref, $chain_table{$table}{$target} ); add_reference ( $fromref, $chain_table{$table}{$target} );
$count++; $count++;
trace( $fromref, 'R', $rule, $_ ) if $debug; trace( $fromref, 'R', $rule, $_ ) if $debug;
@ -1474,7 +1510,7 @@ sub replace_references( $$ ) {
my $rule = 0; my $rule = 0;
for ( @{$fromref->{rules}} ) { for ( @{$fromref->{rules}} ) {
$rule++; $rule++;
if ( defined && s/ -[jg] $chainref->{name}(\b)/ -j ${target}$1/ ) { if ( s/ -[jg] $chainref->{name}(\b)/ -j ${target}$1/ ) {
$count++ ; $count++ ;
trace( $fromref, 'R', $rule, $_ ) if $debug; trace( $fromref, 'R', $rule, $_ ) if $debug;
} }
@ -1511,17 +1547,15 @@ sub replace_references1( $$$ ) {
my $rule = 0; my $rule = 0;
for ( @{$fromref->{rules}} ) { for ( @{$fromref->{rules}} ) {
$rule++; $rule++;
if ( defined ) { if ( /^-A $fromref->{name} .*-[jg] $chainref->{name}\b/ ) {
if ( /^-A $fromref->{name} .*-[jg] $chainref->{name}\b/ ) { #
# # Prevent multiple '-p' matches
# Prevent multiple '-p' matches #
# s/ -p [^ ]+ / / if / -p / && $matches =~ / -p /;
s/ -p [^ ]+ / / if / -p / && $matches =~ / -p /; s/\s+-([jg]) $chainref->{name}(\b)/$matches -$1 ${target}$2/;
s/\s+-([jg]) $chainref->{name}(\b)/$matches -$1 ${target}$2/; add_reference ( $fromref, $chain_table{$table}{$target} );
add_reference ( $fromref, $chain_table{$table}{$target} ); $count++;
$count++; trace( $fromref, 'R', $rule, $_ ) if $debug;
trace( $fromref, 'R', $rule, $_ ) if $debug;
}
} }
} }
} }
@ -1535,16 +1569,14 @@ sub replace_references1( $$$ ) {
if ( $fromref->{referenced} ) { if ( $fromref->{referenced} ) {
for ( @{$fromref->{rules}} ) { for ( @{$fromref->{rules}} ) {
$rule++; $rule++;
if ( defined ) { if ( /^-A $fromref->{name} .*-[jg] $chainref->{name}\b/ ) {
if ( /^-A $fromref->{name} .*-[jg] $chainref->{name}\b/ ) { #
# # Prevent multiple '-p' matches
# Prevent multiple '-p' matches #
# s/ -p [^ ]+ / / if / -p / && $matches =~ / -p /;
s/ -p [^ ]+ / / if / -p / && $matches =~ / -p /; s/\s+-[jg] $chainref->{name}(\b)/$matches -j ${target}$1/;
s/\s+-[jg] $chainref->{name}(\b)/$matches -j ${target}$1/; $count++;
$count++; trace( $fromref, 'R', $rule, $_ ) if $debug;
trace( $fromref, 'R', $rule, $_ ) if $debug;
}
} }
} }
} }
@ -1639,21 +1671,7 @@ sub optimize_ruleset() {
} }
unless ( $chainref->{dont_optimize} ) { unless ( $chainref->{dont_optimize} ) {
# my $numrules = @{$chainref->{rules}};
# Next count the rules -- we must do that because
# we delete rules by setting them
# to nil.
my $numrules = 0;
my $firstrule;
my $lastrule;
for ( @{$chainref->{rules}} ) {
if ( defined ) {
$numrules++;
$lastrule = $_;
$firstrule = $_ unless defined $firstrule;
}
}
if ( $numrules == 0 ) { if ( $numrules == 0 ) {
# #
@ -1672,8 +1690,9 @@ sub optimize_ruleset() {
$progress = 1; $progress = 1;
} }
} elsif ( $numrules == 1 ) { } elsif ( $numrules == 1 ) {
my $firstrule = $chainref->{rules}[0];
# #
# Chain has a single non-nil rule which is in $firstrule # Chain has a single rule
# #
if ( $firstrule =~ /^-A $chainref->{name} -[jg] (.*)$/ ) { if ( $firstrule =~ /^-A $chainref->{name} -[jg] (.*)$/ ) {
# #
@ -1736,11 +1755,7 @@ sub optimize_ruleset() {
$passes++; $passes++;
for my $chainref ( grep $_->{referenced}, values %{$chain_table{$table}} ) { for my $chainref ( grep $_->{referenced}, values %{$chain_table{$table}} ) {
my $lastrule; my $lastrule = $chainref->{rules}[-1];
for ( @{$chainref->{rules}} ) {
$lastrule = $_ if defined;
}
if ( defined $lastrule && $lastrule =~ /^-A $chainref->{name} -[jg] (.*)$/ ) { if ( defined $lastrule && $lastrule =~ /^-A $chainref->{name} -[jg] (.*)$/ ) {
# #

View File

@ -833,6 +833,10 @@ sub compiler {
if ( $config{OPTIMIZE} & 6 ) { if ( $config{OPTIMIZE} & 6 ) {
progress_message2 'Optimizing Ruleset...'; progress_message2 'Optimizing Ruleset...';
# #
# Prepare table for optimization
#
prepare_for_optimization;
#
# Optimize Policy Chains # Optimize Policy Chains
# #
optimize_policy_chains if $config{OPTIMIZE} & 2; optimize_policy_chains if $config{OPTIMIZE} & 2;

View File

@ -17,6 +17,8 @@ Changes in Shorewall 4.4.9
8) Deallocate unused rules. 8) Deallocate unused rules.
9) Keep rule arrays compressed during optimization.
Changes in Shorewall 4.4.8 Changes in Shorewall 4.4.8
1) Correct handling of RATE LIMIT on NAT rules. 1) Correct handling of RATE LIMIT on NAT rules.