diff --git a/Shorewall-perl/Shorewall/Chains.pm b/Shorewall-perl/Shorewall/Chains.pm index 2db7678bf..0c64bd4d6 100644 --- a/Shorewall-perl/Shorewall/Chains.pm +++ b/Shorewall-perl/Shorewall/Chains.pm @@ -125,6 +125,7 @@ our %EXPORT_TAGS = ( get_interface_address get_interface_addresses get_interface_bcasts + get_interface_mac set_global_variables create_netfilter_load create_chainlist_reload @@ -219,6 +220,7 @@ our %interfaceaddr; our %interfaceaddrs; our %interfacenets; our %interfacebcasts; +our %interfacemacs; our @builtins = qw(PREROUTING INPUT FORWARD OUTPUT POSTROUTING); @@ -318,6 +320,7 @@ sub initialize() { %interfaceaddrs = (); %interfacenets = (); %interfacebcasts = (); + %interfacemacs = (); } INIT { @@ -1559,6 +1562,27 @@ sub get_interface_nets ( $ ) { } +# +# Returns the name of the shell variable holding the MAC address of the gateway for the passed provider out of the passed interface +# +sub interface_mac( $$ ) { + my $variable = join( '_' , chain_base( $_[0] ) , $_[1] , 'mac' ); + uc $variable; +} + +# +# Emit code to determine the MAC address of the passed gateway IP routed out of the passed interface for the passed provider number +# +sub get_interface_mac( $$$ ) { + my ( $ipaddr, $interface , $table ) = @_; + + my $variable = interface_mac( $interface , $table ); + + emit qq($variable=\$(find_mac $ipaddr $interface)); + + "\$$variable"; +} + # # This function provides a uniform way to generate rules (something the original Shorewall sorely needed). # diff --git a/Shorewall-perl/Shorewall/Providers.pm b/Shorewall-perl/Shorewall/Providers.pm index d6d3fc733..c74ae3e8c 100644 --- a/Shorewall-perl/Shorewall/Providers.pm +++ b/Shorewall-perl/Shorewall/Providers.pm @@ -54,7 +54,6 @@ our %providers; our @providers; -our $maccount; # # Initialize globals -- we take this novel approach to globals initialization to allow @@ -70,7 +69,6 @@ sub initialize() { %routemarked_interfaces = (); @routemarked_interfaces = (); $balance = 0; - $maccount = 0; $first_default_route = 1; %providers = ( 'local' => { number => LOCAL_NUMBER , mark => 0 , optional => 0 } , @@ -111,7 +109,7 @@ sub setup_route_marking() { if ( $providerref->{shared} ) { my $provider = $providerref->{provider}; add_command( $chainref, qq(if [ -n "${provider}_is_up" ]; then) ), incr_cmd_level( $chainref ) if $providerref->{optional}; - add_rule $chainref, " -m mac --mac-source $providerref->{mac} -j MARK --set-mark $providerref->{mark}"; + add_rule $chainref, " -i $interface -m mac --mac-source $providerref->{mac} -j MARK --set-mark $providerref->{mark}"; decr_cmd_level( $chainref), add_command( $chainref, "fi" ) if $providerref->{optional}; } else { add_rule $chainref, " -i $interface -j MARK --set-mark $providerref->{mark}"; @@ -290,12 +288,8 @@ sub add_a_provider( $$$$$$$$ ) { if ( $shared ) { fatal_error "The 'shared' option requires a gateway" unless $gateway; - my $variable = uc( "${interface}_MAC_" . ++$maccount ); + $providers{$table}{mac} = get_interface_mac( $gateway, $interface , $table ); - emit "$variable=\$(find_mac $gateway $interface)\n"; - - $providers{$table}{mac} = "\$$variable"; - $realm = "realm $number"; }