Delete jumps to empty chains

git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@9556 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
teastep 2009-02-27 16:19:36 +00:00
parent fa4fc86e18
commit e6fa6a5153
3 changed files with 83 additions and 59 deletions

View File

@ -73,6 +73,7 @@ our %EXPORT_TAGS = (
add_commands
move_rules
insert_rule1
purge_jump
add_tunnel_rule
process_comment
no_comment
@ -602,6 +603,21 @@ sub add_jump( $$$;$ ) {
add_rule ($fromref, join( '', $predicate, "-$param $to" ) );
}
#
# Purge a jump previously added via add_jump. If the target chain is empty, reset its
# referenced flag
#
sub purge_jump ( $$ ) {
my ( $fromref, $toref ) = @_;
my $to = $toref->{name};
for ( @{$fromref->{rules}} ) {
$_ = undef, last if / -j ${to}\b/;
}
$toref->{referenced} = 0 unless @{$toref->{rules}};
}
#
# Insert a rule into a chain. Arguments are:
#
@ -2773,7 +2789,7 @@ sub create_netfilter_load( $ ) {
# Then emit the rules
#
for my $chainref ( @chains ) {
emitr $chainref->{name}, $_ for ( @{$chainref->{rules}} );
emitr $chainref->{name}, $_ for ( grep defined $_, @{$chainref->{rules}} );
}
#
# Commit the changes to the table
@ -2885,7 +2901,7 @@ sub create_chainlist_reload($) {
#
# Emit the chain rules
#
emitr $chain, $_ for ( @rules );
emitr $chain, $_ for ( grep defined $_, @rules );
}
#
# Commit the changes to the table

View File

@ -763,7 +763,8 @@ sub lookup_provider( $ ) {
# The Tc module has collected the 'sticky' rules in the 'tcpre' and 'tcout' chains. In this function, we apply them
# to the 'tracked' providers
#
sub handle_stickiness() {
sub handle_stickiness( $ ) {
my $havesticky = shift;
my $mask = $config{HIGH_ROUTE_MARKS} ? '0xFF00' : '0xFF';
my $setstickyref = $mangle_table->{setsticky};
my $setstickoref = $mangle_table->{setsticko};
@ -772,77 +773,84 @@ sub handle_stickiness() {
my %marked_interfaces;
my $sticky = 1;
fatal_error "There are SAME tcrules but no 'track' providers" unless @routemarked_providers;
for my $providerref ( @routemarked_providers ) {
my $interface = $providerref->{interface};
my $base = uc chain_base $interface;
my $mark = $providerref->{mark};
if ( $havesticky ) {
fatal_error "There are SAME tcrules but no 'track' providers" unless @routemarked_providers;
for ( grep /-j sticky/, @{$tcpreref->{rules}} ) {
my $stickyref = ensure_mangle_chain 'sticky';
my ( $rule1, $rule2 );
my $list = sprintf "sticky%03d" , $sticky++;
for my $chainref ( $stickyref, $setstickyref ) {
add_command( $chainref, qq(if [ -n "\$${base}_IS_UP" ]; then) ), incr_cmd_level( $chainref ) if $providerref->{optional};
if ( $chainref->{name} eq 'sticky' ) {
$rule1 = $_;
$rule1 =~ s/-j sticky/-m recent --name $list --update --seconds 300 -j MARK --set-mark $mark/;
$rule2 = $_;
$rule2 =~ s/-j sticky/-m mark --mark 0\/$mask -m recent --name $list --remove/;
} else {
$rule1 = $_;
$rule1 =~ s/-j sticky/-m mark --mark $mark\/$mask -m recent --name $list --set/;
}
for my $providerref ( @routemarked_providers ) {
my $interface = $providerref->{interface};
my $base = uc chain_base $interface;
my $mark = $providerref->{mark};
for ( grep /-j sticky/, @{$tcpreref->{rules}} ) {
my $stickyref = ensure_mangle_chain 'sticky';
my ( $rule1, $rule2 );
my $list = sprintf "sticky%03d" , $sticky++;
$rule1 =~ s/-A //;
for my $chainref ( $stickyref, $setstickyref ) {
add_rule $chainref, $rule1;
add_command( $chainref, qq(if [ -n "\$${base}_IS_UP" ]; then) ), incr_cmd_level( $chainref ) if $providerref->{optional};
if ( $rule2 ) {
$rule2 =~ s/-A //;
add_rule $chainref, $rule2;
if ( $chainref->{name} eq 'sticky' ) {
$rule1 = $_;
$rule1 =~ s/-j sticky/-m recent --name $list --update --seconds 300 -j MARK --set-mark $mark/;
$rule2 = $_;
$rule2 =~ s/-j sticky/-m mark --mark 0\/$mask -m recent --name $list --remove/;
} else {
$rule1 = $_;
$rule1 =~ s/-j sticky/-m mark --mark $mark\/$mask -m recent --name $list --set/;
}
$rule1 =~ s/-A //;
add_rule $chainref, $rule1;
if ( $rule2 ) {
$rule2 =~ s/-A //;
add_rule $chainref, $rule2;
}
decr_cmd_level( $chainref), add_command( $chainref, "fi" ) if $providerref->{optional};
}
decr_cmd_level( $chainref), add_command( $chainref, "fi" ) if $providerref->{optional};
}
}
for ( grep /-j sticko/, @{$tcoutref->{rules}} ) {
my ( $rule1, $rule2 );
my $list = sprintf "sticky%03d" , $sticky++;
my $stickoref = ensure_mangle_chain 'sticko';
for ( grep /-j sticko/, @{$tcoutref->{rules}} ) {
my ( $rule1, $rule2 );
my $list = sprintf "sticky%03d" , $sticky++;
my $stickoref = ensure_mangle_chain 'sticko';
for my $chainref ( $stickoref, $setstickoref ) {
add_command( $chainref, qq(if [ -n "\$${base}_IS_UP" ]; then) ), incr_cmd_level( $chainref ) if $providerref->{optional};
for my $chainref ( $stickoref, $setstickoref ) {
add_command( $chainref, qq(if [ -n "\$${base}_IS_UP" ]; then) ), incr_cmd_level( $chainref ) if $providerref->{optional};
if ( $chainref->{name} eq 'sticko' ) {
$rule1 = $_;
$rule1 =~ s/-j sticko/-m recent --name $list --rdest --update --seconds 300 -j MARK --set-mark $mark/;
$rule2 = $_;
$rule2 =~ s/-j sticko/-m mark --mark 0\/$mask -m recent --name $list --rdest --remove/;
} else {
$rule1 = $_;
$rule1 =~ s/-j sticko/-m mark --mark $mark -m recent --name $list --rdest --set/;
}
if ( $chainref->{name} eq 'sticko' ) {
$rule1 = $_;
$rule1 =~ s/-j sticko/-m recent --name $list --rdest --update --seconds 300 -j MARK --set-mark $mark/;
$rule2 = $_;
$rule2 =~ s/-j sticko/-m mark --mark 0\/$mask -m recent --name $list --rdest --remove/;
} else {
$rule1 = $_;
$rule1 =~ s/-j sticko/-m mark --mark $mark -m recent --name $list --rdest --set/;
}
$rule1 =~ s/-A //;
$rule1 =~ s/-A //;
add_rule $chainref, $rule1;
add_rule $chainref, $rule1;
if ( $rule2 ) {
$rule2 =~ s/-A //;
add_rule $chainref, $rule2;
if ( $rule2 ) {
$rule2 =~ s/-A //;
add_rule $chainref, $rule2;
}
decr_cmd_level( $chainref), add_command( $chainref, "fi" ) if $providerref->{optional};
}
decr_cmd_level( $chainref), add_command( $chainref, "fi" ) if $providerref->{optional};
}
}
}
}
if ( @routemarked_providers ) {
purge_jump $mangle_table->{PREROUTING}, $setstickyref unless @{$setstickyref->{rules}};
purge_jump $mangle_table->{OUTPUT}, $setstickoref unless @{$setstickoref->{rules}};
}
}
1;

View File

@ -988,7 +988,7 @@ sub setup_tc() {
add_rule ensure_chain( 'mangle' , 'tcpost' ), $_;
}
handle_stickiness if $sticky;
handle_stickiness( $sticky );
}
1;