Forum Discussion

Tiaan_92076's avatar
Tiaan_92076
Icon for Nimbostratus rankNimbostratus
Feb 19, 2010

Interface Failover Script via Monitor

I wrote the following script to failover between interfaces in environments where STP or 802.3ad is not available. Eg, when using Cisco's PVST or LACP not supported when cables terminate in separate switches.

I haven't fully tested the script.

 
 !/bin/bash 
 ------------------------------------------------------------------------------------------------ 
  This script is a F5 external monitor to failover the NICs in case of a cable or switch problem. 
  
  Using a spanning tree protocol or 802.3ad would be the preferred method of NIC redundancy. If 
  these protocols is not supported in the environment this script can be used. 
  
  The script expects the two interfaces to provide redundancy on as input parameters, eg. 1.1 1.2 
  
  Last updated 18/02/2010 
 ------------------------------------------------------------------------------------------------ 
  
  Check if 4 parameters were passed to the script 
 if [ "$" != "4" ]; then 
  logger -p local0.warning  "Interface Failover: Only supply two interfaces" 
  exit 1 
 fi 
  
  Check if there is already a copy of the monitor running, monitors will fire on the specified interval regardless if it's still running 
  It sometimes takes a couple of seconds for the interface to come up, this check will prevenet a flip flop between the two NICs 
 if pgrep int_fail > /dev/null; then 
  logger -p local0.warning  "Interface Failover: Script already running, aborting" 
  exit 1 
 fi 
  
  Ignore the 2 default parameters passed by the monitor 
 shift 
 shift 
  
  Setup variables 
 interfaces="$*" 
 state="false" 
 state2="false" 
 state3="false" 
  
  Output interface status to temporary file 
 b interface all show all | grep INTERFACE > /tmp/b_interface_show 
  
  Read statuses from above command into variables 
 int1_status=`grep "^INTERFACE *$1 " /tmp/b_interface_show | awk '{print $5}' | tr '[:lower:]' '[:upper:]'` 
 int1_config=`grep "^INTERFACE *$1 " /tmp/b_interface_show | awk '{print $4}'` 
 int2_status=`grep "^INTERFACE *$2 " /tmp/b_interface_show | awk '{print $5}' | tr '[:lower:]' '[:upper:]'` 
 int2_config=`grep "^INTERFACE *$2 " /tmp/b_interface_show | awk '{print $4}'` 
  
  Check if both interfaces ae enabled, this will cause a loop on the network 
 if [ "$int1_config" == "ENABLED" ] && [ "$int2_config" == "ENABLED" ]; then 
   logger -p local0.warning  "Interface Failover: ERROR: Only one interface should be enabled" 
   exit 1 
 fi 
  
  Check if interface 1 is down and enabled and interface 2 disabled; if this is the case a failover need to happen 
 if [ "$int1_status" == "DOWN" ] && [ "$int1_config" == "ENABLED" ] && [ "$int2_config" == "DISABLED" ]; then 
   logger -p local0.warning  "Interface Failover: Interface $1 is $int1_config and $int1_status" 
   logger -p local0.warning  "Interface Failover: Disabling interface $1" 
  Disable interface 1 
   b interface $1 disable 
  
  Loop for 5 seconds or until interface 1 is disabled 
   for i in {1..5} 
   do 
  Output interface 1 status to temporary file 
    b interface $1 show all | grep INTERFACE > /tmp/b_interface_$1_show 
  Read status from above command into variable 
    config=`grep "^INTERFACE *$1 " /tmp/b_interface_$1_show | awk '{print $4}'` 
  Check if interface 1 is disabled 
     if [ "$config" == "DISABLED" ]; then 
      logger -p local0.warning  "Interface Failover: Enabling interface $2" 
      state3="true" 
  Enable interface 2 after confirming interface 1 is down 
      b interface $2 enable 
      break 
     fi 
    sleep 1s 
   done 
    
  If the interface was not enabled in 5 seconds abort the script 
  if ["$state3" == "false"]; then 
   logger -p local0.warning  "Interface Failover: Error: Unable to disable interface $1" 
   exit 1 
  fi 
  
  Loop for 5 seconds or until interface 2 is enabled 
   for i in {1..5} 
   do 
  Output interface 2 status to temporary file 
    b interface $2 show all | grep INTERFACE > /tmp/b_interface_$2_show 
  Read status from above command into variable 
    config=`grep "^INTERFACE *$2 " /tmp/b_interface_$2_show | awk '{print $4}'` 
  Check if interface 2 is enabled 
     if [ "$config" == "ENABLED" ]; then 
      logger -p local0.warning  "Interface Failover: Interface $2 enabled" 
      state="true" 
      break 
     fi 
    sleep 1s 
   done 
  
  If the interface was not enabled in 5 seconds abort the script 
  if ["$state" == "false"]; then 
   logger -p local0.warning  "Interface Failover: Error: Unable to enable interface $2" 
   exit 1 
  fi 
  
 Waiting for 30 seconds for the interface to come up 
   for i in {1..30} 
   do 
  Output interface 2 status to temporary file 
    b interface $2 show all | grep INTERFACE > /tmp/b_interface_$2_show 
  Read status from above command into variable 
    status=`grep "^INTERFACE *$2 " /tmp/b_interface_$2_show | awk '{print $5}' | tr '[:lower:]' '[:upper:]'` 
  Check if interface 2 is up 
     if [ "$status" == "UP" ]; then 
      logger -p local0.warning  "Interface Failover: Interface $2 UP" 
      state2="true" 
      break 
     fi 
    sleep 1s 
   done 
  
  If the interface did not come up in 30 seconds abort the script 
  if ["$state2" == "false"]; then 
   logger -p local0.warning  "Interface Failover: Error: Interface $2 not coming UP" 
   exit 1 
  fi 
  
 fi 
  
  Check if interface 2 is down and enabled and interface 1 disabled; if this is the case a failover need to happen 
 if [ "$int2_status" == "DOWN" ] && [ "$int2_config" == "ENABLED" ] && [ "$int1_config" == "DISABLED" ]; then 
   logger -p local0.warning  "Interface Failover: Interface $2 is $int2_config and $int2_status" 
   logger -p local0.warning "Interface Failover: Disabling interface $2" 
   b interface $2 disable 
  
  Loop for 5 seconds or until interface 1 is disabled 
   for i in {1..5} 
   do 
  Output interface 2 status to temporary file 
    b interface $2 show all | grep INTERFACE > /tmp/b_interface_$2_show 
  Read status from above command into variable 
    config=`grep "^INTERFACE *$2 " /tmp/b_interface_$2_show | awk '{print $4}'` 
  Check if interface 2 is disabled 
     if [ "$config" == "DISABLED" ]; then 
      logger -p local0.warning "Interface Failover: Enabling interface $1" 
      state3="true" 
  Enable interface 1 after confirming interface 2 is down 
      b interface $1 enable 
      break 
     fi 
    sleep 1s 
   done 
    
  If the interface was not enabled in 5 seconds abort the script 
  if ["$state3" == "false"]; then 
   logger -p local0.warning  "Interface Failover: Error: Unable to disable interface $2" 
   exit 1 
  fi 
  
  Loop for 5 seconds or until interface 1 is enabled 
   for i in {1..5} 
   do 
  Output interface 1 status to temporary file 
    b interface $1 show all | grep INTERFACE > /tmp/b_interface_$1_show 
  Read status from above command into variable 
    config=`grep "^INTERFACE *$1 " /tmp/b_interface_$1_show | awk '{print $4}'` 
  Check if interface 1 is enabled 
     if [ "$config" == "ENABLED" ]; then 
      logger -p local0.warning  "Interface Failover: Interface $1 enabled" 
      state="true" 
      break 
     fi 
    sleep 1s 
   done 
  
   If the interface was not enabled in 5 seconds abort the script 
  if ["$state" == "false"]; then 
   logger -p local0.warning  "Interface Failover: Error: Unable to enable interface $1" 
   exit 1 
  fi 
  
 Waiting for 30 seconds for the interface to come up 
   for i in {1..30} 
   do 
  Output interface 1 status to temporary file 
    b interface $1 show all | grep INTERFACE > /tmp/b_interface_$1_show 
  Read status from above command into variable 
    status=`grep "^INTERFACE *$1 " /tmp/b_interface_$1_show | awk '{print $5}' | tr '[:lower:]' '[:upper:]'` 
  Check if interface 1 is up 
     if [ "$status" == "UP" ]; then 
      logger -p local0.warning  "Interface Failover: Interface $1 UP" 
      state2="true" 
      break 
     fi 
    sleep 1s 
   done 
  
  If the interface did not come up in 30 seconds abort the script 
  if ["$state2" == "false"]; then 
   logger -p local0.warning  "Interface Failover: Error: Interface $1 not coming UP" 
   exit 1 
  fi 
  
 fi 
  
  Remove temporary files 
 rm /tmp/b_interface_$1_show 
 rm /tmp/b_interface_$2_show 
 rm /tmp/b_interface_show 
  
  Monitor expects output of "up"; no return value will mark the monitor down 
 echo "up" 
 exit 0 
 

Thanks

Tiaan
  • It seems like a monitor still running when the next interval is reached; is killed and a new monitor started. Is there any way to prevent this ?
  • spark_86682's avatar
    spark_86682
    Historic F5 Account
    There is no way to prevent the kill signal from being sent. If you really need that, then have your EAV spawn a new process in a new process group, so that child will not receive the signal. It's a bit tricky because the original process will still need to be around to talk to bigd, but it can be done.
  • hello, is it possible to take this script in a monitor and execute it ?

     

    I execute this script in a monitor with the command b monitor interface_failsafe run and nothing happend whereas in execute it with the command sh /usr/bin/monitors/interface_failsafe.eav 0 0 1.1 1.2 its works.

     

    Can you help me ?
  • Hi, I'm using it in a monitor currently, try renaming the file to "interface_failover", removing the extension.
  • Hello, its not work without the extension. I'm using a little script who create a file in tmp like : echo test > /tmp/test.log.

     

    In run it in shell, its work and in external monitor with b monitor test run, it doesn't create the file.

     

    I think that there is an communication error in processes when i run the monitor.