diff --git a/Shorewall/Perl/Shorewall/Accounting.pm b/Shorewall/Perl/Shorewall/Accounting.pm index 3aa7a0bd2..eead516e0 100644 --- a/Shorewall/Perl/Shorewall/Accounting.pm +++ b/Shorewall/Perl/Shorewall/Accounting.pm @@ -108,6 +108,7 @@ sub process_accounting_rule( ) { our $jumpchainref = 0; our %accountingjumps; + my $hasmac; my ($action, $chain, $source, $dest, $proto, $ports, $sports, $user, $mark, $ipsec, $headers ) = split_line1 1, 11, 'Accounting File', $accounting_commands; @@ -210,7 +211,7 @@ sub process_accounting_rule( ) { if ( $source eq 'any' || $source eq 'all' ) { $source = ALLIP; } else { - $restriction |= INPUT_RESTRICT if $source =~ /~/; + fatal_error "MAC addresses not are not allowed in the OUTPUT section" if $hasmac = ( $source =~ /~/ ) && $asection == OUTPUT; } if ( have_bridges && ! $asection ) { @@ -277,10 +278,16 @@ sub process_accounting_rule( ) { $restriction |= $chainref->{restriction}; } + $chainref->{restricted} |= INPUT_RESTRICT if $hasmac; + if ( $jumpchainref ) { - if ( $asection ) { - my $jumprestrict = $jumpchainref->{restriction} || $restriction; - fatal_error "Chain $jumpchainref->{name} contains rules that are incompatible with the $sectionname section" if $jumprestrict && $jumprestrict ne $restriction; + if ( $asection ) { + # + # Check the jump-to chain to be sure that it doesn't contain rules that are incompatible with this section + # + my $jumprestricted = $jumpchainref->{restricted}; + fatal_error "Chain $jumpchainref->{name} contains rules that are incompatible with the $sectionname section" if $jumprestricted && $restriction && $jumprestricted ne $restriction; + $restriction |= $jumpchainref->{restriction}; } $accountingjumps{$jumpchainref->{name}}{$chain} = 1; @@ -288,7 +295,7 @@ sub process_accounting_rule( ) { fatal_error "$chain is not an accounting chain" unless $chainref->{accounting}; - $restriction = $dir eq 'in' ? INPUT_RESTRICT : OUTPUT_RESTRICT if $dir && ! $asection; + $restriction = $dir eq 'in' ? INPUT_RESTRICT : OUTPUT_RESTRICT if $dir; expand_rule $chainref , diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index a7b0efac8..56ed2bd71 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -222,7 +222,8 @@ our $VERSION = '4.4_18'; # references => { => , => , ... } # blacklist => ( 0 or 1 ) # action => -# restrictions => Logical OR of restrictions in this chain. +# restricted => Logical OR of restrictions of rules in this chain. +# restriction => Restrictions on further rules in this chain. # } , # => ... # } @@ -1116,8 +1117,7 @@ sub new_chain($$) log => 1, cmdlevel => 0, references => {}, - blacklist => 0 , - restriction => 0 }; + blacklist => 0 }; trace( $chainref, 'N', undef, '' ) if $debug; @@ -1335,6 +1335,7 @@ sub ensure_accounting_chain( $$$ ) $chainref->{accounting} = 1; $chainref->{referenced} = 1; $chainref->{restriction} = $restriction; + $chainref->{restricted} = NO_RESTRICT; $chainref->{ipsec} = $ipsec; $chainref->{dont_optimize} = 1 unless $config{OPTIMIZE_ACCOUNTING}; @@ -3695,7 +3696,7 @@ sub expand_rule( $$$$$$$$$$;$ ) } } - $chainref->{restriction} |= $restriction; + $chainref->{restricted} |= $restriction; $rule .= match_source_dev( $iiface ); } } @@ -3794,7 +3795,7 @@ sub expand_rule( $$$$$$$$$$;$ ) fatal_error "Source interface ($iiface) is not a port on the same bridge as the destination interface ( $diface )" if $bridge && $bridge ne source_port_to_bridge( $iiface ); } - $chainref->{restriction} |= $restriction; + $chainref->{restricted} |= $restriction; $rule .= match_dest_dev( $diface ); } } else {