#!/bin/bash

# -------------------------------------------------------
# file   : join8k.sh
# purpose: Installation script to remove firewall.
# author : Vittal.S
#
# usage  : join8k
#
# modifications:
# 09-05-08  Initial Creation .
# -------------------------------------------------------

### Constants
_SELF_="$(basename "$(readlink -e "${BASH_SOURCE[0]}")" && echo X)" && \
readonly _SELF_="${_SELF_%$'\nX'}"
_SELFDIR_="$(dirname "$(readlink -e "${BASH_SOURCE[0]}")" && echo X)" && \
readonly _SELFDIR_="${_SELFDIR_%$'\nX'}"
readonly COMMONINC="${_SELFDIR_}/common8k"

if [ -e /usr/sbin/iptables ]
then
IPTABLESPATH=/usr/sbin/
fi

### Include files
source ${COMMONINC} || exit 1
#Check if osv_version is available
OSV_VERSION=$(whereis -b osv_version.sh | awk '{ print $2 }')
if [ ! -f "$OSV_VERSION" ]; then
   logger --id $$ --priority user.warning "$0: osv_version.sh not found in \$PATH ($PATH), exiting!" >/dev/null 2>&1
   exit 1
fi

# ----------------------------------------------------------
# function: textncolor
# description:
#   sets up text in color.
# ----------------------------------------------------------

textncolor( )
{
   echo -e "${1}$2${Norm}"
}

setmode( )
{
   echo -e $1
}

# ----------------------------------------------------------
# function: logstr
# description:
#   logs string to logfile.
# ----------------------------------------------------------

logstr( )
{
   str="$*"

   if [ "$LOG8k4TOOLKIT" != "" -a -w "$LOG8k4TOOLKIT" ];
   then
      echo "`date`: $str" 1>>$LOGFILE 2>/dev/null
   else
      echo "`date`: $str"
   fi
}

# ----------------------------------------------------------------
# function: mapnafodev
# args    : none
# description:
#   In V6 or higher we have a new mapping( BO3621 ).
# ----------------------------------------------------------------

mapnafodev( ) {
   case $2 in
      bond0)
         eval ${1}=bonding_dev0
         ;;
      bond1)
         eval ${1}=bonding_dev1
         ;;
      bond2)
         eval ${1}=bonding_dev2
         ;;
      bond3)
         eval ${1}=cluster_dev
         ;;
      *)
         eval ${1}=$2
         ;;
   esac
}

#---------------------------------------------------------------
# function: ommstate
# args    : None
# description:
#   sets up omm state for pcm to read.
#---------------------------------------------------------------

ommstate( )
{
   if [ "$testbed" != "cluster" -o "$mynode" != "$primhost" ];
   then
      return
   fi

   omnode=$1
   omstate=$2

   textncolor $BoldPurple "upgrade8k : Setting OMM state : $omstate"
   OmFile="/srx_share/OperationMode.txt"
   echo $omstate > ${OmFile}.tmp
   chown srx.$srxgroup ${OmFile}.tmp
   if [ "$omnode" = "remote" ];
   then
      scp ${OmFile}.tmp $othernode:/tmp
      ssh $othernode "mv $OmFile{.tmp,}"
      if [ $? -ne 0 ];
      then
         textncolor $BoldRed "Cannot set omm state."
         exit $FAIL
      fi
   else
      mv $OmFile{.tmp,}
   fi
}


# ---------------------------------------------------------------
# function: initvars
# args    : None
# description:
#   just initialize one variables.
# ---------------------------------------------------------------

