diff --git a/Shorewall/Shorewall/Chains.pm b/Shorewall/Shorewall/Chains.pm index facfd32f5..4adc2db3c 100644 --- a/Shorewall/Shorewall/Chains.pm +++ b/Shorewall/Shorewall/Chains.pm @@ -72,7 +72,6 @@ our %EXPORT_TAGS = ( add_command add_commands move_rules - purge_rules insert_rule1 add_tunnel_rule process_comment @@ -666,17 +665,6 @@ sub move_rules( $$ ) { } } -# -# Purge the rules from the passed chain are return them -# -sub purge_rules( $ ) { - my $chainref = shift; - my @rules = @{$chainref->{rules}}; - $chainref->{rules} = []; - $chainref->{referenced} = 0; - @rules; -} - # # Change the passed interface name so it is a legal shell variable name. # diff --git a/Shorewall/Shorewall/Providers.pm b/Shorewall/Shorewall/Providers.pm index 8184565c9..42c60bb86 100644 --- a/Shorewall/Shorewall/Providers.pm +++ b/Shorewall/Shorewall/Providers.pm @@ -102,7 +102,7 @@ sub setup_route_marking() { add_rule $mangle_table->{OUTPUT} , "-m connmark ! --mark 0/$mask -j CONNMARK --restore-mark --mask $mask"; my $chainref = new_chain 'mangle', 'routemark'; - my $chainref1 = new_chain 'mangle', 'stickymark'; + my $chainref1 = new_chain 'mangle', 'setsticky'; my %marked_interfaces; @@ -762,38 +762,38 @@ sub lookup_provider( $ ) { # to the 'tracked' providers # sub handle_stickiness() { - my $stickyref = $mangle_table->{sticky}; - my $stickymarkref = $mangle_table->{stickymark}; - my $tcpreref = $mangle_table->{tcpre}; - my @rules = purge_rules $stickyref; + my $setstickyref = $mangle_table->{setsticky}; + my $tcpreref = $mangle_table->{tcpre}; my %marked_interfaces; my $sticky = 1; - fatal_error "There are STICKY tcrules but no 'track' providers" unless @routemarked_providers; + fatal_error "There are SAME tcrules but no 'track' providers" unless @routemarked_providers; + + my $stickyref = ensure_mangle_chain 'sticky'; for my $providerref ( @routemarked_providers ) { my $interface = $providerref->{interface}; my $base = uc chain_base $interface; my $mark = $providerref->{mark}; - for my $rule ( @rules ) { + for ( grep /-j sticky/, @{$tcpreref->{rules}} ) { my $rule1; my $list = sprintf "sticky%03d" , $sticky++; - $rule =~ s/-A //; - - for my $chainref ( $tcpreref, $stickymarkref ) { + 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 'tcpre' ) { - $rule1 = $rule; - $rule1 =~ s/-j RETURN/-m recent --name $list --update --seconds 120 -j MARK --set-mark $mark/; + if ( $chainref->{name} eq 'sticky' ) { + $rule1 = $_; + $rule1 =~ s/-j sticky/-m recent --name $list --update --seconds 120 -j MARK --set-mark $mark/; } else { - $rule1 = $rule; - $rule1 =~ s/-j RETURN/-m mark --mark $mark -m recent --name $list --set/; + $rule1 = $_; + $rule1 =~ s/-j sticky/-m mark --mark $mark -m recent --name $list --set/; } + $rule1 =~ s/-A //; + add_rule $chainref, $rule1; decr_cmd_level( $chainref), add_command( $chainref, "fi" ) if $providerref->{optional}; diff --git a/Shorewall/Shorewall/Tc.pm b/Shorewall/Shorewall/Tc.pm index 80a035c54..c01924e2d 100644 --- a/Shorewall/Shorewall/Tc.pm +++ b/Shorewall/Shorewall/Tc.pm @@ -178,8 +178,7 @@ our %tcclasses; our %restrictions = ( tcpre => PREROUTE_RESTRICT , tcpost => POSTROUTE_RESTRICT , tcfor => NO_RESTRICT , - tcout => OUTPUT_RESTRICT , - sticky => PREROUTE_RESTRICT ); + tcout => OUTPUT_RESTRICT ); our $family; @@ -287,8 +286,8 @@ sub process_tc_rule( $$$$$$$$$$$$ ) { } if ( $target eq 'sticky ' ) { - $target = 'RETURN'; - $chain = 'sticky'; + fatal_error "SAME rules are only allowed in the PREROUTING chain" if $chain ne 'tcpre'; + $sticky++; } if ( $rest ) { @@ -921,7 +920,6 @@ sub setup_tc() { if ( $capabilities{MANGLE_ENABLED} && $config{MANGLE_ENABLED} ) { ensure_mangle_chain 'tcpre'; ensure_mangle_chain 'tcout'; - new_chain 'mangle', 'sticky'; if ( $capabilities{MANGLE_FORWARD} ) { ensure_mangle_chain 'tcfor'; @@ -985,9 +983,7 @@ sub setup_tc() { add_rule ensure_chain( 'mangle' , 'tcpost' ), $_; } - if ( $mangle_table->{sticky}{referenced} ) { - handle_stickiness; - } + handle_stickiness if $sticky; } 1;