diff --git a/Shorewall-common/changelog.txt b/Shorewall-common/changelog.txt index ac1c11c66..a6011f883 100644 --- a/Shorewall-common/changelog.txt +++ b/Shorewall-common/changelog.txt @@ -12,6 +12,9 @@ Changes in 4.1.5 6) Fix designator table in Tc.pm. +7) Generate an error when mac match is used in the POSTROUTING or + OUTPUT chains. + Changes in 4.1.4 1) Fix do_test() to accept 0 and to use the same mask as diff --git a/Shorewall-common/releasenotes.txt b/Shorewall-common/releasenotes.txt index fa505ccfe..35e8f9451 100644 --- a/Shorewall-common/releasenotes.txt +++ b/Shorewall-common/releasenotes.txt @@ -108,6 +108,9 @@ New Features in 4.1.5. 3) The /usr/share/shorewall/modules file has been updated to reflect module renaming in kernel 2.6.25. +4) Shorewall-perl now generates an error when a MAC address appears in + a traffic shaping rule in the OUTPUT or POSTROUTING chains. + New Features in Shorewall 4.1. 1) Shorewall 4.1 contains experimental support for multiple Internet diff --git a/Shorewall-perl/Shorewall/Chains.pm b/Shorewall-perl/Shorewall/Chains.pm index 6a1a03db5..4e3360fe4 100644 --- a/Shorewall-perl/Shorewall/Chains.pm +++ b/Shorewall-perl/Shorewall/Chains.pm @@ -1284,8 +1284,10 @@ sub get_set_flags( $$ ) { # # Match a Source. Handles IP addresses and ranges and MAC addresses # -sub match_source_net( $ ) { - my $net = $_[0]; +sub match_source_net( $;$ ) { + my ( $net, $restriction) = @_; + + $restriction |= NO_RESTRICT; if ( $net =~ /^(!?)(\d+\.\d+\.\d+\.\d+)-(\d+\.\d+\.\d+\.\d+)$/ ) { my ($addr1, $addr2) = ( $2, $3 ); @@ -1295,6 +1297,7 @@ sub match_source_net( $ ) { } elsif ( $net =~ /^(!?)~(.*)$/ ) { ( $net = $2 ) =~ tr/-/:/; my $invert = $1 ? '! ' : ''; + fatal_error "MAC address cannot be used in this context" if $restriction >= OUTPUT_RESTRICT; "-m mac --mac-source ${invert}$net "; } elsif ( $net =~ /^(!?)\+/ ) { require_capability( 'IPSET_MATCH' , 'ipset names in Shorewall configuration files' , '' ); @@ -1904,7 +1907,7 @@ sub expand_rule( $$$$$$$$$$ ) unless ( $inets || ( $iiface && $restriction & POSTROUTE_RESTRICT ) ) { my @iexcl = mysplit $iexcl; if ( @iexcl == 1 ) { - $rule .= match_source_net "!$iexcl"; + $rule .= match_source_net "!$iexcl" , $restriction; $iexcl = ''; } @@ -1962,7 +1965,7 @@ sub expand_rule( $$$$$$$$$$ ) # # We evaluate the source net match in the inner loop to accomodate systems without $capabilities{KLUDGEFREE} # - add_rule( $chainref, join( '', $rule, match_source_net( $inet), match_dest_net( $dnet ), $onet, "-j $echain" ), 1 ); + add_rule( $chainref, join( '', $rule, match_source_net( $inet, $restriction ), match_dest_net( $dnet ), $onet, "-j $echain" ), 1 ); } } } @@ -1975,7 +1978,7 @@ sub expand_rule( $$$$$$$$$$ ) # # Generate RETURNs for each exclusion # - add_rule $echainref, ( match_source_net $_ ) . '-j RETURN' for ( mysplit $iexcl ); + add_rule $echainref, ( match_source_net $_ , $restriction ) . '-j RETURN' for ( mysplit $iexcl ); add_rule $echainref, ( match_dest_net $_ ) . '-j RETURN' for ( mysplit $dexcl ); add_rule $echainref, ( match_orig_dest $_ ) . '-j RETURN' for ( mysplit $oexcl ); # @@ -2006,13 +2009,13 @@ sub expand_rule( $$$$$$$$$$ ) '' , $logtag , 'add' , - join( '', $rule, match_source_net( $inet) , match_dest_net( $dnet ), $onet ); + join( '', $rule, match_source_net( $inet , $restriction ) , match_dest_net( $dnet ), $onet ); } unless ( $disposition eq 'LOG' ) { add_rule( $chainref, - join( '', $rule, match_source_net ($inet), match_dest_net( $dnet ), $onet, $target ) , + join( '', $rule, match_source_net ($inet , $restriction ), match_dest_net( $dnet ), $onet, $target ) , 1 ); } } diff --git a/Shorewall-perl/Shorewall/Rules.pm b/Shorewall-perl/Shorewall/Rules.pm index 4e205d712..2d9b8e9c6 100644 --- a/Shorewall-perl/Shorewall/Rules.pm +++ b/Shorewall-perl/Shorewall/Rules.pm @@ -503,8 +503,7 @@ sub add_common_rules() { add_rule_pair new_standard_chain( 'logreject' ), ' ' , 'reject' , $level ; for $interface ( all_interfaces ) { - ensure_chain( 'filter', $_ ) for first_chains( $interface ); - ensure_chain( 'filter', output_chain( $interface ) ); + ensure_chain( 'filter', $_ ) for first_chains( $interface ), output_chain( $interface ); } run_user_exit1 'initdone';