initvars( )
{
   SUCCESS=0
   FAIL=2
   MISSINGCFGDIR=8

   BoldGreen="\033[1;32m"
   BoldBlue="\033[1;34m"
   BoldCyan="\033[1;36m"
   BoldWhite="\033[1;37m"
   UnderLine="\033[4m"
   Yellow="\033[1;33m"
   Norm="\033[0m"

   export LIVE8kUPGRADE=true
   CFG8k=/etc/hiq8000/node.cfg
   LOGFILE=/log/prepare8k.log
   mynode="`uname -n`"
   getcfgvar $CFG8k test_bed     testbed
   getcfgvar $CFG8k srx_build_id buildid
   getcfgvar $CFG8k node_1_name  primhost
   getcfgvar $CFG8k node_2_name  sechost

   #<CheckPlatform>
   res=`type -t getvmtypefromDMI`
   if [ "$res" = "function" ]; then
      vmtype=`getvmtypefromDMI`
      if [ "$vmtype" = "Google" ]; then
         isGoogleCloudPlatform="true"
      else
         isGoogleCloudPlatform="false"
      fi
   else
      isGoogleCloudPlatform="false"
      echo "join8k: Failed to check if system is in Google Cloud."
   fi
   #</CheckPlatform>

   #<CheckTestBed>
   if [ "$testbed" != "cluster" ];
   then
      echo "join8k: This interface is valid only on a cluster."
      exit $FAIL
   fi
   #</CheckTestBed>

   #<GroupFlip>
      grep -q "^rtpgrp" /etc/group
      if [ $? -eq 0 ];
      then
         srxgroup=rtpgrp
      else
         srxgroup=other
      fi
   #</GroupFlip>
}

# ---------------------------------------------------------------
# function: joinsys
# args    : None
# description:
#   joins the x-connect to make a regular cluster.
# ---------------------------------------------------------------

joinsys( )
{
   if "$OSV_VERSION" --major compare "$buildid" lt V5;
   then
      textncolor $BoldCyan "Detected shutdown managed by primecluster on $mynode."
      sdagentcmd="sdtool -b 1>/dev/null 2>&1"
   else
      if "$OSV_VERSION" --major compare "$buildid" lt V7;
      then
         textncolor $BoldCyan "Detected shutdown managed by heartbeat on $mynode."
         sdagentcmd="/etc/init.d/heartbeat start 1>/dev/null 2>&1"
      else
         textncolor $BoldCyan "Detected shutdown managed by xcm on $mynode."
         logstr "   - Turning off shutdown agent on $mynode."
         /unisphere/srx3000/callp/bin/xcm_snd_stop
         if [ $? -ne 0 ];
         then
            textncolor $BoldRed "upgrade8k: Failed to turn off shutdown agent on $mynode"
            exit $SASTOPFAILED
         fi
         logstr "   - Turning on shutdown agent on $mynode."
         /unisphere/srx3000/callp/bin/XcmState -c OTHER
         sdagentcmd="su - srx -c '/unisphere/srx3000/callp/bin/xcm_snd_start' 1>/dev/null 2>&1"
      fi
   fi
   echo "   - Turning on shutdown agent."
   $sdagentcmd 1>/dev/null 2>&1
   if [ $? -ne 0 ];
   then
      textncolor $BoldRed "upgrade8k: Failed to turn on shutdown agent on $mynode"
      exit $SASTOPFAILED
   fi
}

# ---------------------------------------------------------------
# function: enablearp
# args    : None
# description:
#   sends gratuitous arps for HA switchover.
# ---------------------------------------------------------------

enablearp( )
{
   arpcount=${1:-1}
   #<EnableArps>
   for devidx in $sigbondset $nafosigdev
   do
      ifconfig $devidx 1>/dev/null 2>&1
      if [ $? -eq 0 ];
      then
         ip link set arp off dev $devidx
         logstr "   - Enabling arp for $devidx"
         ifconfig $devidx arp
         if [ $? -ne 0 ];
         then
           logstr "join8k:Sorry, Cannot enable arp for $devidx."
           exit $ARPENABLEFAILED
         fi
         ip link set arp on dev  $devidx
         ipv4list="`ip addr list $devidx | grep "inet " | cut -d' ' -f6 | cut -d/ -f1`"
         ipv6list="`ip addr list $devidx | grep "inet6" | cut -d' ' -f6 | cut -d/ -f1 | egrep -ve 'fe80|^::1$'`"
         for ipidx in $ipv4list
         do
            {
               echo "   - Gratuitous arp for $ipidx"
               loopcount=0
               while [ $loopcount -le $arpcount ];
               do
                  arping -U -c 1 -I $devidx $ipidx 
                  loopcount=$[loopcount+1]
               done;
            } >>$LOGFILE
         done
         for ipidx in $ipv6list
         do
            {
               echo "   - Gratuitous arp for $ipidx"
               arping6 -c $arpcount -I $devidx $ipidx 
            } >>$LOGFILE
         done
      fi
   done
   #</EnableArps>
}

