diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index 947ac301b..c83ab7d71 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -2747,11 +2747,13 @@ sub accounting_chainrefs() { grep $_->{accounting} , values %$filter_table; } -sub ensure_mangle_chain($) { - my $chain = $_[0]; +sub ensure_mangle_chain($;$$) { + my ( $chain, $number, $restriction ) = @_; my $chainref = ensure_chain 'mangle', $chain; - $chainref->{referenced} = 1; + $chainref->{referenced} = 1; + $chainref->{chainnumber} = $number if $number; + $chainref->{restriction} = $restriction if $restriction; $chainref; } @@ -8305,7 +8307,7 @@ sub ensure_ipsets( @ ) { if ( $family == F_IPV4 ) { if ( have_capability 'IPSET_V5' ) { emit ( qq( if ! qt \$IPSET list $set -n; then) , - qq( error_message "WARNING: ipset $set does not exist; creating it as an hash:net set") , + qq( error_message "WARNING: ipset $set does not exist; creating it as a hash:net set") , qq( \$IPSET create $set hash:net family inet timeout 0${counters}) , qq( fi) ); } else { @@ -8316,7 +8318,7 @@ sub ensure_ipsets( @ ) { } } else { emit ( qq( if ! qt \$IPSET list $set -n; then) , - qq( error_message "WARNING: ipset $set does not exist; creating it as an hash:net set") , + qq( error_message "WARNING: ipset $set does not exist; creating it as a hash:net set") , qq( \$IPSET create $set hash:net family inet6 timeout 0${counters}) , qq( fi) ); } diff --git a/Shorewall/Perl/Shorewall/Rules.pm b/Shorewall/Perl/Shorewall/Rules.pm index e118d94d1..dad0c7c10 100644 --- a/Shorewall/Perl/Shorewall/Rules.pm +++ b/Shorewall/Perl/Shorewall/Rules.pm @@ -4183,11 +4183,13 @@ sub process_mangle_rule1( $$$$$$$$$$$$$$$$$$ ) { my $chainref = ensure_chain( 'mangle', $chain = $chainnames{$chain} ); + $restriction |= $chainref->{restriction}; + for ( my $packet = 0; $packet < $marks; $packet++, $markval += $increment ) { my $match = "-m statistic --mode nth --every $marks --packet $packet "; expand_rule( $chainref, - $restrictions{$chain} | $restriction, + $restriction, $prerule , $match . do_user( $user ) . @@ -4930,8 +4932,10 @@ sub process_mangle_rule1( $$$$$$$$$$$$$$$$$$ ) { $chainref = ensure_chain( 'mangle', $chainnames{$chain} ); } + $restriction |= $chainref->{restriction}; + if ( ( my $result = expand_rule( $chainref , - ( $restrictions{$chain} || 0 ) | $restriction, + $restriction, $prerule, do_proto( $proto, $ports, $sports) . $matches . do_user( $user ) . diff --git a/Shorewall/Perl/Shorewall/Tc.pm b/Shorewall/Perl/Shorewall/Tc.pm index f87d7f740..a4fae1bd3 100644 --- a/Shorewall/Perl/Shorewall/Tc.pm +++ b/Shorewall/Perl/Shorewall/Tc.pm @@ -827,7 +827,7 @@ sub validate_tc_class( ) { fatal_error "Invalid 'occurs' ($val)" unless defined $occurs && $occurs > 1 && $occurs <= 256; fatal_error "Invalid 'occurs' ($val)" if $occurs > $globals{TC_MAX}; fatal_error q(Duplicate 'occurs') if $tcref->{occurs} > 1; - fatal_error q(The 'occurs' option is not valid with 'default') if $devref->{default} == $classnumber; + fatal_error q(The 'occurs' option is not valid with 'default') if defined($devref->{default}) && $devref->{default} == $classnumber; fatal_error q(The 'occurs' option is not valid with 'tos') if @{$tcref->{tos}}; warning_message "MARK ($mark) is ignored on an occurring class" if $mark ne '-'; @@ -1308,6 +1308,8 @@ sub handle_ematch( $$ ) { $setname =~ s/\+//; + add_ipset($setname); + return "ipset\\($setname $options\\)"; } @@ -1518,7 +1520,7 @@ sub process_tc_filter2( $$$$$$$$$ ) { $rule .= ' and' if $have_rule; if ( $source =~ /^\+/ ) { - $rule = join( '', "\\\n ", handle_ematch( $source, 'src' ) ); + $rule .= join( '', "\\\n ", handle_ematch( $source, 'src' ) ); } else { my @parts = decompose_net_u32( $source ); @@ -1557,9 +1559,9 @@ sub process_tc_filter2( $$$$$$$$$ ) { $rule .= ' and' if @parts; } } - - $have_rule = 1; } + + $have_rule = 1; } if ( $have_rule ) { @@ -2276,13 +2278,13 @@ sub setup_tc( $ ) { $convert = $_[0]; if ( $config{MANGLE_ENABLED} ) { - ensure_mangle_chain 'tcpre'; - ensure_mangle_chain 'tcout'; + ensure_mangle_chain( 'tcpre', PREROUTING, PREROUTE_RESTRICT ); + ensure_mangle_chain( 'tcout', OUTPUT , OUTPUT_RESTRICT ); if ( have_capability( 'MANGLE_FORWARD' ) ) { - ensure_mangle_chain 'tcfor'; - ensure_mangle_chain 'tcpost'; - ensure_mangle_chain 'tcin'; + ensure_mangle_chain( 'tcfor', FORWARD , NO_RESTRICT ); + ensure_mangle_chain( 'tcpost', POSTROUTING, POSTROUTE_RESTRICT ); + ensure_mangle_chain( 'tcin', INPUT , INPUT_RESTRICT ); } my @mark_part;