From 028fc20741e085ce1f1b2bf53ca5dca766e91df9 Mon Sep 17 00:00:00 2001
From: Tom Eastep <teastep@shorewall.net>
Date: Sat, 23 Jul 2011 07:31:58 -0700
Subject: [PATCH] Correct reference accounting when long port lists are split

Signed-off-by: Tom Eastep <teastep@shorewall.net>
---
 Shorewall/Perl/Shorewall/Chains.pm | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm
index bf0dd38e9..1773c11e3 100644
--- a/Shorewall/Perl/Shorewall/Chains.pm
+++ b/Shorewall/Perl/Shorewall/Chains.pm
@@ -266,6 +266,7 @@ our $filter_table;
 my  $comment;
 my  @comments;
 my  $export;
+my  $splitcount;
 
 #
 # Target Types
@@ -951,12 +952,14 @@ sub handle_port_list( $$$$$$ ) {
 		handle_port_list( $chainref, $newrule, 0, $1, $2, $3 );
 	    } else {
 		push_rule ( $chainref, $newrule );
+		$splitcount++;
 	    }
 	}
     } elsif ( $dport && $rule =~  /^(.* --sports\s+)([^ ]+)(.*)$/ ) {
 	handle_port_list( $chainref, $rule, 0, $1, $2, $3 );
     } else {
 	push_rule ( $chainref, $rule );
+	$splitcount++;
     }
 }
 
@@ -966,7 +969,7 @@ sub handle_port_list( $$$$$$ ) {
 sub handle_icmptype_list( $$$$ ) {
     my ($chainref, $first, $types, $rest) = @_;
     my @ports = split ',', $types;
-    push_rule ( $chainref, join ( '', $first, shift @ports, $rest ) ) while @ports;
+    push_rule ( $chainref, join ( '', $first, shift @ports, $rest ) ), $splitcount++ while @ports;
 }
 
 #
@@ -1010,9 +1013,11 @@ sub add_rule($$;$) {
 		handle_icmptype_list( $chainref, $first, $types, $rest );
 	    } else {
 		push_rule( $chainref, $rule );
+		$splitcount++;
 	    }
 	} else {
 	    push_rule ( $chainref, $rule );
+	    $splitcount++;
 	}
     } else {
 	push_rule( $chainref, $rule );
@@ -4523,6 +4528,10 @@ sub expand_rule( $$$$$$$$$$;$ )
 	push @ends, $end;
     }
     #
+    # Clear Split Count
+    #
+    $splitcount = 0;
+    #
     # Trim disposition
     #
     $disposition =~ s/\s.*//;
@@ -5021,7 +5030,10 @@ sub expand_rule( $$$$$$$$$$;$ )
 	my $targetref = $chain_table{$table}{$target};
 	if ( $targetref ) {
 	    $targetref->{referenced} = 1;
-	    add_reference $fromref, $targetref;
+	    
+	    for ( my $i = 0; $i < $splitcount; $i++ ) {
+		add_reference $fromref, $targetref;
+	    }
 	}
     }