diff --git a/Shorewall-perl/Shorewall/Chains.pm b/Shorewall-perl/Shorewall/Chains.pm index 5389f9e47..a57f3f4db 100644 --- a/Shorewall-perl/Shorewall/Chains.pm +++ b/Shorewall-perl/Shorewall/Chains.pm @@ -68,6 +68,7 @@ our %EXPORT_TAGS = ( add_command add_commands + move_rules process_comment no_comment clear_comment @@ -492,6 +493,25 @@ sub insert_rule($$$) } +# +# Move the rules from one chain to another +# +sub move_rules( $$ ) { + my ($chain1, $chain2 ) = @_; + + if ( $chain1->{referenced} ) { + my @rules = @{$chain1->{rules}}; + + s/ $chain1->{name} / $chain2->{name} / for @rules; + + splice @{$chain2->{rules}}, 0, 0, @rules; + + $chain2->{referenced} = 1; + $chain1->{referenced} = 0; + $chain1->{rules} = []; + } +} + # # Form the name of a chain. # @@ -528,12 +548,11 @@ sub zone_forward_chain($) { # sub use_forward_chain($) { my $interface = $_[0]; - my $chainref = $filter_table->{forward_chain($interface)}; my $interfaceref = find_interface($interface); # - # We must use the interfaces's chain if it is referenced (has rules in it) or if the interface is associated with multiple zone nets + # We must use the interfaces's chain if the interface is associated with multiple zone nets # - $interfaceref->{nets} != 1 || $chainref->{referenced}; + $interfaceref->{nets} != 1; } # @@ -556,20 +575,19 @@ sub zone_input_chain($) { # sub use_input_chain($) { my $interface = $_[0]; - my $chainref = $filter_table->{input_chain($interface)}; my $interfaceref = find_interface($interface); # - # We must use the interfaces's chain if it is referenced (has rules in it) or if the interface is associated with multiple zone nets + # We must use the interfaces's chain if the interface is associated with multiple zone nets # - return 1 if $interfaceref->{nets} != 1 || $chainref->{referenced}; + return 1 if $interfaceref->{nets} != 1; - my $chainref1 = $filter_table->{zone_input_chain $interfaceref->{zone}}; + my $chainref = $filter_table->{zone_input_chain $interfaceref->{zone}}; - return 1 if $chainref1; + return 1 if $chainref; - $chainref1 = $filter_table->{join( '' , $interfaceref->{zone} , '2' , firewall_zone )}; + $chainref = $filter_table->{join( '' , $interfaceref->{zone} , '2' , firewall_zone )}; - ! $chainref1->{referenced}; + ! $chainref->{referenced}; } # @@ -592,20 +610,19 @@ sub zone_output_chain($) { # sub use_output_chain($) { my $interface = $_[0]; - my $chainref = $filter_table->{output_chain($interface)}; my $interfaceref = find_interface($interface); # - # We must use the interfaces's chain if it is referenced (has rules in it) or if the interface is associated with multiple zone nets + # We must use the interfaces's chain if the interface is associated with multiple zone nets # - return 1 if $interfaceref->{nets} != 1 || $chainref->{referenced}; + return 1 if $interfaceref->{nets} != 1; - my $chainref1 = $filter_table->{zone_output_chain $interfaceref->{zone}}; + my $chainref = $filter_table->{zone_output_chain $interfaceref->{zone}}; - return 1 if $chainref1; + return 1 if $chainref; - $chainref1 = $filter_table->{join( '', firewall_zone , '2', $interfaceref->{zone} )}; + $chainref = $filter_table->{join( '', firewall_zone , '2', $interfaceref->{zone} )}; - ! $chainref1->{referenced}; + ! $chainref->{referenced}; } # diff --git a/Shorewall-perl/Shorewall/Rules.pm b/Shorewall-perl/Shorewall/Rules.pm index 2564ef268..ae4248ecd 100644 --- a/Shorewall-perl/Shorewall/Rules.pm +++ b/Shorewall-perl/Shorewall/Rules.pm @@ -1556,6 +1556,7 @@ sub generate_matrix() { } else { $sourcechainref = $filter_table->{FORWARD}; $interfacematch = match_source_dev $interface; + move_rules( $filter_table->{forward_chain $interface} , $frwd_ref ); } my $arrayref = $source_ref->{$interface}; @@ -1668,6 +1669,8 @@ sub generate_matrix() { add_rule( $outputref , join('', $interfacematch, '-d 255.255.255.255 ' , $ipsec_out_match, "-j $nextchain" ) ) if $hostref->{options}{broadcast}; + + move_rules( $filter_table->{output_chain $interface} , $filter_table->{$nextchain} ) unless use_output_chain $interface; } next if $hostref->{options}{destonly}; @@ -1698,13 +1701,19 @@ sub generate_matrix() { } if ( $chain2 ) { + my $nextchain; + if ( @$exclusions ) { my $input = zone_input_chain $zone; add_rule $inputchainref, join( '', $interfacematch, $source, $ipsec_in_match, "-j $input" ); add_rule $filter_table->{ $input } , "-j $chain2"; + $nextchain = $input; } else { add_rule $inputchainref, join( '', $interfacematch, $source, $ipsec_in_match, "-j $chain2" ); + $nextchain = $chain2; } + + move_rules( $filter_table->{input_chain $interface} , $filter_table->{$nextchain} ) unless use_input_chain $interface; } if ( $hostref->{ipsec} ne 'ipsec' ) { @@ -1712,6 +1721,7 @@ sub generate_matrix() { add_rule $filter_table->{forward_chain $interface} , join( '', $source, $ipsec_in_match. "-j $frwd_ref->{name}" ); } else { add_rule $filter_table->{FORWARD} , join( '', match_source_dev( $interface ) , $source, $ipsec_in_match. "-j $frwd_ref->{name}" ); + move_rules ( $filter_table->{forward_chain $interface} , $frwd_ref ); } } }