On 2/15/11 8:00 PM, Tom Eastep wrote:

>>
>> Using the following accounting rules, Shorewall generates an iptables chain 
>> test4 that is unreferenced.
>>
>> SECTION INPUT
>> test
>> test2:COUNT  test
>> test3:COUNT  test2
>> test4:COUNT  test3
>> ACCOUNT(net2lan,192.168.0.0/24)  test4
>>
>> A copy of the config. is attached.
> 
> I've pushed b03e3b94ef5a54fc2d658ef355c543d4241005a6 which fixes some
> optimization problems (one hunk I think you already have). But I still
> haven't identified the root cause of the issue you have raised. I'll
> work on it again tomorrow.

Here is a patch to be applied after the one mentioned above. It fixes
the problem that you have described but I'm not yet convinced that the
fix is complete.

-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 a3bfc95..d5d79e4 100644
--- a/Shorewall/Perl/Shorewall/Chains.pm
+++ b/Shorewall/Perl/Shorewall/Chains.pm
@@ -759,6 +759,15 @@ sub increment_reference_count( $$ ) {
     $toref->{references}{$chain}++ if $toref;
 }
 
+sub decrement_reference_count( $$ ) {
+    my ($toref, $chain) = @_;
+
+    if ( $toref && $toref->{referenced} && $toref->{references}{$chain} ) {
+       delete $toref->{references}{$chain} unless 
--$toref->{references}{$chain};
+       delete_chain( $toref ) unless ( keys %{$toref->{references}} );
+    }
+}      
+
 #
 # Move the rules from one chain to another
 #
@@ -815,6 +824,30 @@ sub move_rules( $$ ) {
 }
 
 #
+# Recursively delete references from $chain to $name
+#
+sub recursive_delete_references( $$ );
+
+sub recursive_delete_references( $$ ) {
+    my ( $chain1, $chain2 ) = @_;
+
+    my $name2 = $chain2->{name};
+
+    unless ( --$chain1->{references}{$name2} ) {
+       delete $chain1->{references}{$name2};
+       unless ( keys %{$chain1->{references}} ) {
+           my $tableref = $chain_table{$chain1->{table}};
+           my $name1    = $chain1->{name}; 
+           for ( @{$chain1->{rules}} ) {
+               decrement_reference_count( $tableref->{$1}, $name1 ) if / -[jg] 
([^\s]+)/;
+           }
+
+           delete_chain $chain1;
+       }
+    }
+}
+
+#
 # Replace the jump at the end of one chain (chain2) with the rules from 
another chain (chain1).
 #
 
@@ -881,12 +914,7 @@ sub copy_rules( $$ ) {
 
     progress_message "  $count rules from $chain1->{name} appended to 
$chain2->{name}";
 
-    unless ( --$chain1->{references}{$name2} ) {
-       delete $chain1->{references}{$name2};
-       unless ( keys %{$chain1->{references}} ) {
-           delete_chain $chain1;
-       }
-    }
+    recursive_delete_references( $chain1, $chain2 );
 }
 
 #
@@ -1604,7 +1632,7 @@ sub optimize_chain( $ ) {
            progress_message "  $count ACCEPT rules deleted from $type chain 
$chainref->{name}" if $count;
        } elsif ( $chainref->{builtin} ) {
            $chainref->{policy} = 'ACCEPT';
-           trace( $chainref, 'P', undef, 'ACCEPT' );
+           trace( $chainref, 'P', undef, 'ACCEPT' ) if $debug;
            $count++;
            progress_message "  $count ACCEPT rules deleted from builtin chain 
$chainref->{name}";
        } else {
@@ -1667,7 +1695,7 @@ sub replace_references( $$ ) {
 
     $name =~ s/\+/\\+/;
 
-    if ( defined $tableref->{$target}  && ! $tableref->{$target}{builtin} ) {
+    if ( ! $tableref->{$target}{builtin} ) {
        #
        # The target is a chain -- use the jump type from each referencing rule
        #
@@ -1676,12 +1704,14 @@ sub replace_references( $$ ) {
                my $rule = 0;
                for ( @{$fromref->{rules}} ) {
                    $rule++;
-                   if ( s/ -([jg]) $name(.*$)/ -$1 ${target}$2/ ) {
+                   if ( s/ -([jg]) $name(\s|$)/ -$1 ${target}$2/ ) {
                        add_reference ( $fromref, $tableref->{$target} );
                        $count++;
                        trace( $fromref, 'R', $rule, $_ ) if $debug;
                    }
                }
+               
+               delete $chainref->{references}{$fromref->{name}};
            }
        }
 
@@ -1695,13 +1725,18 @@ sub replace_references( $$ ) {
                my $rule = 0;
                for ( @{$fromref->{rules}} ) {
                    $rule++;
-                   if ( s/ -[jg] $name(.*$)/ -j ${target}$1/ ) {
+                   if ( s/ -[jg] $name(\s|$)/ -j ${target}$1/ ) {
+                       add_reference ( $fromref, $tableref->{$target} );
                        $count++ ;
                        trace( $fromref, 'R', $rule, $_ ) if $debug;
                    }
                }
+
+               delete $chainref->{references}{$fromref->{name}};
            }
        }
+
+       delete $tableref->{$target}{references}{$chainref->{name}};
     }
 
     progress_message "  $count references to chain $chainref->{name} replaced" 
if $count;

Attachment: signature.asc
Description: OpenPGP digital signature

------------------------------------------------------------------------------
The ultimate all-in-one performance toolkit: Intel(R) Parallel Studio XE:
Pinpoint memory and threading errors before they happen.
Find and fix more than 250 security defects in the development cycle.
Locate bottlenecks in serial and parallel code that limit performance.
http://p.sf.net/sfu/intel-dev2devfeb
_______________________________________________
Shorewall-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/shorewall-devel

Reply via email to