forked from extern/shorewall_code
Use splice() to delete rules from chains
Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
parent
2f3f591af1
commit
1e078b8c8d
@ -593,23 +593,6 @@ sub add_reference ( $$ ) {
|
||||
$toref->{references}{$fromref->{name}}++;
|
||||
}
|
||||
|
||||
#
|
||||
# Compress out undefined elements in rules - beginning with 4.4.9, this gets called any time that
|
||||
# a rule other than the last one in the chain is deleted (set to 'undef').
|
||||
#
|
||||
sub compress_rules( $ ) {
|
||||
my $chainref = shift;
|
||||
my @rules;
|
||||
|
||||
for ( @{$chainref->{rules}} ) {
|
||||
push @rules, $_ if defined;
|
||||
}
|
||||
|
||||
$chainref->{rules} = \@rules;
|
||||
|
||||
trace( $chainref, 'C', undef, '' ) if $debug;
|
||||
}
|
||||
|
||||
#
|
||||
# Purge jumps previously added via add_jump. If the target chain is empty, reset its
|
||||
# referenced flag
|
||||
@ -617,20 +600,30 @@ sub compress_rules( $ ) {
|
||||
sub purge_jump ( $$ ) {
|
||||
my ( $fromref, $toref ) = @_;
|
||||
my $to = $toref->{name};
|
||||
#
|
||||
# splice() of an array being iterated over causes elements to be skipped so
|
||||
# we need to restart the scan after each deletion.
|
||||
#
|
||||
my $progress = 1;
|
||||
|
||||
while ( $progress ) {
|
||||
my $rule = 0;
|
||||
my $rules = @{$fromref->{rules}};
|
||||
my $deleted = 0;
|
||||
|
||||
$progress = 0;
|
||||
|
||||
for ( @{$fromref->{rules}} ) {
|
||||
$rule++;
|
||||
if ( / -[gj] ${to}\b/ ) {
|
||||
trace( $fromref, 'D', $rule, $_ ) if $debug;
|
||||
$_ = undef;
|
||||
$deleted = 1 unless $rule == $rules && $rules > 1;
|
||||
trace( $fromref, 'D', $rule + 1, $_ ) if $debug;
|
||||
splice( @{$fromref->{rules}}, $rule, 1 );
|
||||
$progress = 1;
|
||||
last;
|
||||
}
|
||||
|
||||
$rule++;
|
||||
}
|
||||
}
|
||||
|
||||
compress_rules( $fromref ) if $deleted;
|
||||
delete $toref->{references}{$fromref->{name}};
|
||||
|
||||
unless ( @{$toref->{rules}} ) {
|
||||
$toref->{referenced} = 0;
|
||||
@ -1438,22 +1431,31 @@ sub delete_references( $ ) {
|
||||
my $count = 0;
|
||||
|
||||
for my $fromref ( map $chain_table{$table}{$_} , keys %{$chainref->{references}} ) {
|
||||
#
|
||||
# splice() of an array being iterated over causes elements to be skipped so
|
||||
# we need to restart the scan after each deletion.
|
||||
#
|
||||
my $progress = 1;
|
||||
|
||||
while ( $progress ) {
|
||||
my $rule = 0;
|
||||
my $deleted = 0;
|
||||
my $rules = @{$fromref->{rules}};
|
||||
|
||||
$progress = 0;
|
||||
|
||||
for ( @{$fromref->{rules}} ) {
|
||||
$rule++;
|
||||
|
||||
if ( / -[jg] $chainref->{name}$/ ) {
|
||||
trace( $fromref, 'D', $rule, $_ ) if $debug;
|
||||
$_ = undef;
|
||||
trace( $fromref, 'D', $rule + 1, $_ ) if $debug;
|
||||
splice( @{$fromref->{rules}}, $rule, 1 );
|
||||
$count++;
|
||||
$deleted = 1 unless $rule == $rules && $rules > 1;
|
||||
$progress = 1;
|
||||
last;
|
||||
}
|
||||
|
||||
$rule++;
|
||||
}
|
||||
}
|
||||
|
||||
compress_rules( $fromref ) if $deleted;
|
||||
delete $chainref->{references}{$fromref->{name}};
|
||||
}
|
||||
|
||||
if ( $count ) {
|
||||
|
@ -293,9 +293,8 @@ None.
|
||||
I - Inserted a rule into a chain.
|
||||
T - Shell source text appended/inserted into a chain --
|
||||
converted into rules at run-time.
|
||||
D - Deleted Rule from a chain
|
||||
C - Compressed the rules array for a chain to remove deleted
|
||||
rules. This renumbers the remaining rules.
|
||||
D - Deleted Rule from a chain; note that this causes the
|
||||
following rules to be renumbered.
|
||||
X - Deleted a chain
|
||||
|
||||
Netfilter trace records indicate the table and chain being
|
||||
@ -304,7 +303,7 @@ None.
|
||||
|
||||
Example (append the first rule to the filter FORWARD chain):
|
||||
|
||||
NF-(A)-> filter:FORWARD:1
|
||||
NF-(A)-> filter:FORWARD:1 ...
|
||||
|
||||
If the trace record involves the chain itself, then no rule number
|
||||
is present.
|
||||
|
Loading…
Reference in New Issue
Block a user