forked from extern/shorewall_code
Optimize 8
Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
parent
3b6b7a4099
commit
f8bacb54ef
@ -1621,125 +1621,160 @@ sub optimize_ruleset() {
|
|||||||
|
|
||||||
my $progress = 1;
|
my $progress = 1;
|
||||||
my $passes = 0;
|
my $passes = 0;
|
||||||
#
|
|
||||||
# Make repeated passes through each table looking for short chains (those with less than 2 entries)
|
|
||||||
#
|
|
||||||
# When an unreferenced chain is found, it is deleted unless its 'dont_delete' flag is set.
|
|
||||||
# When an empty chain is found, delete the references to it.
|
|
||||||
# When a chain with a single entry is found, replace it's references by its contents
|
|
||||||
#
|
|
||||||
# The search continues until no short chains remain
|
|
||||||
# Chains with 'dont_optimize = 1' are exempted from optimization
|
|
||||||
#
|
|
||||||
while ( $progress ) {
|
|
||||||
$progress = 0;
|
|
||||||
$passes++;
|
|
||||||
|
|
||||||
for my $chainref ( grep $_->{referenced}, values %{$chain_table{$table}} ) {
|
if ( $config{OPTIMIZE} & 4 ) {
|
||||||
#
|
#
|
||||||
# If the chain isn't branched to, then delete it
|
# Make repeated passes through each table looking for short chains (those with less than 2 entries)
|
||||||
#
|
#
|
||||||
unless ( $chainref->{dont_delete} || keys %{$chainref->{references}} ) {
|
# When an unreferenced chain is found, it is deleted unless its 'dont_delete' flag is set.
|
||||||
delete_chain $chainref;
|
# When an empty chain is found, delete the references to it.
|
||||||
progress_message " Unreferenced chain $chainref->{name} deleted";
|
# When a chain with a single entry is found, replace it's references by its contents
|
||||||
next;
|
#
|
||||||
}
|
# The search continues until no short chains remain
|
||||||
|
# Chains with 'dont_optimize = 1' are exempted from optimization
|
||||||
|
#
|
||||||
|
while ( $progress ) {
|
||||||
|
$progress = 0;
|
||||||
|
$passes++;
|
||||||
|
|
||||||
unless ( $chainref->{dont_optimize} ) {
|
for my $chainref ( grep $_->{referenced}, values %{$chain_table{$table}} ) {
|
||||||
my $numrules = @{$chainref->{rules}};
|
#
|
||||||
|
# If the chain isn't branched to, then delete it
|
||||||
if ( $numrules == 0 ) {
|
#
|
||||||
#
|
unless ( $chainref->{dont_delete} || keys %{$chainref->{references}} ) {
|
||||||
# No rules in this chain
|
delete_chain $chainref;
|
||||||
#
|
progress_message " Unreferenced chain $chainref->{name} deleted";
|
||||||
if ( $chainref->{builtin} ) {
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
unless ( $chainref->{dont_optimize} ) {
|
||||||
|
my $numrules = @{$chainref->{rules}};
|
||||||
|
|
||||||
|
if ( $numrules == 0 ) {
|
||||||
#
|
#
|
||||||
# Built-in -- mark it 'dont_optimize' so we ignore it in follow-on passes
|
# No rules in this chain
|
||||||
#
|
|
||||||
$chainref->{dont_optimize} = 1;
|
|
||||||
} else {
|
|
||||||
#
|
|
||||||
# Not a built-in -- we can delete it and it's references
|
|
||||||
#
|
|
||||||
delete_references $chainref;
|
|
||||||
$progress = 1;
|
|
||||||
}
|
|
||||||
} elsif ( $numrules == 1 ) {
|
|
||||||
my $firstrule = $chainref->{rules}[0];
|
|
||||||
#
|
|
||||||
# Chain has a single rule
|
|
||||||
#
|
|
||||||
if ( $firstrule =~ /^-A $chainref->{name} -[jg] (.*)$/ ) {
|
|
||||||
#
|
|
||||||
# Easy case -- the rule is a simple jump
|
|
||||||
#
|
#
|
||||||
if ( $chainref->{builtin} ) {
|
if ( $chainref->{builtin} ) {
|
||||||
#
|
#
|
||||||
# A built-in chain. If the target is a user chain without 'dont_move',
|
# Built-in -- mark it 'dont_optimize' so we ignore it in follow-on passes
|
||||||
# we can move its rules to the built-in
|
|
||||||
#
|
|
||||||
if ( conditionally_move_rules $chainref, $1 ) {
|
|
||||||
#
|
|
||||||
# Target was a user chain -- rules moved
|
|
||||||
#
|
|
||||||
$progress = 1;
|
|
||||||
} else {
|
|
||||||
#
|
|
||||||
# Target was a built-in. Ignore this chain in follow-on passes
|
|
||||||
#
|
|
||||||
$chainref->{dont_optimize} = 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
#
|
|
||||||
# Replace all references to this chain with references to the target
|
|
||||||
#
|
|
||||||
replace_references $chainref, $1;
|
|
||||||
$progress = 1;
|
|
||||||
}
|
|
||||||
} elsif ( $firstrule =~ /-A $chainref->{name}( +.+) -[jg] (.*)$/ ) {
|
|
||||||
#
|
|
||||||
# Not so easy -- the rule contains matches
|
|
||||||
#
|
|
||||||
if ( $chainref->{builtin} || ! have_capability 'KLUDGEFREE' ) {
|
|
||||||
#
|
|
||||||
# This case requires a new rule merging algorithm. Ignore this chain for
|
|
||||||
# now.
|
|
||||||
#
|
#
|
||||||
$chainref->{dont_optimize} = 1;
|
$chainref->{dont_optimize} = 1;
|
||||||
} else {
|
} else {
|
||||||
#
|
#
|
||||||
# Replace references to this chain with the target and add the predicates
|
# Not a built-in -- we can delete it and it's references
|
||||||
#
|
#
|
||||||
replace_references1 $chainref, $2, $1;
|
delete_references $chainref;
|
||||||
$progress = 1;
|
$progress = 1;
|
||||||
}
|
}
|
||||||
|
} elsif ( $numrules == 1 ) {
|
||||||
|
my $firstrule = $chainref->{rules}[0];
|
||||||
|
#
|
||||||
|
# Chain has a single rule
|
||||||
|
#
|
||||||
|
if ( $firstrule =~ /^-A $chainref->{name} -[jg] (.*)$/ ) {
|
||||||
|
#
|
||||||
|
# Easy case -- the rule is a simple jump
|
||||||
|
#
|
||||||
|
if ( $chainref->{builtin} ) {
|
||||||
|
#
|
||||||
|
# A built-in chain. If the target is a user chain without 'dont_move',
|
||||||
|
# we can move its rules to the built-in
|
||||||
|
#
|
||||||
|
if ( conditionally_move_rules $chainref, $1 ) {
|
||||||
|
#
|
||||||
|
# Target was a user chain -- rules moved
|
||||||
|
#
|
||||||
|
$progress = 1;
|
||||||
|
} else {
|
||||||
|
#
|
||||||
|
# Target was a built-in. Ignore this chain in follow-on passes
|
||||||
|
#
|
||||||
|
$chainref->{dont_optimize} = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
#
|
||||||
|
# Replace all references to this chain with references to the target
|
||||||
|
#
|
||||||
|
replace_references $chainref, $1;
|
||||||
|
$progress = 1;
|
||||||
|
}
|
||||||
|
} elsif ( $firstrule =~ /-A $chainref->{name}( +.+) -[jg] (.*)$/ ) {
|
||||||
|
#
|
||||||
|
# Not so easy -- the rule contains matches
|
||||||
|
#
|
||||||
|
if ( $chainref->{builtin} || ! have_capability 'KLUDGEFREE' ) {
|
||||||
|
#
|
||||||
|
# This case requires a new rule merging algorithm. Ignore this chain for
|
||||||
|
# now.
|
||||||
|
#
|
||||||
|
$chainref->{dont_optimize} = 1;
|
||||||
|
} else {
|
||||||
|
#
|
||||||
|
# Replace references to this chain with the target and add the predicates
|
||||||
|
#
|
||||||
|
replace_references1 $chainref, $2, $1;
|
||||||
|
$progress = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
#
|
||||||
#
|
# In this loop, we look for chains that end in an unconditional jump. If the target of the jump
|
||||||
# In this loop, we look for chains that end in an unconditional jump. If the target of the jump
|
# is subject to deletion (dont_delete = false), the jump is replaced by target's rules.
|
||||||
# is subject to deletion (dont_delete = false), the jump is replaced by target's rules.
|
#
|
||||||
#
|
$progress = 1;
|
||||||
$progress = 1;
|
|
||||||
|
while ( $progress ) {
|
||||||
while ( $progress ) {
|
$progress = 0;
|
||||||
$progress = 0;
|
$passes++;
|
||||||
$passes++;
|
|
||||||
|
for my $chainref ( grep $_->{referenced}, values %{$chain_table{$table}} ) {
|
||||||
for my $chainref ( grep $_->{referenced}, values %{$chain_table{$table}} ) {
|
my $lastrule = $chainref->{rules}[-1];
|
||||||
my $lastrule = $chainref->{rules}[-1];
|
|
||||||
|
|
||||||
if ( defined $lastrule && $lastrule =~ /^-A $chainref->{name} -[jg] (.*)$/ ) {
|
|
||||||
#
|
|
||||||
# Last rule is a simple branch
|
|
||||||
my $targetref = $chain_table{$table}{$1};
|
|
||||||
|
|
||||||
if ( $targetref && ! ( $targetref->{builtin} || $targetref->{dont_move} ) ) {
|
if ( defined $lastrule && $lastrule =~ /^-A $chainref->{name} -[jg] (.*)$/ ) {
|
||||||
copy_rules( $targetref, $chainref );
|
#
|
||||||
$progress = 1;
|
# Last rule is a simple branch
|
||||||
|
my $targetref = $chain_table{$table}{$1};
|
||||||
|
|
||||||
|
if ( $targetref && ! ( $targetref->{builtin} || $targetref->{dont_move} ) ) {
|
||||||
|
copy_rules( $targetref, $chainref );
|
||||||
|
$progress = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $config{OPTIMIZE} & 8 ) {
|
||||||
|
#
|
||||||
|
# Now delete duplicate chains
|
||||||
|
#
|
||||||
|
$progress = 1;
|
||||||
|
|
||||||
|
while ( $progress ) {
|
||||||
|
$progress = 0;
|
||||||
|
$passes++;
|
||||||
|
|
||||||
|
for my $chainref ( grep $_->{referenced} && ! $_->{builtin}, values %{$chain_table{$table}} ) {
|
||||||
|
my $rules = $chainref->{rules};
|
||||||
|
CHAIN:
|
||||||
|
for my $chainref1 ( grep $_->{referenced}, values %{$chain_table{$table}} ) {
|
||||||
|
next if $chainref->{name} eq $chainref1->{name};
|
||||||
|
my $rules1 = $chainref1->{rules};
|
||||||
|
next if @$rules != @$rules1;
|
||||||
|
next if $chainref1->{dont_delete};
|
||||||
|
next if $chainref1->{builtin};
|
||||||
|
|
||||||
|
for ( my $i = 0; $i <= $#$rules; $i++ ) {
|
||||||
|
my $rule = $rules->[$i];
|
||||||
|
$rule =~ s/^-A $chainref->{name} /-A $chainref1->{name} /;
|
||||||
|
next CHAIN unless $rule eq $rules1->[$i];
|
||||||
|
}
|
||||||
|
|
||||||
|
replace_references $chainref1, $chainref->{name};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -830,7 +830,7 @@ sub compiler {
|
|||||||
#
|
#
|
||||||
generate_matrix;
|
generate_matrix;
|
||||||
|
|
||||||
if ( $config{OPTIMIZE} & 6 ) {
|
if ( $config{OPTIMIZE} & 0xD ) {
|
||||||
progress_message2 'Optimizing Ruleset...';
|
progress_message2 'Optimizing Ruleset...';
|
||||||
#
|
#
|
||||||
# Optimize Policy Chains
|
# Optimize Policy Chains
|
||||||
@ -839,7 +839,7 @@ sub compiler {
|
|||||||
#
|
#
|
||||||
# More Optimization
|
# More Optimization
|
||||||
#
|
#
|
||||||
optimize_ruleset if $config{OPTIMIZE} & 4;
|
optimize_ruleset if $config{OPTIMIZE} & 0xC;
|
||||||
}
|
}
|
||||||
|
|
||||||
enable_script;
|
enable_script;
|
||||||
|
@ -3060,7 +3060,7 @@ sub get_configuration( $ ) {
|
|||||||
|
|
||||||
$val = numeric_value $config{OPTIMIZE};
|
$val = numeric_value $config{OPTIMIZE};
|
||||||
|
|
||||||
fatal_error "Invalid OPTIMIZE value ($config{OPTIMIZE})" unless defined( $val ) && $val >= 0 && ( $val & ( 4096 ^ -1 ) ) <= 7;
|
fatal_error "Invalid OPTIMIZE value ($config{OPTIMIZE})" unless defined( $val ) && $val >= 0 && ( $val & ( 4096 ^ -1 ) ) <= 15;
|
||||||
|
|
||||||
$globals{MARKING_CHAIN} = $config{MARK_IN_FORWARD_CHAIN} ? 'tcfor' : 'tcpre';
|
$globals{MARKING_CHAIN} = $config{MARK_IN_FORWARD_CHAIN} ? 'tcfor' : 'tcpre';
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user