# ---------------------------------------------------------------
# function: erasefw
# args    : None
# description:
#   clean up the firewall so that any one can talk to us in any
#   interface except x-connect.
# ---------------------------------------------------------------

erasefw( )
{
   ChainName=firewall
   ExtendedChainName=xchcom
   ExtendedStrictChain=allcom



   #<GetNodeSpecificDev>
      nodesep="`cfgread node_separation`"
      if [ "$mynode" = "$primhost" ];
      then
         nafosigdev="`cfgread nafo1| awk '{ print $2 }'`"
         nafosignm="`cfgread nafo1| awk '{ print $6 }'`"
         nafosigsn="`cfgread nafo1| awk '{ print $7 }'`"
         defaultgw="`cfgread default_router`"
         defaultv6gw="`cfgread default_router_1_ipv6`"
         defaultv6sn="`cfgread subnet_1_ipv6`"
         defaultv6snmask="`echo $defaultv6sn | sed -e 's/.*\///g'`"
         defaultv6snmask=${defaultv6snmask:-"64"}
         if [ "$extraBuildid" \> "08.00" ]
         then
         primvipv6="`cfgread sip_ipv6_node1`"
         secvipv6="`cfgread sipmtls_ipv6_node1`"
         partnerprimvipv6="`cfgread sip_ipv6_node2`"
         partnersecvipv6="`cfgread sipmtls_ipv6_node2`"
	 else 
         primvipv6="`cfgread sipsm1_vipV6`"
         secvipv6="`cfgread sipsm3_vipV6`"
         partnerprimvipv6="`cfgread sipsm2_vipV6`"
         partnersecvipv6="`cfgread sipsm4_vipV6`"
         fi
         nafosiggw="`cfgread signaling_1_gateway`"
         routeprefix="first_node_r"
         routev6prefix="first_node_v"
      else
         nafosigdev="`cfgread nafo1| awk '{ print $3 }'`"
         nafosignm="`cfgread nafo1| awk '{ print $9 }'`"
         nafosigsn="`cfgread nafo1| awk '{ print $10 }'`"
         defaultgw="`cfgread default_router_2`"
         defaultv6gw="`cfgread default_router_2_ipv6`"
         defaultv6sn="`cfgread subnet_2_ipv6`"
         defaultv6snmask="`echo $defaultv6sn | sed -e 's/.*\///g'`"
         defaultv6snmask=${defaultv6snmask:-"64"}
         if [ "$extraBuildid" \> "08.00" ]
         then
         primvipv6="`cfgread sip_ipv6_node2`"
         secvipv6="`cfgread sipmtls_ipv6_node2`"
         partnerprimvipv6="`cfgread sip_ipv6_node1`"
         partnersecvipv6="`cfgread sipmtls_ipv6_node1`"
         else
         primvipv6="`cfgread sipsm2_vipV6`"
         secvipv6="`cfgread sipsm4_vipV6`"
         partnerprimvipv6="`cfgread sipsm1_vipV6`"
         partnersecvipv6="`cfgread sipsm3_vipV6`"
         fi 
         nafosiggw="`cfgread signaling_2_gateway`"
         routeprefix="second_node_r"
         routev6prefix="second_node_v"
      fi
      if [ "$nafosigdev" = "" ];
      then
         textncolor $BoldCyan "join8k:Wow. What is this system?"
         exit $FAIL
      fi
      mapnafodev nafosigtag $nafosigdev
      sigbondset="$nafosigdev `cfgread $nafosigtag`"
   #</GetNodeSpecificDev>

   {
      echo "[join8k] Checking firewall."
      
      ${IPTABLESPATH}iptables -L $ChainName || ${IPTABLESPATH}iptables -L $ExtendedChainName || ${IPTABLESPATH}iptables -L $ExtendedStrictChain || ifconfig $nafosigdev | grep -q NOARP || return
   } 1>>$LOGFILE 2>&1

   #<ReSetupFw>
   {
      ${IPTABLESPATH}iptables -D INPUT      -p all -j $ChainName
      ${IPTABLESPATH}iptables -D OUTPUT     -p all -j $ChainName
      ${IPTABLESPATH}iptables -D FORWARD    -p all -j $ChainName
      ${IPTABLESPATH}iptables -D $ExtendedChainName -p all -j $ExtendedStrictChain
      ${IPTABLESPATH}iptables -F $ExtendedStrictChain
      ${IPTABLESPATH}iptables -X $ExtendedStrictChain
      ${IPTABLESPATH}iptables -D $ChainName -p all -j $ExtendedChainName
      ${IPTABLESPATH}iptables -F $ExtendedChainName
      ${IPTABLESPATH}iptables -X $ExtendedChainName
      ${IPTABLESPATH}iptables -F $ChainName
      ${IPTABLESPATH}iptables -X $ChainName
   } 2>/dev/null
   #</ReSetupFw>

#      #<ReSetupIPv6Fw>
#   {
#      ${IPTABLESPATH}ip6tables -D INPUT      -p all -j $ChainName
#      ${IPTABLESPATH}ip6tables -D OUTPUT     -p all -j $ChainName
#      ${IPTABLESPATH}ip6tables -D FORWARD    -p all -j $ChainName
#      ${IPTABLESPATH}ip6tables -D $ExtendedChainName -p all -j $ExtendedStrictChain
#      ${IPTABLESPATH}ip6tables -F $ExtendedStrictChain
#      ${IPTABLESPATH}ip6tables -X $ExtendedStrictChain
#      ${IPTABLESPATH}ip6tables -D $ChainName -p all -j $ExtendedChainName
#      ${IPTABLESPATH}ip6tables -F $ExtendedChainName
#      ${IPTABLESPATH}ip6tables -X $ExtendedChainName
#      ${IPTABLESPATH}ip6tables -F $ChainName
#      ${IPTABLESPATH}ip6tables -X $ChainName
#   } 2>/dev/null
#   #</ReSetupIPv6Fw>



   for devidx in $sigbondset
   do
      logstr "   - Enabling interface $devidx"
      ifconfig  $devidx up
      if [ $? -ne 0 ];
      then
         logstr "join8k:Sorry, cant bring $devidx up."
      fi
      vdevlist=`ifconfig -a | grep $devidx | awk '{ print $1 }'`
      for vdevidx in $vdevlist
      do
         ifconfig  $vdevidx up
         if [ $? -ne 0 ];
         then
            logstr "join8k:Sorry, cant bring $vdevidx up."
         fi
      done
   done
 
   #<DeleteArpGw>
      if [ "$defaultgw" != "" ];
      then
         logstr "   - Deleting arp cache for $defaultgw."
         {
            arp -d $defaultgw 
            kver=`uname -r`
            if [ "$kver" \< "3.0.101" ];
            then
               arp -s $defaultgw "00:00:00:00:00:00"
            else
               arp -s $defaultgw "00:00:00:01:02:03"
            fi
            arp -d $defaultgw
         } 1>>$LOGFILE 2>&1
      fi
      if [ "$nafosiggw" != "" ];
      then
         logstr "   - Deleting arp cache for $nafosiggw."
         {
            arp -d $nafosiggw 
            kver=`uname -r`
            if [ "$kver" \< "3.0.101" ];
            then
               arp -s $nafosiggw "00:00:00:00:00:00"
            else
               arp -s $nafosiggw "00:00:00:01:02:03"
            fi
            arp -d $nafosiggw
         } 1>>$LOGFILE 2>&1
      fi
   #</DeleteArpGw>

   #<DeleteIfArp>
      if [ "$nafosigdev" != "" ];
      then
         nafosigknown=`arp -nv -i $nafosigdev | awk -v device=$nafosigdev '{ if ( $5 == device ) print $1 }'`
         for knownidx in $nafosigknown
         do
            logstr "   - Deleting arp cache for $knownidx"
            arp -d $knownidx 1>>$LOGFILE 2>&1
         done
      fi
   #</DeleteIfArp>
   
   #<RebuildV6If>
      if [ "$primvipv6" != "" ];
      then
         logstr "   - Adding primary IpV6 address for ($primvipv6/$nafosigdev)."
         ifconfig $nafosigdev inet6 add ${primvipv6}/${defaultv6snmask} 1>>$LOGFILE 2>&1
      fi
      if [ "$secvipv6" != "" ];
      then
         logstr "   - Adding secondary IpV6 address for ($secvipv6/$nafosigdev)."
         ifconfig $nafosigdev inet6 add ${secvipv6}/${defaultv6snmask} 1>>$LOGFILE 2>&1
      fi
      if [ "$testbed" = "cluster" -a "$nodesep" = "none" ];
      then
         if [ "$partnerprimvipv6" != "" ];
         then
            logstr "   - Adding partner primary IpV6 address for ($partnerprimvipv6/$nafosigdev)."
            ifconfig $nafosigdev inet6 add ${partnerprimvipv6}/${defaultv6snmask} 1>>$LOGFILE 2>&1
         fi
         if [ "$partnersecvipv6" != "" ];
         then
            logstr "   - Adding partner secondary IpV6 address for ($partnersecvipv6/$nafosigdev)."
            ifconfig $nafosigdev inet6 add ${partnersecvipv6}/${defaultv6snmask} 1>>$LOGFILE 2>&1
         fi
      fi
   #</RebuildV6If>

   #<DefaultRoute>
      logstr "   - Adding back default routes."
      {
         ip route show
         ip rule show
         if [ "$defaultgw" != "" -a "$defaultgw" != "0.0.0.0" ];
         then
            route add default gw $defaultgw
         fi
         if [ "$defaultv6sn" != "" ];
         then
             route --inet6 add $defaultv6sn dev $nafosigdev
         fi
         if [ "$defaultv6gw" != "" ];
         then
            route --inet6 add default gw $defaultv6gw
         fi
      } 1>>$LOGFILE 2>&1
      logstr "   - Adding back network routes."
      {
         #<ipv4routes> 
         count=1
         while ( true )
         do
            nextroute="`cfgread ${routeprefix}${count}`"
            if [ "$nextroute" = "" ];
            then
               break;
            fi
            echo $nextroute | grep -q nafo1
            if [ $? -eq 0 ];
            then
               echo "   - Adding ${routeprefix}${count}."
               nextnw="`echo $nextroute | awk '{ print $1 }'`"
               nextnm="`echo $nextroute | awk '{ print $2 }'`"
               nextgw="`echo $nextroute | awk '{ print $3 }'`"
               if [ "$nextgw" != "0.0.0.0" ];
               then
                  route add -net $nextnw netmask $nextnm gw $nextgw dev $nafosigdev
               else
                  route add -net $nextnw netmask $nextnm dev $nafosigdev
               fi
            fi
            count=`expr $count + 1`
         done
         #</ipv4routes> 

         #<ipv6routes> 
         count=1
         while ( true )
         do
            nextroute="`cfgread ${routev6prefix}${count}`"
            if [ "$nextroute" = "" ];
            then
               break;
            fi
            echo $nextroute | grep -q nafo1
            if [ $? -eq 0 ];
            then
               echo "   - Adding ${routev6prefix}${count}."
               nextnw="`echo $nextroute | awk '{ print $1 }'`"
               nextgw="`echo $nextroute | awk '{ print $2 }'`"
               if [ "$nextgw" != "0.0.0.0" ];
               then
                  route --inet6 add $nextnw gw $nextgw dev $nafosigdev
               else
                  route --inet6 add $nextnw dev $nafosigdev
               fi
            fi
            count=`expr $count + 1`
         done
         #</ipv6routes> 
      } 1>>$LOGFILE 2>&1
   #</DefaultRoute>

   #<RestoreRtTables>
      ROUTEINFO=/repository/rttables
      if [ "$isGoogleCloudPlatform" = "true" ]; then
         logstr "   - Google Cloud Platform, skipping restoring network routes."
      else
          for rtidx in `find $ROUTEINFO -name \*.${buildid}.cmd -type f`
          do
             ${rtidx}
          done 1>>$LOGFILE 2>&1
      fi
      rm -rf $ROUTEINFO
   #</RestoreRtTables>

   #<EnableIpFw>
      ipfwlist="                                                                  \
         /proc/sys/net/ipv4/conf/all/accept_redirects:/tmp/ipv4_accept_redirects  \
         /proc/sys/net/ipv4/conf/all/send_redirects:/tmp/ipv4_send_redirects      \
         /proc/sys/net/ipv6/conf/all/accept_redirects:/tmp/ipv6_accept_redirects  \
         /proc/sys/net/ipv6/conf/all/send_redirects:/tmp/ipv6_send_redirects      \
      "

      for ipfwlistidx in $ipfwlist
      do
         sysparm=`echo $ipfwlistidx | awk -F':' '{ print $1 }'`
         sysfile=`echo $ipfwlistidx | awk -F':' '{ print $2 }'`
         if [ -f $sysfile ];
         then
            cat $sysfile > $sysparm
            rm -f $sysfile
         fi
      done
   #</EnableIpFw>

   #<EnableArps>
      enablearp
      enablearp 16 1>>$LOGFILE 2>&1
   #</EnableArps>

   #<EnableSnort>
     logstr "   - Enabling snort."
     systemctl start IDS.service 1>/dev/null 2>&1 || \
     logstr "join8k: Failed to start IDS service"
   #</EnableSnort>

   #<xChannelCtl>
      if [ -x /unisphere/srx3000/callp/bin/xChannelCtl ];
      then
         /unisphere/srx3000/callp/bin/xChannelCtl JOIN
      fi
   #</xChannelCtl>

}



