From 8b91575c9e08d9a307e4a8e1f1c9dc74593dbd22 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Wed, 17 Apr 2013 06:52:32 -0700 Subject: [PATCH] Maintain order when multiple instances of a match are separated. Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Chains.pm | 36 +++++++++++++++++++----------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index f2cd69f07..33207bae6 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -834,8 +834,9 @@ sub set_rule_option( $$$ ) { } } else { $ruleref->{$option} = $value; - push @{$ruleref->{matches}}, $option; } + + push @{$ruleref->{matches}}, $option; } sub transform_rule( $;\$ ) { @@ -945,28 +946,38 @@ sub set_rule_target( $$$ ) { sub format_option( $$ ) { my ( $option, $value ) = @_; - my $list = reftype $value ? $value : [ $value ]; + assert( ! reftype $value ); my $rule = ''; - s/\s*$//, $rule .= join( ' ' , ' -m', $option, $_ ) for @$list; + $value =~ s/\s*$//; + + $rule .= join( ' ' , ' -m', $option, $value ); $rule; } -sub debug() { - return 1; +# +# And one that 'pops' an option value +# +sub pop_match( $$ ) { + my ( $ruleref, $option ) = @_; + my $value = $ruleref->{$option}; + + $value = shift @{$ruleref->{$option}} if reftype $value; + + $value; } sub format_rule( $$;$ ) { - my ( $chainref, $ruleref, $suppresshdr ) = @_; + my ( $chainref, $rulerefp, $suppresshdr ) = @_; - return $ruleref->{cmd} if exists $ruleref->{cmd}; - - debug if $chainref->{name} eq 'drct-net'; + return $rulerefp->{cmd} if exists $rulerefp->{cmd}; my $rule = $suppresshdr ? '' : "-A $chainref->{name}"; + my $ruleref = clone_rule( $rulerefp ); + for ( @unique_options ) { if ( exists $ruleref->{$_} ) { my $value = $ruleref->{$_}; @@ -989,10 +1000,8 @@ sub format_rule( $$;$ ) { $rule .= format_option( 'state', $ruleref->{state} ); } - my %done; - for ( grep ! $opttype{$_}, @{$ruleref->{matches}} ) { - $rule .= format_option( $_, $ruleref->{$_} ) unless $done{$_}++; + $rule .= format_option( $_, pop_match( $ruleref, $_ ) ); } if ( $ruleref->{target} ) { @@ -1327,8 +1336,9 @@ sub push_matches { } else { $ruleref->{$option} = $value; $dont_optimize ||= $option =~ /^[piosd]$/ && $value =~ /^!/; - push @{$ruleref->{matches}}, $option; } + + push @{$ruleref->{matches}}, $option; } DONT_OPTIMIZE if $dont_optimize;