diff --git a/Shorewall-core/lib.base b/Shorewall-core/lib.base index fcc158261..774b2c7f8 100644 --- a/Shorewall-core/lib.base +++ b/Shorewall-core/lib.base @@ -130,71 +130,6 @@ combine_list() echo $o } -# -# Call this function to assert mutual exclusion with Shorewall. If you invoke the -# /sbin/shorewall program while holding mutual exclusion, you should pass "nolock" as -# the first argument. Example "shorewall nolock refresh" -# -# This function uses the lockfile utility from procmail if it exists. -# Otherwise, it uses a somewhat race-prone algorithm to attempt to simulate the -# behavior of lockfile. -# -mutex_on() -{ - local try - try=0 - local lockf - lockf=${LOCKFILE:=${VARDIR}/lock} - local lockpid - - MUTEX_TIMEOUT=${MUTEX_TIMEOUT:-60} - - if [ $MUTEX_TIMEOUT -gt 0 ]; then - - [ -d ${VARDIR} ] || mkdir -p ${VARDIR} - - if [ -f $lockf ]; then - lockpid=`cat ${lockf} 2> /dev/null` - if [ -z "$lockpid" -o $lockpid = 0 ]; then - rm -f ${lockf} - error_message "WARNING: Stale lockfile ${lockf} removed" - elif ! qt ps p ${lockpid}; then - rm -f ${lockf} - error_message "WARNING: Stale lockfile ${lockf} from pid ${lockpid} removed" - fi - fi - - if qt mywhich lockfile; then - lockfile -${MUTEX_TIMEOUT} -r1 ${lockf} - chmod u+w ${lockf} - echo $$ > ${lockf} - chmod u-w ${lockf} - else - while [ -f ${lockf} -a ${try} -lt ${MUTEX_TIMEOUT} ] ; do - sleep 1 - try=$((${try} + 1)) - done - - if [ ${try} -lt ${MUTEX_TIMEOUT} ] ; then - # Create the lockfile - echo $$ > ${lockf} - else - echo "Giving up on lock file ${lockf}" >&2 - fi - fi - fi -} - -# -# Call this function to release mutual exclusion -# -mutex_off() -{ - rm -f ${LOCKFILE:=${VARDIR}/lock} -} - -[ -z "$LEFTSHIFT" ] && . ${g_basedir}/lib.common - # # Validate an IP address # @@ -323,6 +258,8 @@ ip_range_explicit() { done } +[ -z "$LEFTSHIFT" ] && . ${g_basedir}/lib.common + # # Netmask to VLSM # diff --git a/Shorewall-core/lib.common b/Shorewall-core/lib.common index d704be5a5..d02fdc29f 100644 --- a/Shorewall-core/lib.common +++ b/Shorewall-core/lib.common @@ -717,3 +717,69 @@ truncate() # $1 = length { cut -b -${1} } + +# +# Call this function to assert mutual exclusion with Shorewall. If you invoke the +# /sbin/shorewall program while holding mutual exclusion, you should pass "nolock" as +# the first argument. Example "shorewall nolock refresh" +# +# This function uses the lockfile utility from procmail if it exists. +# Otherwise, it uses a somewhat race-prone algorithm to attempt to simulate the +# behavior of lockfile. +# +mutex_on() +{ + local try + try=0 + local lockf + lockf=${LOCKFILE:=${VARDIR}/lock} + local lockpid + + MUTEX_TIMEOUT=${MUTEX_TIMEOUT:-60} + + if [ $MUTEX_TIMEOUT -gt 0 ]; then + + [ -d ${VARDIR} ] || mkdir -p ${VARDIR} + + if [ -f $lockf ]; then + lockpid=`cat ${lockf} 2> /dev/null` + if [ -z "$lockpid" -o $lockpid = 0 ]; then + rm -f ${lockf} + error_message "WARNING: Stale lockfile ${lockf} removed" + elif [ $lockpid -eq $$ ]; then + return 0 + elif ! qt ps p ${lockpid}; then + rm -f ${lockf} + error_message "WARNING: Stale lockfile ${lockf} from pid ${lockpid} removed" + fi + fi + + if qt mywhich lockfile; then + lockfile -${MUTEX_TIMEOUT} -r1 ${lockf} + chmod u+w ${lockf} + echo $$ > ${lockf} + chmod u-w ${lockf} + else + while [ -f ${lockf} -a ${try} -lt ${MUTEX_TIMEOUT} ] ; do + sleep 1 + try=$((${try} + 1)) + done + + if [ ${try} -lt ${MUTEX_TIMEOUT} ] ; then + # Create the lockfile + echo $$ > ${lockf} + else + echo "Giving up on lock file ${lockf}" >&2 + fi + fi + fi +} + +# +# Call this function to release mutual exclusion +# +mutex_off() +{ + rm -f ${LOCKFILE:=${VARDIR}/lock} +} + diff --git a/Shorewall-init/ifupdown.sh b/Shorewall-init/ifupdown.sh index 4975fd781..933dca20c 100644 --- a/Shorewall-init/ifupdown.sh +++ b/Shorewall-init/ifupdown.sh @@ -108,7 +108,7 @@ if [ -f /etc/debian_version ]; then fi case "$PHASE" in - pre-*) + post-*) exit 0 ;; esac @@ -187,22 +187,9 @@ else fi for PRODUCT in $PRODUCTS; do - # - # For backward compatibility, lib.base appends the product name to VARDIR - # Save it here and restore it below - # - save_vardir=${VARDIR} if [ -x $VARDIR/$PRODUCT/firewall ]; then - ( g_program=$PRODUCT - g_readrc= - - . ${SHAREDIR}/shorewall/lib.base - mutex_on - ${VARDIR}/firewall -V0 $COMMAND $INTERFACE || echo_notdone - mutex_off - ) + ( ${VARDIR}/$PRODUCT/firewall -V0 $COMMAND $INTERFACE ) || true fi - VARDIR=${save_vardir} done exit 0 diff --git a/Shorewall-init/install.sh b/Shorewall-init/install.sh index ecf58dd44..4a026c468 100755 --- a/Shorewall-init/install.sh +++ b/Shorewall-init/install.sh @@ -347,7 +347,7 @@ fi cp ifupdown.sh ifupdown -d[ "${SHAREDIR}" = /usr/share ] || eval sed -i \'s\|/usr/share/\|${SHAREDIR}/\|\' ifupdown +[ "${SHAREDIR}" = /usr/share ] || eval sed -i \'s\|/usr/share/\|${SHAREDIR}/\|\' ifupdown mkdir -p ${DESTDIR}${LIBEXECDIR}/shorewall-init diff --git a/Shorewall/Perl/Shorewall/Providers.pm b/Shorewall/Perl/Shorewall/Providers.pm index a31d3a4fe..15b3a47de 100644 --- a/Shorewall/Perl/Shorewall/Providers.pm +++ b/Shorewall/Perl/Shorewall/Providers.pm @@ -39,6 +39,7 @@ our @EXPORT = qw( process_providers @routemarked_interfaces handle_stickiness handle_optional_interfaces + compile_updown setup_load_distribution ); our @EXPORT_OK = qw( initialize lookup_provider ); @@ -1235,6 +1236,8 @@ sub process_providers( $ ) { enable_provider() { g_interface=$1; + mutex_on + case $g_interface in EOF @@ -1269,6 +1272,8 @@ EOF startup_error "$g_interface is not an optional provider or provider interface" ;; esac + + mutex_off } # @@ -1354,6 +1359,214 @@ sub setup_providers() { } +# +# Emit the updown() function +# +sub compile_updown() { + emit( '', + '#', + '# Handle the "up" and "down" commands', + '#', + 'updown() # $1 = interface', + '{', + ); + + push_indent; + + emit( 'local state', + 'state=cleared', + '' + ); + + emit 'progress_message3 "$g_product $COMMAND triggered by $1"'; + emit ''; + + if ( $family == F_IPV4 ) { + emit 'if shorewall_is_started; then'; + } else { + emit 'if shorewall6_is_started; then'; + } + + emit( ' state=started', + 'elif [ -f ${VARDIR}/state ]; then', + ' case "$(cat ${VARDIR}/state)" in', + ' Stopped*)', + ' state=stopped', + ' ;;', + ' Cleared*)', + ' ;;', + ' *)', + ' state=unknown', + ' ;;', + ' esac', + 'else', + ' state=unknown', + 'fi', + '' + ); + + emit( 'case $1 in' ); + + push_indent; + + my $ignore = find_interfaces_by_option 'ignore'; + my $required = find_interfaces_by_option 'required'; + my $optional = find_interfaces_by_option 'optional'; + + if ( @$ignore ) { + my $interfaces = join '|', map get_physical( $_ ), @$ignore; + + $interfaces =~ s/\+/*/g; + + emit( "$interfaces)", + ' progress_message3 "$COMMAND on interface $1 ignored"', + ' exit 0', + ' ;;' + ); + } + + my @nonshared = ( grep $providers{$_}->{optional}, + sort( { $providers{$a}->{number} <=> $providers{$b}->{number} } values %provider_interfaces ) ); + + if ( @nonshared ) { + my $interfaces = join( '|', map $providers{$_}->{physical}, @nonshared ); + + emit "$interfaces)"; + + push_indent; + + emit( q(if [ "$state" = started ]; then) , + q( if [ "$COMMAND" = up ]; then) , + q( progress_message3 "Attempting enable on interface $1") , + q( COMMAND=enable) , + q( detect_configuration), + q( enable_provider $1), + q( else) , + q( progress_message3 "Attempting disable on interface $1") , + q( COMMAND=disable) , + q( detect_configuration), + q( disable_provider $1) , + q( fi) , + q(elif [ "$COMMAND" = up ]; then) , + q( echo 0 > \${VARDIR}/${1}.state) , + q( COMMAND=start), + q( progress_message3 "$g_product attempting start") , + q( detect_configuration), + q( define_firewall), + q(else), + q( progress_message3 "\$COMMAND on interface $1 ignored") , + q(fi) , + q(;;) ); + + pop_indent; + } + + if ( @$required ) { + my $interfaces = join '|', map get_physical( $_ ), @$required; + + my $wildcard = ( $interfaces =~ s/\+/*/g ); + + emit( "$interfaces)", + ' if [ "$COMMAND" = up ]; then' ); + + if ( $wildcard ) { + emit( ' if [ "$state" = started ]; then', + ' COMMAND=restart', + ' else', + ' COMMAND=start', + ' fi' ); + } else { + emit( ' COMMAND=start' ); + } + + emit( ' progress_message3 "$g_product attempting $COMMAND"', + ' detect_configuration', + ' define_firewall' ); + + if ( $wildcard ) { + emit( ' elif [ "$state" = started ]; then', + ' progress_message3 "$g_product attempting restart"', + ' COMMAND=restart', + ' detect_configuration', + ' define_firewall' ); + } else { + emit( ' else', + ' COMMAND=stop', + ' progress_message3 "$g_product attempting stop"', + ' detect_configuration', + ' stop_firewall' ); + } + + emit( ' fi', + ' ;;' + ); + } + + if ( @$optional ) { + my @interfaces = map( get_physical( $_ ), grep( ! $provider_interfaces{$_} , @$optional ) ); + my $interfaces = join '|', @interfaces; + + if ( $interfaces ) { + if ( $interfaces =~ s/\+/*/g || @interfaces > 1 ) { + emit( "$interfaces)", + ' if [ "$COMMAND" = up ]; then', + ' echo 0 > ${VARDIR}/${1}.state', + ' else', + ' echo 1 > ${VARDIR}/${1}.state', + ' fi' ); + } else { + emit( "$interfaces)", + ' if [ "$COMMAND" = up ]; then', + " echo 0 > \${VARDIR}/$interfaces.state", + ' else', + " echo 1 > \${VARDIR}/$interfaces.state", + ' fi' ); + } + + emit( '', + ' if [ "$state" = started ]; then', + ' COMMAND=restart', + ' progress_message3 "$g_product attempting restart"', + ' detect_configuration', + ' define_firewall', + ' elif [ "$state" = stopped ]; then', + ' COMMAND=start', + ' progress_message3 "$g_product attempting start"', + ' detect_configuration', + ' define_firewall', + ' else', + ' progress_message3 "$COMMAND on interface $1 ignored"', + ' fi', + ' ;;', + ); + } + } + + emit( "*)", + ' case $state in', + ' started)', + ' COMMAND=restart', + ' progress_message3 "$g_product attempting restart"', + ' detect_configuration', + ' define_firewall', + ' ;;', + ' *)', + ' progress_message3 "$COMMAND on interface $1 ignored"', + ' ;;', + ' esac', + ); + + pop_indent; + + emit( 'esac' ); + + pop_indent; + + emit( '}', + '', + ); +} + sub lookup_provider( $ ) { my $provider = $_[0]; my $providerref = $providers{ $provider }; diff --git a/Shorewall/Perl/Shorewall/Zones.pm b/Shorewall/Perl/Shorewall/Zones.pm index b9300c1bd..46c718dfa 100644 --- a/Shorewall/Perl/Shorewall/Zones.pm +++ b/Shorewall/Perl/Shorewall/Zones.pm @@ -80,7 +80,6 @@ our @EXPORT = qw( NOTHING set_interface_provider interface_zones verify_required_interfaces - compile_updown validate_hosts_file find_hosts_by_option find_zone_hosts_by_option @@ -173,6 +172,7 @@ my %reservedName = ( all => 1, # number => # physical => # base => +# provider => # zones => { zone1 => 1, ... } # } # } @@ -1635,175 +1635,6 @@ sub verify_required_interfaces( $ ) { $returnvalue; } -# -# Emit the updown() function -# -sub compile_updown() { - emit( '', - '#', - '# Handle the "up" and "down" commands', - '#', - 'updown() # $1 = interface', - '{', - ); - - push_indent; - - emit( 'local state', - 'state=cleared', - '' ); - - emit 'progress_message3 "$g_product $COMMAND triggered by $1"'; - emit ''; - - if ( $family == F_IPV4 ) { - emit 'if shorewall_is_started; then'; - } else { - emit 'if shorewall6_is_started; then'; - } - - emit( ' state=started', - 'elif [ -f ${VARDIR}/state ]; then', - ' case "$(cat ${VARDIR}/state)" in', - ' Stopped*)', - ' state=stopped', - ' ;;', - ' Cleared*)', - ' ;;', - ' *)', - ' state=unknown', - ' ;;', - ' esac', - 'else', - ' state=unknown', - 'fi', - '' - ); - - emit( 'case $1 in' ); - - push_indent; - - my $ignore = find_interfaces_by_option 'ignore'; - my $required = find_interfaces_by_option 'required'; - my $optional = find_interfaces_by_option 'optional'; - - if ( @$ignore ) { - my $interfaces = join '|', map $interfaces{$_}->{physical}, @$ignore; - - $interfaces =~ s/\+/*/g; - - emit( "$interfaces)", - ' progress_message3 "$COMMAND on interface $1 ignored"', - ' exit 0', - ' ;;' - ); - } - - if ( @$required ) { - my $interfaces = join '|', map $interfaces{$_}->{physical}, @$required; - - my $wildcard = ( $interfaces =~ s/\+/*/g ); - - emit( "$interfaces)", - ' if [ "$COMMAND" = up ]; then' ); - - if ( $wildcard ) { - emit( ' if [ "$state" = started ]; then', - ' COMMAND=restart', - ' else', - ' COMMAND=start', - ' fi' ); - } else { - emit( ' COMMAND=start' ); - } - - emit( ' progress_message3 "$g_product attempting $COMMAND"', - ' detect_configuration', - ' define_firewall' ); - - if ( $wildcard ) { - emit( ' elif [ "$state" = started ]; then', - ' progress_message3 "$g_product attempting restart"', - ' COMMAND=restart', - ' detect_configuration', - ' define_firewall' ); - } else { - emit( ' else', - ' COMMAND=stop', - ' progress_message3 "$g_product attempting stop"', - ' detect_configuration', - ' stop_firewall' ); - } - - emit( ' fi', - ' ;;' - ); - } - - if ( @$optional ) { - my @interfaces = map $interfaces{$_}->{physical}, @$optional; - my $interfaces = join '|', @interfaces; - - if ( $interfaces =~ s/\+/*/g || @interfaces > 1 ) { - emit( "$interfaces)", - ' if [ "$COMMAND" = up ]; then', - ' echo 0 > ${VARDIR}/${1}.state', - ' else', - ' echo 1 > ${VARDIR}/${1}.state', - ' fi' ); - } else { - emit( "$interfaces)", - ' if [ "$COMMAND" = up ]; then', - " echo 0 > \${VARDIR}/$interfaces.state", - ' else', - " echo 1 > \${VARDIR}/$interfaces.state", - ' fi' ); - } - - emit( '', - ' if [ "$state" = started ]; then', - ' COMMAND=restart', - ' progress_message3 "$g_product attempting restart"', - ' detect_configuration', - ' define_firewall', - ' elif [ "$state" = stopped ]; then', - ' COMMAND=start', - ' progress_message3 "$g_product attempting start"', - ' detect_configuration', - ' define_firewall', - ' else', - ' progress_message3 "$COMMAND on interface $1 ignored"', - ' fi', - ' ;;', - ); - } - - emit( "*)", - ' case $state in', - ' started)', - ' COMMAND=restart', - ' progress_message3 "$g_product attempting restart"', - ' detect_configuration', - ' define_firewall', - ' ;;', - ' *)', - ' progress_message3 "$COMMAND on interface $1 ignored"', - ' ;;', - ' esac', - ); - - pop_indent; - - emit( 'esac' ); - - pop_indent; - - emit( '}', - '', - ); -} - # # Process a record in the hosts file # diff --git a/Shorewall/lib.core b/Shorewall/lib.core index a8b5ea222..d953d87f8 100644 --- a/Shorewall/lib.core +++ b/Shorewall/lib.core @@ -182,7 +182,6 @@ get_routed_networks() # $1 = interface name, $2-n = Fatal error message [ $g_family -eq 4 ] && mask=32 || mask=128 - $IP -$g_family route show dev $1 2> /dev/null | while read address rest; do case "$address" in