ARGLIST="$*"
initvars
{
   echo "join8k: `date`"
   echo "join8k: Firewall before join8k $ARGLIST."
   ${IPTABLESPATH}iptables -nL
   echo "join8k: Firewall for IPv6 befire join8k $ARGLIST."
   ${IPTABLESPATH}ip6tables -nL
} 1>>$LOGFILE 2>&1

extraBuildid=`/sbin/cfgread "# VERSION" |awk {'print $1'}`

while [ "$#" -gt "0" ];
do
   case $1 in
      -nfw)
         textncolor $BoldCyan "The firewall on current 8k($mynode) will be removed."
         erasefw
         ;;
      -fwxch)
         textncolor $BoldCyan "The firewall on xchannel on current 8k($mynode) will be applied."
         split8k -fwxch
         ;;
      -join)
         joinsys
         ;;
      *)
         textncolor $BoldCyan "Sorry, Unknown option."
         echo "Usage: join8k [-nfw]"
         exit $FAIL
         ;;
   esac
   shift
done
{
   echo "join8k: `date`"
   echo "join8k: Firewall after join8k $ARGLIST."
   ${IPTABLESPATH}iptables -nL
   echo "join8k: Firewall for IPv6 after join8k $ARGLIST."
  ${IPTABLESPATH}ip6tables -nL
} 1>>$LOGFILE 2>&1
echo "Done."
exit $SUCCESS

