Correct Chains::promote_blacklist_rules()

- Interate through chains that jump to 'blacklst' until no rule is promoted
  This is required to promote jumps past exclusion chains
- Correct reference counting; the first cut was horribly wrong

Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
Tom Eastep 2010-09-18 08:36:35 -07:00
parent c040344bc1
commit 6f0893cd7a

View File

@ -214,7 +214,7 @@ our $VERSION = '4.4_13';
# ] # ]
# logchains => { <key1> = <chainref1>, ... } # logchains => { <key1> = <chainref1>, ... }
# references => { <ref1> => <refs>, <ref2> => <refs>, ... } # references => { <ref1> => <refs>, <ref2> => <refs>, ... }
# blacklist => <number of blacklist rules at the head of the rules array> # blacklist => <number of blacklist rules at the head of the rules array> ( 0 or 1 )
# } , # } ,
# <chain2> => ... # <chain2> => ...
# } # }
@ -3684,19 +3684,26 @@ sub expand_rule( $$$$$$$$$$;$ )
# the associated interface chain # the associated interface chain
# #
sub promote_blacklist_rules() { sub promote_blacklist_rules() {
my $promoted = 1;
my $chainbref = $filter_table->{blacklst};
while ( $promoted ) {
$promoted = 0;
for my $chain1ref ( grep $_->{blacklist} , values %$filter_table ) { for my $chain1ref ( grep $_->{blacklist} , values %$filter_table ) {
my $copied = 0; my $copied = 0;
my $rule = $chain1ref->{rules}[0]; my $rule = $chain1ref->{rules}[0];
my $chain1 = $chain1ref->{name};
# #
# Isolate the name of the blacklist chain # Isolate the name of the blacklist chain
# #
$rule =~ / -j ([^\/s]+)/; $rule =~ / -j ([^\s]+)/;
my $chainb = $1; my $chainb = $1;
assert( $chainb && $chainb =~ /^black/ ); assert( $chainb && $chainb =~ /^black/ );
unless ( $chainb eq 'blackout' ) { next unless $chainb eq 'blacklst';
# #
# An 'in' blacklist rule # An 'in' blacklist rule
# #
@ -3705,7 +3712,6 @@ sub promote_blacklist_rules() {
# #
# This is not INPUT or FORWARD -- we wouldn't want to move the # This is not INPUT or FORWARD -- we wouldn't want to move the
# rule to the head of one of those chains # rule to the head of one of those chains
#
$copied++; $copied++;
# #
# Copy the blacklist rule to the head of the parent chain unless it # Copy the blacklist rule to the head of the parent chain unless it
@ -3713,8 +3719,8 @@ sub promote_blacklist_rules() {
# #
unless ( $chain2ref->{blacklist} ) { unless ( $chain2ref->{blacklist} ) {
unshift @{$chain2ref->{rules}}, $rule; unshift @{$chain2ref->{rules}}, $rule;
$chain2ref->{references}{$chainb}++; $chainbref->{references}{$chain2ref->{name}}++;
$chain2ref->{blacklist}++; $chain2ref->{blacklist} = 1;
} }
} }
} }
@ -3722,11 +3728,13 @@ sub promote_blacklist_rules() {
if ( $copied ) { if ( $copied ) {
shift @{$chain1ref->{rules}}; shift @{$chain1ref->{rules}};
$chain1ref->{blacklist} = 0; $chain1ref->{blacklist} = 0;
$chain1ref->{references}{chainb}--; assert ( $chainbref->{references}{$chain1ref->{name}}-- > 0 );
$promoted = 1;
} }
} }
} }
} }
# #
# The following code generates the input to iptables-restore from the contents of the # The following code generates the input to iptables-restore from the contents of the
# @rules arrays in the chain table entries. # @rules arrays in the chain table entries.