On 12/02/2012 08:57 AM, Tom Eastep wrote:
When optimize level 16 is requested, the optimizer currently deletes
duplicate rules only in the 'raw' table. There is quite a bit of work
and lots of testing to be done to delete them in the other table chains,
because there are cases in those chains where duplicate rules must not
deleted. As a trivial example:
-A chain -j CONNMARK --restore-mark
-A chain -m mark ! --mark 0 RETURN
-A chain -s 1.2.3.4 -j MARK --set-mark 1
-A chain -s 2.3.4.5 -j MARK --set-mark 2
-A chain -m mark ! --mark 0 RETURN
-A chain -j MARK --set-mark 3
-A chain -j CONNMARK --save-mark
It's clearly a bad idea to remove the duplicate RETURN rule.
I'll think about working on this for 4.5.11.
In the meantime, here's a very conservative patch that deletes adjacent
duplicates in the other tables.
-Tom
--
Tom Eastep \ When I die, I want to go like my Grandfather who
Shoreline, \ died peacefully in his sleep. Not screaming like
Washington, USA \ all of the passengers in his car
http://shorewall.net \________________________________________________
diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm
index 4174165..d51d400 100644
--- a/Shorewall/Perl/Shorewall/Chains.pm
+++ b/Shorewall/Perl/Shorewall/Chains.pm
@@ -3432,6 +3432,62 @@ sub delete_duplicates {
\@rules;
}
+sub delete_adjacent_duplicates {
+ my @rules;
+ my $chainref = shift;
+ my $lastrule = @_;
+ my $baseref = pop;
+ my $ruleref;
+ my $duplicate = 0;
+
+ while ( @_ && ! $duplicate ) {
+ {
+ my $ports1;
+ my @keys1 = sort( keys( %$baseref ) );
+ my $rulenum = @_;
+ my $duplicate = 0;
+
+ if ( $baseref->{mode} == CAT_MODE ) {
+ {
+ RULE:
+
+ while ( --$rulenum >= 0 ) {
+ $ruleref = $_[$rulenum];
+
+ last unless $ruleref->{mode} == CAT_MODE;
+
+ my @keys2 = sort(keys( %$ruleref ) );
+
+ last RULE unless @keys1 == @keys2 ;
+
+ my $keynum = 0;
+
+ for my $key ( @keys1 ) {
+ last RULE unless $key eq $keys2[$keynum++];
+ last RULE unless compare_values( $baseref->{$key}, $ruleref->{$key} );
+ }
+
+ $duplicate = 1;
+ }
+ }
+ }
+
+ if ( $duplicate ) {
+ trace( $chainref, 'D', $lastrule, $baseref ) if $debug;
+ } else {
+ unshift @rules, $baseref;
+ }
+
+ $baseref = pop @_;
+ $lastrule--;
+ }
+ }
+
+ unshift @rules, $baseref if $baseref;
+
+ \@rules;
+}
+
sub optimize_level16( $$$ ) {
my ( $table, $tableref , $passes ) = @_;
my @chains = ( grep $_->{referenced}, values %{$tableref} );
@@ -3440,18 +3496,24 @@ sub optimize_level16( $$$ ) {
progress_message "\n Table $table pass $passes, $chains referenced user chains, level 16...";
- if ( $table eq 'raw' ) {
- #
- # Helpers in rules have the potential for generating lots of duplicate iptables rules
- # in the raw table. This step eliminates those duplicates
- #
- for my $chainref ( @chains ) {
+ for my $chainref ( @chains ) {
+ if ( $table eq 'raw' ) {
+ #
+ # Helpers in rules have the potential for generating lots of duplicate iptables rules
+ # in the raw table. This step eliminates those duplicates
+ #
$chainref->{rules} = delete_duplicates( $chainref, @{$chainref->{rules}} );
+ } else {
+ #
+ # Conservative version that only deletes adjacent duplicates
+ #
+ $chainref->{rules} = delete_adjacent_duplicates( $chainref, @{$chainref->{rules}} );
}
- $passes++;
}
+ $passes++;
+
for my $chainref ( @chains ) {
$chainref->{rules} = combine_dports( $chainref, @{$chainref->{rules}} );
}
------------------------------------------------------------------------------
Keep yourself connected to Go Parallel:
DESIGN Expert tips on starting your parallel project right.
http://goparallel.sourceforge.net/
_______________________________________________
Shorewall-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/shorewall-devel