diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index baa10ee9e..d0e8a9a66 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -213,6 +213,7 @@ our $VERSION = '4.4_13'; # ] # logchains => { = , ... } # references => { => , => , ... } +# frozen => # } , # => ... # } @@ -695,6 +696,8 @@ sub move_rules( $$ ) { my $rules = $chain2->{rules}; my $count = @{$chain1->{rules}}; my $tableref = $chain_table{$chain1->{table}}; + my @frozen = (); + my $frozen = $chain2->{frozen} || 0; # # We allow '+' in chain names and '+' is an RE meta-character. Escape it. # @@ -703,13 +706,22 @@ sub move_rules( $$ ) { for ( @{$chain1->{rules}} ) { adjust_reference_counts( $tableref->{$1}, $name1, $name2 ) if / -[jg] ([^\s]+)/; } + # + # Get the frozen rules out of the way for the moment + # + $chain2->{frozen} += $chain1->{frozen}; + unshift @frozen, shift @$rules while $frozen--; if ( $debug ) { my $rule = @{$chain1->{rules}}; trace( $chain2, 'A', ++$rule, $_ ) for @{$chain1->{rules}}; } - unshift @{$rules}, @{$chain1->{rules}}; + unshift @$rules, @{$chain1->{rules}}; + # + # Now re-add the frozen rules at the front + # + unshift @$rules, @frozen; # # In a firewall->x policy chain, multiple DHCP ACCEPT rules can be moved to the head of the chain. # This hack avoids that. @@ -1028,8 +1040,8 @@ sub ensure_chain($$) # optional 5th argument causes long port lists to be split. The optional 6th # argument, if passed, gives the 0-relative index where the jump is to be inserted. # -sub add_jump( $$$;$$$ ) { - my ( $fromref, $to, $goto_ok, $predicate, $expandports, $index ) = @_; +sub add_jump( $$$;$$$$ ) { + my ( $fromref, $to, $goto_ok, $predicate, $expandports, $index, $freeze ) = @_; $predicate |= ''; @@ -1062,6 +1074,8 @@ sub add_jump( $$$;$$$ ) { } else { add_rule ($fromref, join( '', $predicate, "-$param $to" ), $expandports || 0 ); } + + $fromref->{frozen}++ if $freeze; } # diff --git a/Shorewall/Perl/Shorewall/Rules.pm b/Shorewall/Perl/Shorewall/Rules.pm index 4e660f652..4c5fdcc60 100644 --- a/Shorewall/Perl/Shorewall/Rules.pm +++ b/Shorewall/Perl/Shorewall/Rules.pm @@ -1874,16 +1874,21 @@ sub generate_matrix() { if ( $zoneref->{options}{in}{blacklist} ) { my $blackref = $filter_table->{blacklst}; - add_jump $frwd_ref , $blackref, 0, $state; - add_jump ensure_filter_chain( rules_chain( $zone, firewall_zone ), 1 ) , $blackref , 0, $state, 0, 0; + add_jump $frwd_ref , $blackref, 0, $state, 0, undef, 1; + add_jump ensure_filter_chain( rules_chain( $zone, firewall_zone ), 1 ) , $blackref , 0, $state, 0, 0, 1; } if ( $zoneref->{options}{out}{blacklist} ) { my $blackref = $filter_table->{blackout}; - add_jump ensure_filter_chain( rules_chain( firewall_zone, $zone ), 1 ) , $blackref , 0, $state, 0, 0; + add_jump ensure_filter_chain( rules_chain( firewall_zone, $zone ), 1 ) , $blackref , 0, $state, 0, 0, 1; for my $zone1 ( @zones ) { - add_jump( ensure_filter_chain( rules_chain( $zone1, $zone ), 1 ), $blackref, 0, $state, 0, 0 ) unless $zone eq $zone1; + my $ruleschain = rules_chain( $zone1, $zone ); + my $ruleschainref = $filter_table->{$ruleschain}; + + if ( $zone ne $zone1 || ( $ruleschainref && $ruleschainref->{referenced} ) ) { + add_jump( ensure_filter_chain( $ruleschain, 1 ), $blackref, 0, $state, 0, 0 , 1 ); + } } } @@ -2382,33 +2387,38 @@ EOF $output->{policy} = 'ACCEPT' if $config{ADMINISABSENTMINDED}; if ( $family == F_IPV4 ) { - emit( ' deletechain() {', - ' qt $IPTABLES -L $1 -n && qt $IPTABLES -F $1 && qt $IPTABLES -X $1' ); - } else { - emit( ' deletechain() {', - ' qt $IP6TABLES -L $1 -n && qt $IP6TABLES -F $1 && qt $IP6TABLES -X $1' ); - } - - emit <<'EOF'; + emit <<'EOF'; + deletechain() { + qt $IPTABLES -L $1 -n && qt $IPTABLES -F $1 && qt $IPTABLES -X $1 } case $COMMAND in - stop|clear|restore) + stop|clear|restore) if chain_exists dynamic; then + ${IPTABLES}-save -t filter | grep '^-A dynamic' > ${VARDIR}/.dynamic + fi + ;; + *) + set +x EOF - - if ( $family == F_IPV4 ) { - emit( ' ${IPTABLES}-save -t filter | grep \'^-A dynamic\' > ${VARDIR}/.dynamic' ); } else { - emit( ' ${IP6TABLES}-save -t filter | grep \'^-A dynamic\' > ${VARDIR}/.dynamic' ); + emit <<'EOF'; + deletechain() { + qt $IPTABLES -L $1 -n && qt $IPTABLES -F $1 && qt $IPTABLES -X $1 + } + + case $COMMAND in + stop|clear|restore) + if chain_exists dynamic; then + ${IP6TABLES}-save -t filter | grep '^-A dynamic' > ${VARDIR}/.dynamic + fi + ;; + *) + set +x +EOF } emit <<'EOF'; - fi - ;; - *) - set +x - case $COMMAND in start) logger -p kern.err "ERROR:$g_product start failed" diff --git a/Shorewall/Perl/Shorewall/Zones.pm b/Shorewall/Perl/Shorewall/Zones.pm index 5f4779070..f870d9752 100644 --- a/Shorewall/Perl/Shorewall/Zones.pm +++ b/Shorewall/Perl/Shorewall/Zones.pm @@ -231,7 +231,7 @@ sub initialize( $ ) { if ( $family == F_IPV4 ) { %validinterfaceoptions = (arp_filter => BINARY_IF_OPTION, arp_ignore => ENUM_IF_OPTION, - blacklist => SIMPLE_IF_OPTION, + blacklist => SIMPLE_IF_OPTION + IF_OPTION_HOST, bridge => SIMPLE_IF_OPTION, detectnets => OBSOLETE_IF_OPTION, dhcp => SIMPLE_IF_OPTION, @@ -264,7 +264,7 @@ sub initialize( $ ) { sourceonly => 1, ); } else { - %validinterfaceoptions = ( blacklist => SIMPLE_IF_OPTION, + %validinterfaceoptions = ( blacklist => SIMPLE_IF_OPTION + IF_OPTION_HOST, bridge => SIMPLE_IF_OPTION, dhcp => SIMPLE_IF_OPTION, maclist => SIMPLE_IF_OPTION + IF_OPTION_HOST, diff --git a/Shorewall/releasenotes.txt b/Shorewall/releasenotes.txt index 48640c8f3..86d571db6 100644 --- a/Shorewall/releasenotes.txt +++ b/Shorewall/releasenotes.txt @@ -224,12 +224,6 @@ VI. PROBLEMS CORRECTED AND NEW FEATURES IN PRIOR RELEASES to be supported for several releases. A warning will be added at least one release before support is removed. - g) Given that blacklisting is now zone-based, there is a slight - change in behavior. Previously, blacklisting was done before - the other interface-oriented checks (tcpflags, nosmurfs, dhcp, - etc.). Beginning with this release, blacklisting is performed - after these checks. - 5) There is now an OUT-BANDWIDTH column in /etc/shorewall/tcinterfaces.