diff --git a/Shorewall-common/changelog.txt b/Shorewall-common/changelog.txt index f493ef841..64e4ceb8e 100644 --- a/Shorewall-common/changelog.txt +++ b/Shorewall-common/changelog.txt @@ -10,6 +10,8 @@ Changes in 4.0.1 5) Correct handling of ECN with MANGLE_FORWARD. +6) Relax ADDRTYPE restriction. + Changes in 4.0.0 Final 1) Fix lite install.sh manpage problem. diff --git a/Shorewall-common/lib.base b/Shorewall-common/lib.base index 6bf92ae83..c9c78c3e3 100644 --- a/Shorewall-common/lib.base +++ b/Shorewall-common/lib.base @@ -857,11 +857,9 @@ get_routed_networks() # $1 = interface name, $2-n = Fatal error message get_interface_bcasts() # $1 = interface { - local addresses= - ip -f inet addr show dev $1 2> /dev/null | grep 'inet.*brd' | sed 's/inet.*brd //; s/scope.*//;' | sort -u } - + # # Internal version of 'which' # diff --git a/Shorewall-common/releasenotes.txt b/Shorewall-common/releasenotes.txt index ce16f551e..3bc6e74a0 100644 --- a/Shorewall-common/releasenotes.txt +++ b/Shorewall-common/releasenotes.txt @@ -92,6 +92,10 @@ Other changes in Shorewall 4.0.1. zone and 'b' is the DEST zone. See http://linuxman.wikispaces.com/PPPPPPS for more information. +2) The Shorewall-perl dependency on the "Address Type Match" + capability has been relaxed. This allows Shorewall 4.0.1 to be used + on releases like RHEL4 that con's support that capability. + Migration Considerations: 1) Beginning with Shorewall 4.0.0, there is no single 'shorewall' diff --git a/Shorewall-perl/Shorewall/Actions.pm b/Shorewall-perl/Shorewall/Actions.pm index a8d962f0c..59e113657 100644 --- a/Shorewall-perl/Shorewall/Actions.pm +++ b/Shorewall-perl/Shorewall/Actions.pm @@ -656,25 +656,48 @@ sub process_actions3 () { sub dropBcast( $$$ ) { my ($chainref, $level, $tag) = @_; - if ( $level ) { - log_rule_limit $level, $chainref, 'dropBcast' , 'DROP', '', $tag, 'add', ' -m addrtype --dst-type BROADCAST'; - log_rule_limit $level, $chainref, 'dropBcast' , 'DROP', '', $tag, 'add', ' -d 224.0.0.0/4'; - } + if ( $capabilities{ADDRTYPE} ) { + if ( $level ) { + log_rule_limit $level, $chainref, 'dropBcast' , 'DROP', '', $tag, 'add', ' -m addrtype --dst-type BROADCAST'; + log_rule_limit $level, $chainref, 'dropBcast' , 'DROP', '', $tag, 'add', ' -d 224.0.0.0/4'; + } + + add_rule $chainref, '-m addrtype --dst-type BROADCAST -j DROP'; + } else { + add_command $chainref, 'for address in $ALL_BCASTS; do'; + push_cmd_mode $chainref; + log_rule_limit $level, $chainref, 'dropBcast' , 'DROP', '', $tag, 'add', ' -d $address' if $level; + add_rule $chainref, '-d $address -j DROP'; + pop_cmd_mode $chainref; + add_command $chainref, 'done'; + + log_rule_limit $level, $chainref, 'dropBcast' , 'DROP', '', $tag, 'add', ' -d 224.0.0.0/4' if $level; + } - add_rule $chainref, '-m addrtype --dst-type BROADCAST -j DROP'; add_rule $chainref, '-d 224.0.0.0/4 -j DROP'; } sub allowBcast( $$$ ) { my ($chainref, $level, $tag) = @_; - if ( $level ) { - log_rule_limit $level, $chainref, 'allowBcast' , 'ACCEPT', '', $tag, 'add', ' -m addrtype --dst-type BROADCAST'; - log_rule_limit $level, $chainref, 'allowBcast' , 'ACCEPT', '', $tag, 'add', ' -d 224.0.0.0/4'; - } + if ( $capabilities{ADDRTYPE} ) { + if ( $level ) { + log_rule_limit $level, $chainref, 'allowBcast' , 'ACCEPT', '', $tag, 'add', ' -m addrtype --dst-type BROADCAST'; + log_rule_limit $level, $chainref, 'allowBcast' , 'ACCEPT', '', $tag, 'add', ' -d 224.0.0.0/4'; + } - add_rule $chainref, '-m addrtype --dst-type BROADCAST -j ACCEPT'; - add_rule $chainref, '-d 224.0.0.0/4 -j ACCEPT'; + add_rule $chainref, '-m addrtype --dst-type BROADCAST -j ACCEPT'; + } else { + add_command $chainref, 'for address in $ALL_BCASTS; do'; + push_cmd_mode $chainref; + log_rule_limit $level, $chainref, 'allowBcast' , 'ACCEPT', '', $tag, 'add', ' -d $address' if $level; + add_rule $chainref, '-d $address -j ACCEPT'; + pop_cmd_mode $chainref; + add_command $chainref, 'done'; + + log_rule_limit $level, $chainref, 'allowBcast' , 'ACCEPT', '', $tag, 'add', ' -d 224.0.0.0/4' if $level; + } + add_rule $chainref, '-d 224.0.0.0/4 -j ACCEPT'; } sub dropNotSyn ( $$$ ) { diff --git a/Shorewall-perl/Shorewall/Chains.pm b/Shorewall-perl/Shorewall/Chains.pm index 31e8feda2..b1b33b6fa 100644 --- a/Shorewall-perl/Shorewall/Chains.pm +++ b/Shorewall-perl/Shorewall/Chains.pm @@ -112,6 +112,7 @@ our @EXPORT = qw( STANDARD insertnatjump get_interface_address get_interface_addresses + get_interface_bcasts set_global_variables create_netfilter_load create_blacklist_reload @@ -207,6 +208,7 @@ our $chainseq; our %interfaceaddr; our %interfaceaddrs; our %interfacenets; +our %interfacebcasts; our @builtins = qw(PREROUTING INPUT FORWARD OUTPUT POSTROUTING); @@ -302,9 +304,10 @@ sub initialize() { # # Keep track of which interfaces have active 'address', 'addresses' and 'networks' variables # - %interfaceaddr = (); - %interfaceaddrs = (); - %interfacenets = (); + %interfaceaddr = (); + %interfaceaddrs = (); + %interfacenets = (); + %interfacebcasts = (); # # When true, we've emitted a comment about global variable initialization # @@ -1378,6 +1381,26 @@ sub get_interface_address ( $ ) { "\$$variable"; } +# +# Returns the name of the shell variable holding the broadcast addresses of the passed interface +# +sub interface_bcasts( $ ) { + chain_base( $_[0] ) . '_bcasts'; +} + +# +# Record that the ruleset requires the broadcast addresses on the passed interface +# +sub get_interface_bcasts ( $ ) { + my ( $interface ) = $_[0]; + + my $variable = interface_bcasts( $interface ); + + $interfacebcasts{$interface} = qq($variable="\$(get_interface_bcasts $interface) 255.255.255.255"); + + "\$$variable"; +} + # # Returns the name of the shell variable holding the addresses of the passed interface # @@ -1847,6 +1870,14 @@ sub set_global_variables() { emit $_; } + unless ( $capabilities{ADDRTYPE} ) { + emit_comment; + emit 'ALL_BCASTS="255.255.255.255 $(get_all_bcasts)"'; + + for ( values %interfacebcasts ) { + emit $_; + } + } } # diff --git a/Shorewall-perl/Shorewall/Compiler.pm b/Shorewall-perl/Shorewall/Compiler.pm index 04da4ddda..9ec0951e8 100644 --- a/Shorewall-perl/Shorewall/Compiler.pm +++ b/Shorewall-perl/Shorewall/Compiler.pm @@ -706,7 +706,6 @@ sub compiler( $$$$ ) { report_capabilities if $verbose > 1; require_capability( 'MULTIPORT' , "Shorewall-perl $globals{VERSION}" , 's' ); - require_capability( 'ADDRTYPE' , "Shorewall-perl $globals{VERSION}" , 's' ); require_capability( 'RECENT_MATCH' , 'MACLIST_TTL' , 's' ) if $config{MACLIST_TTL}; require_capability( 'XCONNMARK' , 'HIGH_ROUTE_MARKS=Yes' , 's' ) if $config{HIGH_ROUTE_MARKS}; require_capability( 'MANGLE_ENABLED' , 'Traffic Shaping' , 's' ) if $config{TC_ENABLED}; diff --git a/Shorewall-perl/Shorewall/Rules.pm b/Shorewall-perl/Shorewall/Rules.pm index a110117b9..966e24670 100644 --- a/Shorewall-perl/Shorewall/Rules.pm +++ b/Shorewall-perl/Shorewall/Rules.pm @@ -527,13 +527,31 @@ sub add_common_rules() { $list = find_hosts_by_option 'nosmurfs'; $chainref = new_standard_chain 'smurfs'; + + if ( $capabilities{ADDRTYPE} ) { + add_rule $chainref , '-s 0.0.0.0 -j RETURN'; + add_rule_pair $chainref, '-m addrtype --src-type BROADCAST ', 'DROP', $config{SMURF_LOG_LEVEL} ; + } else { + add_command $chainref, 'for address in $ALL_BCASTS; do'; + push_cmd_mode $chainref; + log_rule( $config{SMURF_LOG_LEVEL} , $chainref, 'DROP', '-d $address ' ); + add_rule $chainref, '-d $address -j DROP'; + pop_cmd_mode $chainref; + add_command $chainref, 'done'; + } - add_rule $chainref , '-s 0.0.0.0 -j RETURN'; - - add_rule_pair $chainref, '-m addrtype --src-type BROADCAST ', 'DROP', $config{SMURF_LOG_LEVEL} ; add_rule_pair $chainref, '-s 224.0.0.0/4 ', 'DROP', $config{SMURF_LOG_LEVEL} ; - add_rule $rejectref , '-m addrtype --src-type BROADCAST -j DROP'; + if ( $capabilities{ADDRTYPE} ) { + add_rule $rejectref , '-m addrtype --src-type BROADCAST -j DROP'; + } else { + add_command $rejectref, 'for address in $ALL_BCASTS; do'; + push_cmd_mode $rejectref; + add_rule $rejectref, '-d $address -j DROP'; + pop_cmd_mode $rejectref; + add_command $rejectref, 'done'; + } + add_rule $rejectref , '-s 224.0.0.0/4 -j DROP'; if ( @$list ) { @@ -782,11 +800,24 @@ sub setup_mac_lists( $ ) { if ( $level ne '' || $disposition ne 'ACCEPT' ) { my $variable = get_interface_addresses $interfaces{$interface}{bridge}; - add_commands( $chainref, - "for address in $variable; do", - " echo \"-A $chainref->{name} -s \$address -m addrtype --dst-type BROADCAST -j RETURN\" >&3", - " echo \"-A $chainref->{name} -s \$address -d 224.0.0.0/4 -j RETURN\" >&3", - 'done' ); + + if ( $capabilities{ADDRTYPE} ) { + add_commands( $chainref, + "for address in $variable; do", + " echo \"-A $chainref->{name} -s \$address -m addrtype --dst-type BROADCAST -j RETURN\" >&3", + " echo \"-A $chainref->{name} -s \$address -d 224.0.0.0/4 -j RETURN\" >&3", + 'done' ); + } else { + my $variable1 = get_interface_bcasts $interfaces{$interface}{bridge}; + + add_commands( $chainref, + "for address in $variable; do", + " for address1 in $variable1; do", + " echo \"-A $chainref->{name} -s \$address -d \$address1 -j RETURN\" >&3", + " done", + " echo \"-A $chainref->{name} -s \$address -d 224.0.0.0/4 -j RETURN\" >&3", + 'done' ); + } } run_user_exit2( 'maclog', $chainref ); @@ -1549,7 +1580,19 @@ sub generate_matrix() { if ( $chain1 ) { for my $interface ( keys %needbroadcast ) { - add_rule $filter_table->{output_chain $interface} , "-m addrtype --dst-type BROADCAST -j $chain1"; + if ( $capabilities{ADDRTYPE} ) { + add_rule $filter_table->{output_chain $interface} , "-m addrtype --dst-type BROADCAST -j $chain1"; + } else { + my $variable = get_interface_bcasts $interface; + my $chain = output_chain $interface; + my $chainref = $filter_table->{$chain}; + + add_commands( $chainref, + "for address in $variable; do", + " echo \"-A $chain -d \$address -j $chain1\" >&3", + 'done' ); + } + add_rule $filter_table->{output_chain $interface} , "-d 224.0.0.0/4 -j $chain1"; } } diff --git a/Shorewall-perl/prog.functions b/Shorewall-perl/prog.functions index af71d14ea..faf0d1532 100644 --- a/Shorewall-perl/prog.functions +++ b/Shorewall-perl/prog.functions @@ -162,3 +162,12 @@ get_device_mtu1() # $1 = device fi } + +# +# Get a list of all configured broadcast addresses on the system +# +get_all_bcasts() +{ + ip -f inet addr show 2> /dev/null | grep 'inet.*brd' | sed 's/inet.*brd //; s/scope.*//;' | sort -u +} +