Detect IP configuration early in start/restart so that stopping the fireawall isn't necessary in the case of failure.

Signed-off-by: Tom Eastep <teastep@shorewall.net>

git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@9722 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
teastep 2009-03-21 16:45:27 +00:00
parent 072067c8d2
commit bb8e562d18
4 changed files with 129 additions and 91 deletions

View File

@ -68,6 +68,8 @@ our %EXPORT_TAGS = (
OUTPUT_RESTRICT
POSTROUTE_RESTRICT
ALL_RESTRICT
ALL_COMMANDS
NOT_RESTORE
add_command
add_commands
@ -148,6 +150,7 @@ our %EXPORT_TAGS = (
get_interface_acasts
get_interface_gateway
get_interface_mac
have_global_variables
set_global_variables
create_netfilter_load
create_chainlist_reload
@ -241,6 +244,10 @@ our $exclseq;
our $iprangematch;
our $chainseq;
our $global_variables;
use constant { ALL_COMMANDS => 1, NOT_RESTORE => 2 };
our %interfaceaddr;
our %interfaceaddrs;
our %interfacenets;
@ -338,6 +345,8 @@ sub initialize( $ ) {
%interfaceacasts = ();
%interfacegateways = ();
$global_variables = 0;
}
INIT {
@ -2014,6 +2023,8 @@ 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';
$global_variables |= ALL_COMMANDS;
$interfaceaddr{$interface} = "$variable=\$($function $interface)\n";
"\$$variable";
@ -2035,6 +2046,8 @@ sub get_interface_bcasts ( $ ) {
my $variable = interface_bcasts( $interface );
$global_variables |= NOT_RESTORE;
$interfacebcasts{$interface} = qq($variable="\$(get_interface_bcasts $interface) 255.255.255.255");
"\$$variable";
@ -2054,6 +2067,8 @@ sub interface_acasts( $ ) {
sub get_interface_acasts ( $ ) {
my ( $interface ) = $_[0];
$global_variables |= NOT_RESTORE;
my $variable = interface_acasts( $interface );
$interfaceacasts{$interface} = qq($variable="\$(get_interface_acasts $interface) ff00::/10");
@ -2079,11 +2094,13 @@ sub get_interface_gateway ( $ ) {
my $routine = $config{USE_DEFAULT_RT} ? 'detect_dynamic_gateway' : 'detect_gateway';
$global_variables |= ALL_COMMANDS;
if ( interface_is_optional $interface ) {
$interfacegateways{$interface} = qq([ -n "\$$variable" ] || $variable=\$($routine $interface)\n);
} else {
$interfacegateways{$interface} = qq([ -n "\$$variable" ] || $variable=\$($routine $interface)
[ -n "\$$variable" ] || fatal_error "Unable to detect the gateway through interface $interface"
[ -n "\$$variable" ] || startup_error "Unable to detect the gateway through interface $interface"
);
}
@ -2106,11 +2123,13 @@ sub get_interface_addresses ( $ ) {
my $variable = interface_addresses( $interface );
$global_variables |= NOT_RESTORE;
if ( interface_is_optional $interface ) {
$interfaceaddrs{$interface} = qq($variable=\$(find_interface_addresses $interface)\n);
} else {
$interfaceaddrs{$interface} = qq($variable=\$(find_interface_addresses $interface)
[ -n "\$$variable" ] || fatal_error "Unable to determine the IP address(es) of $interface"
[ -n "\$$variable" ] || startup_error "Unable to determine the IP address(es) of $interface"
);
}
@ -2133,11 +2152,13 @@ sub get_interface_nets ( $ ) {
my $variable = interface_nets( $interface );
$global_variables |= ALL_COMMANDS;
if ( interface_is_optional $interface ) {
$interfacenets{$interface} = qq($variable=\$(get_routed_networks $interface)\n);
} else {
$interfacenets{$interface} = qq($variable=\$(get_routed_networks $interface)
[ -n "\$$variable" ] || fatal_error "Unable to determine the routes through interface \\"$interface\\""
[ -n "\$$variable" ] || startup_error "Unable to determine the routes through interface \\"$interface\\""
);
}
@ -2161,86 +2182,50 @@ sub get_interface_mac( $$$ ) {
my $variable = interface_mac( $interface , $table );
$global_variables |= NOT_RESTORE;
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\\""
[ -n "\$$variable" ] || startup_error "Unable to determine the MAC address of $ipaddr through interface \\"$interface\\""
);
}
"\$$variable";
}
sub have_global_variables() {
$capabilities{ADDRTYPE} ? $global_variables : $global_variables | NOT_RESTORE;
}
#
# Generate setting of run-time global shell variables
#
sub emit_comment() {
emit ( '#',
'# Establish the values of shell variables used in the following function calls',
'#' );
our $emitted_comment = 1;
}
sub emit_test() {
emit ( 'if [ "$COMMAND" != restore ]; then' ,
'' );
push_indent;
our $emitted_test = 1;
}
sub set_global_variables( $ ) {
sub set_global_variables() {
my $setall = shift;
our ( $emitted_comment, $emitted_test ) = (0, 0);
emit $_ for values %interfaceaddr;
emit $_ for values %interfacegateways;
emit $_ for values %interfacemacs;
for ( values %interfaceaddr ) {
emit_comment unless $emitted_comment;
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;
emit $_;
}
for ( values %interfacenets ) {
emit_comment unless $emitted_comment;
emit_test unless $emitted_test;
emit $_;
}
if ( $setall ) {
emit $_ for values %interfaceaddrs;
emit $_ for values %interfacenets;
unless ( $capabilities{ADDRTYPE} ) {
emit_comment unless $emitted_comment;
emit_test unless $emitted_test;
if ( $family == F_IPV4 ) {
emit 'ALL_BCASTS="$(get_all_bcasts) 255.255.255.255"';
for ( values %interfacebcasts ) {
emit $_;
}
emit $_ for values %interfacebcasts;
} else {
emit 'ALL_ACASTS="$(get_all_acasts)"';
for ( values %interfaceacasts ) {
emit $_;
emit $_ for values %interfaceacasts;
}
}
}
pop_indent, emit "fi\n" if $emitted_test;
}
################################################################################################################
@ -2736,7 +2721,10 @@ sub create_netfilter_load( $ ) {
$mode = NULL_MODE;
emit ( 'setup_netfilter()',
emit ( '#',
'# Create the input to iptables-restore/ip6tables-restore and pass that input to the utility',
'#',
'setup_netfilter()',
'{'
);

View File

@ -75,11 +75,6 @@ sub reinitialize() {
# First stage of script generation.
#
# Copy the prog.header to the generated script.
# Generate the various user-exit jacket functions.
# Generate the 'initialize()' function.
#
# Note: This function is not called when $command eq 'check'. So it must have no side effects other
# than those related to writing to the object file.
sub generate_script_1() {
@ -95,6 +90,18 @@ sub generate_script_1() {
copy $globals{SHAREDIRPL} . 'prog.header6';
}
}
}
#
# Second stage of script generation.
#
# Generate the various user-exit jacket functions.
# Generate the 'initialize()' function.
#
# Note: This function is not called when $command eq 'check'. So it must have no side effects other
# than those related to writing to the object file.
sub generate_script_2() {
for my $exit qw/init isusable start tcclear started stop stopped clear refresh refreshed restored/ {
emit "\nrun_${exit}_exit() {";
@ -227,9 +234,50 @@ sub generate_script_1() {
'[ -d ${VARDIR} ] || mkdir -p ${VARDIR}'
);
my $global_variables = have_global_variables;
if ( $global_variables ) {
emit( '' ,
'#' ,
'# Set global variables holding detected IP information' ,
'#' ,
'case $COMMAND in' );
push_indent;
if ( $global_variables & NOT_RESTORE ) {
emit( 'start|restart|refresh)' );
} else {
emit( 'start|restart|refresh|restore)' );
}
push_indent;
set_global_variables(1);
emit ';;';
if ( $global_variables == ( ALL_COMMANDS | NOT_RESTORE ) ) {
pop_indent;
emit "}\n"; # End of initialize()
emit 'restore)';
push_indent;
set_global_variables(0);
emit ';;';
}
pop_indent;
pop_indent;
emit ( 'esac' ) ,
}
pop_indent;
emit "\n}\n"; # End of initialize()
}
@ -579,6 +627,7 @@ EOF
#
# Final stage of script generation.
#
# Copy prog.functions to the object file.
# Generate code for loading the various files in /var/lib/shorewall[-lite]
# Generate code to add IP addresses under ADD_IP_ALIASES and ADD_SNAT_ALIASES
#
@ -588,7 +637,15 @@ EOF
# Note: This function is not called when $command eq 'check'. So it must have no side effects other
# than those related to writing to the object file.
#
sub generate_script_2($) {
sub generate_script_3($) {
unless ( $test ) {
if ( $family == F_IPV4 ) {
copy $globals{SHAREDIRPL} . 'prog.functions';
} else {
copy $globals{SHAREDIRPL} . 'prog.functions6';
}
}
if ( $family == F_IPV4 ) {
progress_message2 "Creating iptables-restore input...";
@ -730,10 +787,6 @@ sub generate_script_2($) {
emit qq(delete_tc1\n) if $config{CLEAR_TC};
set_global_variables;
emit '';
emit( 'setup_common_rules', '' );
emit( 'setup_routing_and_traffic_shaping', '' );
@ -957,26 +1010,18 @@ sub compiler {
# (Produces no output to the compiled script)
#
setup_notrack;
#
# I N I T I A L I Z E
# (Writes the initialize() function to the compiled script)
#
enable_object;
unless ( $command eq 'check' ) {
#
# Place Header in the object
#
generate_script_1;
#
# C O M M O N _ R U L E S
# (Writes the setup_common_rules() function to the compiled script)
#
unless ( $test ) {
if ( $family == F_IPV4 ) {
copy $globals{SHAREDIRPL} . 'prog.functions';
} else {
copy $globals{SHAREDIRPL} . 'prog.functions6';
}
}
emit( "\n#",
'# Setup Common Rules (/proc)',
'#',
@ -1112,6 +1157,11 @@ sub compiler {
}
} else {
enable_object;
#
# I N I T I A L I Z E
# (Writes the initialize() function to the compiled script)
#
generate_script_2;
# S T O P _ F I R E W A L L
# (Writes the stop_firewall() function to the compiled script)
#
@ -1120,7 +1170,7 @@ sub compiler {
# N E T F I L T E R L O A D
# (Produces setup_netfilter(), chainlist_reload() and define_firewall() )
#
generate_script_2( $chains );
generate_script_3( $chains );
#
# Close, rename and secure the object
#

View File

@ -580,7 +580,7 @@ find_first_interface_address() # $1 = interface
#
# If there wasn't one, bail out now
#
[ -n "$addr" ] || fatal_error "Can't determine the IP address of $1"
[ -n "$addr" ] || startup_error "Can't determine the IP address of $1"
#
# Strip off the trailing VLSM mask (or the peer IP in case of a P-t-P link)
# along with everything else on the line

View File

@ -446,7 +446,7 @@ find_first_interface_address() # $1 = interface
#
# If there wasn't one, bail out now
#
[ -n "$addr" ] || fatal_error "Can't determine the IPv6 address of $1"
[ -n "$addr" ] || startup_error "Can't determine the IPv6 address of $1"
#
# Strip off the trailing VLSM mask (or the peer IP in case of a P-t-P link)
# along with everything else on the line