From 312efe5c7b40611ff7977dd76ae869fe02b6d02e Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Fri, 1 Jun 2012 11:27:57 -0700 Subject: [PATCH] Use enable/disable for up and down of provider interfaces Signed-off-by: Tom Eastep --- Shorewall-core/lib.base | 67 +--------------- Shorewall-core/lib.common | 66 ++++++++++++++++ Shorewall-init/ifupdown.sh | 11 +-- Shorewall/Perl/Shorewall/Providers.pm | 109 ++++++++++++++++++-------- Shorewall/lib.core | 1 - 5 files changed, 146 insertions(+), 108 deletions(-) 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 bba943f0a..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 @@ -188,14 +188,7 @@ fi for PRODUCT in $PRODUCTS; do 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 done diff --git a/Shorewall/Perl/Shorewall/Providers.pm b/Shorewall/Perl/Shorewall/Providers.pm index cf728770c..15b3a47de 100644 --- a/Shorewall/Perl/Shorewall/Providers.pm +++ b/Shorewall/Perl/Shorewall/Providers.pm @@ -1236,6 +1236,8 @@ sub process_providers( $ ) { enable_provider() { g_interface=$1; + mutex_on + case $g_interface in EOF @@ -1270,6 +1272,8 @@ EOF startup_error "$g_interface is not an optional provider or provider interface" ;; esac + + mutex_off } # @@ -1371,7 +1375,8 @@ sub compile_updown() { emit( 'local state', 'state=cleared', - '' ); + '' + ); emit 'progress_message3 "$g_product $COMMAND triggered by $1"'; emit ''; @@ -1420,6 +1425,42 @@ sub compile_updown() { ); } + 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; @@ -1462,41 +1503,43 @@ sub compile_updown() { } if ( @$optional ) { - my @interfaces = map get_physical( $_ ), @$optional; + my @interfaces = map( get_physical( $_ ), grep( ! $provider_interfaces{$_} , @$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' ); - } + 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( '', + ' 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( "*)", 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