Verify that interfaces in the providers file are known; unify 'optional' settings

git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@7680 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
teastep 2007-11-17 16:48:25 +00:00
parent 43bde8c079
commit 8673ac70dd
4 changed files with 84 additions and 23 deletions

View File

@ -125,6 +125,7 @@ our %EXPORT_TAGS = (
get_interface_address
get_interface_addresses
get_interface_bcasts
get_interface_gateway
get_interface_mac
set_global_variables
create_netfilter_load
@ -219,7 +220,9 @@ our $chainseq;
our %interfaceaddr;
our %interfaceaddrs;
our %interfacenets;
our %interfacemacs;
our %interfacebcasts;
our %interfacegateways;
our @builtins = qw(PREROUTING INPUT FORWARD OUTPUT POSTROUTING);
@ -315,10 +318,12 @@ sub initialize() {
#
# Keep track of which interfaces have active 'address', 'addresses' and 'networks' variables
#
%interfaceaddr = ();
%interfaceaddrs = ();
%interfacenets = ();
%interfacebcasts = ();
%interfaceaddr = ();
%interfaceaddrs = ();
%interfacenets = ();
%interfacemacs = ();
%interfacebcasts = ();
%interfacegateways = ();
}
INIT {
@ -1467,7 +1472,7 @@ sub mysplit( $ ) {
#
sub interface_address( $ ) {
my $variable = chain_base( $_[0] ) . '_address';
"\U$variable";
uc $variable;
}
#
@ -1479,7 +1484,7 @@ sub get_interface_address ( $ ) {
my $variable = interface_address( $interface );
my $function = interface_is_optional( $interface ) ? 'find_first_interface_address_if_any' : 'find_first_interface_address';
$interfaceaddr{$interface} = "$variable=\$($function $interface)";
$interfaceaddr{$interface} = "$variable=\$($function $interface)\n";
"\$$variable";
}
@ -1489,7 +1494,7 @@ sub get_interface_address ( $ ) {
#
sub interface_bcasts( $ ) {
my $variable = chain_base( $_[0] ) . '_bcasts';
"\U$variable";
uc $variable;
}
#
@ -1505,12 +1510,39 @@ sub get_interface_bcasts ( $ ) {
"\$$variable";
}
#
# Returns the name of the shell variable holding the gateway through the passed interface
#
sub interface_gateway( $ ) {
my $variable = chain_base( $_[0] ) . '_gateway';
uc $variable;
}
#
# Record that the ruleset requires the gateway address on the passed interface
#
sub get_interface_gateway ( $ ) {
my ( $interface ) = $_[0];
my $variable = interface_gateway( $interface );
if ( interface_is_optional $interface ) {
$interfacegateways{$interface} = qq($variable=\$(detect_gateway $interface)\n);
} else {
$interfacegateways{$interface} = qq($variable=\$(detect_gateway $interface)
[ -n "\$$variable" ] || fatal_error "Unable to detect the gateway through interface $interface"
);
}
"\$$variable";
}
#
# Returns the name of the shell variable holding the addresses of the passed interface
#
sub interface_addresses( $ ) {
my $variable = chain_base( $_[0] ) . '_addresses';
"\U$variable";
uc $variable;
}
#
@ -1537,7 +1569,7 @@ sub get_interface_addresses ( $ ) {
#
sub interface_nets( $ ) {
my $variable = chain_base( $_[0] ) . '_networks';
"\U$variable";
uc $variable;
}
#
@ -1564,19 +1596,25 @@ 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' );
my $variable = join( '_' , chain_base( $_[0] ) , chain_base( $_[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
# 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, $interface , $table ) = @_;
my $variable = interface_mac( $interface , $table );
emit qq($variable=\$(find_mac $ipaddr $interface));
if ( interface_is_optional $interface ) {
$interfacemacs{$table} = qq($variable=\$(find_mac $ipaddr $interface)\n);
} else {
$interfacemacs{$table} = qq($variable=\$(find_mac $ipaddr $interface)
[ -n "\$$variable" ] || fatal_error "Unable to determine the MAC address of $ipaddr through interface \\"$interface\\""
);
}
"\$$variable";
}
@ -1980,6 +2018,16 @@ sub set_global_variables() {
emit $_;
}
for ( values %interfacegateways ) {
emit_comment unless $emitted_comment;
emit $_;
}
for ( values %interfacemacs ) {
emit_comment unless $emitted_comment;
emit $_;
}
for ( values %interfaceaddrs ) {
emit_comment unless $emitted_comment;
emit_test unless $emitted_test;

View File

@ -198,6 +198,8 @@ sub add_a_provider( $$$$$$$$ ) {
fatal_error "Duplicate provider number ($number)" if $providerref->{number} == $number;
}
fatal_error "Unknown Interface ($interface)" unless known_interface $interface;
my $provider = chain_base $table;
emit "#\n# Add Provider $table ($number)\n#";
@ -213,11 +215,7 @@ sub add_a_provider( $$$$$$$$ ) {
if ( $gateway eq 'detect' ) {
$variable = get_interface_address $interface;
emit ( "gateway=\$(detect_gateway $interface)\n",
'if [ -z "$gateway" ]; then',
" fatal_error \"Unable to detect the gateway through interface $interface\"",
"fi\n" );
$gateway = '$gateway';
$gateway = get_interface_gateway $interface;
} elsif ( $gateway && $gateway ne '-' ) {
validate_address $gateway, 0;
$variable = get_interface_address $interface;
@ -253,7 +251,7 @@ sub add_a_provider( $$$$$$$$ ) {
);
}
my ( $loose, $optional, $track, $shared, $balance ) = (0,0,0,0,0);
my ( $loose, $track, $shared, $balance , $optional ) = (0,0,0,0,interface_is_optional( $interface ));
unless ( $options eq '-' ) {
for my $option ( split /,/, $options ) {
@ -266,6 +264,7 @@ sub add_a_provider( $$$$$$$$ ) {
} elsif ( $option eq 'loose' ) {
$loose = 1;
} elsif ( $option eq 'optional' ) {
set_interface_option $interface, 'optional', 1;
$optional = 1;
} elsif ( $option eq 'shared' ) {
require_capability 'REALM_MATCH', "The 'shared' option", "s";
@ -276,7 +275,13 @@ sub add_a_provider( $$$$$$$$ ) {
}
}
$providers{$table} = { provider => $table, number => $number , mark => $val , optional => $optional , interface => $interface , gateway => $gateway, shared => $shared };
$providers{$table} = { provider => $table,
number => $number ,
mark => $val ,
interface => $interface ,
optional => $optional ,
gateway => $gateway ,
shared => $shared };
if ( $track ) {
fatal_error "The 'track' option requires a numeric value in the MARK column" if $mark eq '-';
@ -415,7 +420,7 @@ sub add_an_rtrule( $$$$ ) {
emit ( "qt ip rule del $source $dest $priority" ) if $config{DELETE_THEN_ADD};
my ( $base, $optional, $number ) = ( chain_base( $provider ), $providers{$provider}{optional} , $providers{$provider}{number} );
my ( $base, $optional, $number ) = ( chain_base( $provider ) , $providers{$provider}{optional} , $providers{$provider}{number} );
emit ( '', "if [ -n \$${base}_is_up ]; then" ), push_indent if $optional;

View File

@ -59,6 +59,7 @@ our @EXPORT = qw( NOTHING
interface_is_optional
find_interfaces_by_option
get_interface_option
set_interface_option
validate_hosts_file
find_hosts_by_option
);
@ -863,6 +864,15 @@ sub get_interface_option( $$ ) {
$interfaces{$interface}{options}{$option};
}
#
# Set an option for an interface
#
sub set_interface_option( $$$ ) {
my ( $interface, $option, $value ) = @_;
$interfaces{$interface}{options}{$option} = $value;
}
#
# Validates the hosts file. Generates entries in %zone{..}{hosts}
#

View File

@ -918,11 +918,9 @@ find_mac() # $1 = IP address, $2 = interface
\<*\>)
;;
*)
[ -n "$result" ] && echo $result && return
[ -n "$result" ] && echo $result
;;
esac
fatal_error "Cannot determine the MAC address of $1 through $2"
}
################################################################################