From 2ed523101c30698d6389902ec8edf69340284582 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Sun, 6 Jul 2014 09:54:53 -0700 Subject: [PATCH] Allow specification of the MAC address of a gateway Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Chains.pm | 17 +++++++++++------ Shorewall/Perl/Shorewall/Providers.pm | 19 ++++++++++++++++--- Shorewall/manpages/shorewall-providers.xml | 8 ++++++-- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index 96abf219d..b4acfa258 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -6723,20 +6723,25 @@ sub interface_mac( $$ ) { # # Record the fact that the ruleset requires MAC address of the passed gateway IP routed out of the passed interface for the passed provider number # -sub get_interface_mac( $$$ ) { - my ( $ipaddr, $logical , $table ) = @_; +sub get_interface_mac( $$$$ ) { + my ( $ipaddr, $logical , $table, $mac ) = @_; my $interface = get_physical( $logical ); my $variable = interface_mac( $interface , $table ); $global_variables |= NOT_RESTORE; - - if ( interface_is_optional $logical ) { - $interfacemacs{$table} = qq($variable=\$(find_mac $ipaddr $interface)\n); + + if ( $mac ) { + $interfacemacs{$table} = qq($variable=$mac); } else { - $interfacemacs{$table} = qq($variable=\$(find_mac $ipaddr $interface) + if ( interface_is_optional $logical ) { + $interfacemacs{$table} = qq($variable=\$(find_mac $ipaddr $interface)\n); + } else { + $interfacemacs{$table} = qq($variable=\$(find_mac $ipaddr $interface) [ -n "\$$variable" ] || startup_error "Unable to determine the MAC address of $ipaddr through interface \\"$interface\\"" ); + + } } "\$$variable"; diff --git a/Shorewall/Perl/Shorewall/Providers.pm b/Shorewall/Perl/Shorewall/Providers.pm index bf32b225c..4ad8d859b 100644 --- a/Shorewall/Perl/Shorewall/Providers.pm +++ b/Shorewall/Perl/Shorewall/Providers.pm @@ -258,7 +258,7 @@ sub copy_and_edit_table( $$$$$ ) { emit ''; if ( $realm ) { - emit ( "\$IP -$family -o route show table $duplicate | sed -r 's/ realm [[:alnum:]]+//' | ${filter}while read net route; do" ) + emit ( "\$IP -$family -o route show table $duplicate | sed -r 's/ realm [[:alnum:]_]+//' | ${filter}while read net route; do" ) } else { emit ( "\$IP -$family -o route show table $duplicate | ${filter}while read net route; do" ) } @@ -442,10 +442,11 @@ sub process_a_provider( $ ) { fatal_error 'INTERFACE must be specified' if $interface eq '-'; - ( $interface, my $address ) = split /:/, $interface; + ( $interface, my $address ) = split /:/, $interface, 2; my $shared = 0; my $noautosrc = 0; + my $mac = ''; if ( defined $address ) { validate_address $address, 0; @@ -469,7 +470,17 @@ sub process_a_provider( $ ) { $gateway = get_interface_gateway $interface; $gatewaycase = 'detect'; } elsif ( $gateway && $gateway ne '-' ) { + ( $gateway, $mac ) = split_host_list( $gateway, 0 ); validate_address $gateway, 0; + + if ( defined $mac ) { + $mac =~ tr/-/:/; + $mac =~ s/^~//; + fatal_error "Invalid MAC address ($mac)" unless $mac =~ /^(?:[0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$/; + } else { + $mac = ''; + } + $gatewaycase = 'specified'; } else { $gatewaycase = 'none'; @@ -644,6 +655,7 @@ sub process_a_provider( $ ) { loose => $loose , duplicate => $duplicate , address => $address , + mac => $mac , local => $local , tproxy => $tproxy , load => $load , @@ -720,6 +732,7 @@ sub add_a_provider( $$ ) { my $loose = $providerref->{loose}; my $duplicate = $providerref->{duplicate}; my $address = $providerref->{address}; + my $mac = $providerref->{mac}; my $local = $providerref->{local}; my $tproxy = $providerref->{tproxy}; my $load = $providerref->{load}; @@ -733,7 +746,7 @@ sub add_a_provider( $$ ) { my $realm = ''; if ( $shared ) { - my $variable = $providers{$table}{mac} = get_interface_mac( $gateway, $interface , $table ); + my $variable = $providers{$table}{mac} = get_interface_mac( $gateway, $interface , $table, $mac ); $realm = "realm $number"; start_provider( $label , $table, $number, $id, qq(if interface_is_usable $physical && [ -n "$variable" ]; then) ); } elsif ( $pseudo ) { diff --git a/Shorewall/manpages/shorewall-providers.xml b/Shorewall/manpages/shorewall-providers.xml index b5df8e756..fb74de032 100644 --- a/Shorewall/manpages/shorewall-providers.xml +++ b/Shorewall/manpages/shorewall-providers.xml @@ -129,11 +129,15 @@ GATEWAY - {-|address|-|address[,mac]|detect} - The IP address of the provider's gateway router. + The IP address of the provider's gateway router. Beginning + with Shorewall 4.6.2, you may also specify the MAC address of the + gateway when there are multiple providers serviced through the same + interface. When the MAC is not specified, Shorewall will detect the + MAC during firewall start or restart. You can enter "detect" here and Shorewall will attempt to detect the gateway automatically.