#!/bin/sh
# IBM(c) 2011EPL license http://www.eclipse.org/legal/epl-v10.html

#-------------------------------------------------------------------------------
#=head1  routeop  
#=head2  routeop is called by makeroutes command and setuproutes postscript to
#        setup a route on a node.    
#        The syntax is:
#          routeop add/delete net mask gateway ifname
#=cut
#-------------------------------------------------------------------------------

op=$1

net=$2
mask=$3
gw=$4
if [ -n "$5" ]; then
    ifname=$5
fi

function debianpreconf(){
    #create the config sub dir
    if [ ! -d "/etc/network/interfaces.d" ];then
        mkdir -p "/etc/network/interfaces.d"
    fi
    #search xcat flag
    XCATFLAG=`grep "#XCAT_CONFIG" /etc/network/interfaces`
    if [ -n "$XCATFLAG" ];then
        return
    fi

    #back up the old interface configure
    if [ ! -e "/etc/network/interfaces.bak" ];then
        mv /etc/network/interfaces /etc/network/interfaces.bak
    fi

    #create the new config file
    echo "#XCAT_CONFIG" > /etc/network/interfaces
    echo "source /etc/network/interfaces.d/*" >> /etc/network/interfaces

    CONFFILE=''

    #read the backfile
    cat /etc/network/interfaces.bak | while read LINE
    do
        if [ ! "$LINE" ];then
            continue
        fi
        FIRSTCHAR=${LINE:0:1}
        if [ $FIRSTCHAR = '#' ];then
            continue
        fi

        CONFTYPE=`echo $LINE | cut -d" " -f1`
        if [ $CONFTYPE = 'auto' -o $CONFTYPE = 'allow-hotplug' ];then
            LINE=${LINE#$CONFTYPE}
            for NICNAME in $LINE; do
                echo "$CONFTYPE $NICNAME" > "/etc/network/interfaces.d/$NICNAME"
            done
        elif [ $CONFTYPE = 'iface' -o $CONFTYPE = 'mapping' ];then
            #find out the nic name, should think about the eth0:1
            NICNAME=`echo $LINE | cut -d" " -f 2 | cut -d":" -f 1`
            CONFFILE="/etc/network/interfaces.d/$NICNAME"
            if [ ! -e $CONFFILE ];then
                echo "auto $NICNAME" > $CONFFILE
            fi

            #write lines into the conffile
            echo $LINE >> $CONFFILE
        else
            echo $LINE >> $CONFFILE
        fi

    done
}

route_exists()
{
    net=$1
    mask=$2
    gw=$3
    ret=0

    if [ -n "$4" ]; then
        ifname=$4
    fi

    os_type=$(uname -s)

    # ipv6
    if echo $net | grep : 2>&1 1>/dev/null
    then
        result=`ip -6 route show $net/$mask`
        if [ $? -ne 0 ] || [ -z "$result" ]
        then
            ret=0
        else
            ret=1
        fi
    else
        result=`netstat -nr|grep $net`;
        if [ $? -eq 0 ] && [ -n "$result" ]; then
            for x in `echo "$result"|tr -s " " ","`
                do
                if [ "$os_type" = "Linux" ]; then
                    net1=`echo $x|cut -d',' -f1`
                    gw1=`echo $x|cut -d',' -f2`
                    mask1=`echo $x|cut -d',' -f3`
                    ifname1=`echo $x|cut -d',' -f8`
                    if [ "$net" = "$net1" ] && [ "$mask" = "$mask1" ] && [ "$gw" = "$gw1" ] && [ "$ifname" = "$ifname1"  ]; then
                        ret=1
                        break
                    fi
                else
                    tmp1=`echo $x|cut -d',' -f1`
                    gw1=`echo $x|cut -d',' -f2`

                    n1=`echo $net |cut -d'.' -f1`           
                    n2=`echo $net |cut -d'.' -f2`           
                    n3=`echo $net |cut -d'.' -f3`           
                    n4=`echo $net |cut -d'.' -f4`

                    netnum="$(( ($n1 << 24) + ($n2 << 16) + ($n3 << 8) + $n4 ))"
                    bits=32
                    while [ `expr $netnum % 2` -eq 0 ]
                    do
                        bits="$(( $bits - 1 ))"
                        netnum="$(( $netnum >> 1 ))"
                    done
                
                    tmp2="$net/$bits";
                    #echo "$tmp2=$tmp2"
                    if [ "$tmp1" = "$tmp2" ] && [ "$gw" = "$gw1" ]; then
                        ret=1
                        break
                    fi
                fi
                done
        fi
    fi
    
    echo $ret
}

add_persistent_route() 
{
    net=$1;
    mask=$2;
    gw=$3;
    if [ -n "$4" ]; then
        ifname=$4
    fi

    xcat_config_start="# xCAT_CONFIG_START";
    xcat_config_end="# xCAT_CONFIG_END";

    if [ "$(uname -s)" = "Linux" ]; then
    #determine the os name
    OS_name="something"
    if [ -f /etc/redhat-release ]
    then
        OS_name="redhat"  #it can be RedHatFerdora or CentOS
    elif [ -f /etc/SuSE-release ]
    then
        OS_name="sles"
    else
        OS_name="debian"
    fi

    case $OS_name in
        sles)
        #echo "sles"
        # ipv6 net
        filename="/etc/sysconfig/network/routes";
        if echo $net | grep : 2>&1 1>/dev/null
        then
	    if [ $gw_ip = "" -o $gw_ip = "0.0.0.0" ] ; then
                route="$net/$mask 0.0.0.0 - $ifname"
                route1="$net\/$mask 0.0.0.0 - $ifname";
	    else
                route="$net/$mask $gw - -"
                route1="$net\/$mask $gw - -";
	    fi
        else
	    if [ $gw_ip = "" -o $gw_ip = "0.0.0.0" ] ; then
                route="$net 0.0.0.0 $mask $ifname";
                route1="$net 0.0.0.0 $mask $ifname";
	    else
                route="$net $gw $mask $ifname";
                route1="$net $gw $mask $ifname";
	    fi
        fi
        if [ -f $filename ]; then
            grep "$route" $filename 2>&1 1>/dev/null
            if [ $? -ne 0 ]; then #route does not exist
            grep "$xcat_config_start" $filename 2>&1 1>/dev/null
            if [ $? -ne 0 ]; then #no xCAT section
                echo $xcat_config_start >> $filename
                echo $route >> $filename
                echo $xcat_config_end >> $filename
            else
                sed -i -e s/"$xcat_config_end"/"$route1\n$xcat_config_end"/g $filename
            fi
            echo "Persistent route \"$route\" added in $filename."
            else 
            echo "Persistent route \"$route\" already exists in $filename."
            fi
        else
            #echo "got here"
            echo "$xcat_config_start" > $filename
            echo "$route" >> $filename
            echo "$xcat_config_end" >> $filename
            echo "Route \"$route\" added in $filename."
        fi

        ;;
        debian)
            debianpreconf
            matchstr=""
            v6flag=0
            #on debian/ubuntu need the network device name
            if [ ! $ifname ];then
                ifname=`netstat -nr | grep "$net" | awk '{print $8}' | head -1`
            fi
            filename="/etc/network/interfaces.d/$ifname"

            if [ ! -f $filename ];then
                echo "auto $ifname" > $filename
                echo "iface $ifname inet dhcp" >> $filename
            fi
            echo $net | grep : 2>&1 1>/dev/null
            #ipv6
            if [ $? -eq 0 ];then
		if [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then
                    matchstr="$net/$mask dev $ifname"
		else
                    matchstr="$net/$mask gw $gw"
                fi
                v6flag=1
            else
		if [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then
                    matchstr="net $net netmask $mask dev $ifname"
		else
                    matchstr="net $net netmask $mask gw $gw"
		fi
            fi

            grep "$matchstr" $filename 2>&1 1>/dev/null
            if [ $? -ne 0 ];then
                foundflag=0
                tempfile="/etc/network/interfaces.d/tmp"
                while read LINE
                do
                    echo $LINE | grep "iface" 2>&1 1>/dev/null
                    if [ $? -eq 0 -a $foundflag -eq 1 ];then
                        foundflag=0
                        if [ $v6flag -eq 1 ];then
		            if [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then
                                echo "  up route -A inet6 add $net/$mask dev $ifname" >> $tempfile
                                echo "  down route -A inet6 del $net/$mask dev $ifname" >> $tempfile
			    else
                                echo "  up route -A inet6 add $net/$mask gw $gw" >> $tempfile
                                echo "  down route -A inet6 del $net/$mask gw $gw" >> $tempfile
		            fi
                        else
		            if [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then
			        echo "  up route add -net $net netmask $mask dev $ifname" >> $tempfile
			        echo "  down route del -net $net netmask $mask dev $ifname" >> $tempfile
			    else
                                echo "  up route add -net $net netmask $mask gw $gw" >> $tempfile
                                echo "  down route del -net $net netmask $mask gw $gw" >> $tempfile
			    fi
                        fi
                    fi
                    echo $LINE | grep "iface $ifname " 2>&1 1>/dev/null
                    #this is the last line of the device
                    if [ $? -eq 0 ];then
                        foundflag=1
                    fi

                    echo $LINE >> $tempfile
                done < $filename
                #the insert place is the last line of the config file
                if [ $foundflag -eq 1 ];then
                    if [ $v6flag -eq 1 ];then
		        if [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then
                            echo "  up route -A inet6 add $net/$mask dev $ifname" >> $tempfile
                            echo "  down route -A inet6 del $net/$mask dev $ifname" >> $tempfile
			else
                            echo "  up route -A inet6 add $net/$mask gw $gw" >> $tempfile
                            echo "  down route -A inet6 del $net/$mask gw $gw" >> $tempfile
			fi
                    else
		        if [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then
			    echo "  up route add -net $net netmask $mask dev $ifname" >> $tempfile
			    echo "  down route del -net $net netmask $mask dev $ifname" >> $tempfile
			else
                            echo "  up route add -net $net netmask $mask gw $gw" >> $tempfile
                            echo "  down route del -net $net netmask $mask gw $gw" >> $tempfile
			fi
                    fi 
                fi
                mv -f $tempfile $filename
                echo "Persistent route \"$matchstr\" added in $filename."
            else
                echo "Persisten route \"$match\" already exists in $filename"
            fi
        ;;
        redhat)
        #echo "rh/fedora/centos"
        # ipv6 net
        if echo $net | grep : 2>&1 1>/dev/null
        then
            if [ "$gw" = "" ] ; then
	        $gw = "0.0.0.0";
            fi
            filename="/etc/sysconfig/static-routes-ipv6";
            route="$ifname $net/$mask $gw";
            # $net/mask does not work with sed cmd
            route1="$ifname $net\/$mask $gw";
        else
            filename="/etc/sysconfig/static-routes";
            if [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then
               route="any net $net netmask $mask dev $ifname";
               route1="any net $net netmask $mask dev $ifname";
	    else
               route="any net $net netmask $mask gw $gw $ifname";
               route1="any net $net netmask $mask gw $gw $ifname";
	    fi
        fi
        if [ -f $filename ]; then
            grep "$route" $filename 2>&1 1>/dev/null
            if [ $? -ne 0 ]; then #route does not exist
                grep "$xcat_config_start" $filename 2>&1 1>/dev/null
                if [ $? -ne 0 ]; then #no xCAT section
                    echo $xcat_config_start >> $filename
                    echo $route >> $filename
                    echo $xcat_config_end >> $filename
                else
                    sed -i -e s/"$xcat_config_end"/"$route1\n$xcat_config_end"/g $filename
                fi
                echo "Persistent route \"$route\" added in $filename."
            else 
                echo "Persistent route \"$route\" already exists in $filename."
            fi
        else
                #echo "got here"
                echo "$xcat_config_start" > $filename
                echo "$route" >> $filename
                echo "$xcat_config_end" >> $filename
                echo "Persistent route \"$route\" added in $filename."
       fi
      ;;
    esac
    else #AIX
    echo "Adding persistent route on AIX is not supported yet."
    fi
}

rm_persistent_route() 
{
    net=$1;
    mask=$2;
    gw=$3;
    if [ -n "$4" ]; then
        ifname=$4
    fi

    if [ "$(uname -s)" = "Linux" ]; then
    #determine the os name
    OS_name="something"
    if [ -f /etc/redhat-release ]
    then
        OS_name="redhat"  #it can be RedHatFerdora or CentOS
    elif [ -f /etc/SuSE-release ]
    then
        OS_name="sles"
    else
        OS_name="debian"
    fi

    case $OS_name in
        sles)
        #echo "sles"
        filename="/etc/sysconfig/network/routes";
        # ipv6 net
        if echo $net | grep : 2>&1 1>/dev/null
        then
	    if [ $gw = "" -o $gw = "0.0.0.0" ] ; then
                route="$net/$mask 0.0.0.0 - $ifname";
                route1="$net\/$mask 0.0.0.0 - $ifname";
	    else
                route="$net/$mask $gw - -";
                route1="$net\/$mask $gw - -";
	    fi
        else
	    if [ $gw = "" ] ; then
	        $gw = "0.0.0.0";
            fi
            if [ -n "$ifname" ]; then
                route="$net $gw $mask $ifname";
                route1="$net $gw $mask $ifname";
            else
                route="$net $gw $mask -";
                route1="$net $gw $mask -";
            fi
        fi
        if [ -f $filename ]; then
            grep "$route" $filename 2>&1 1>/dev/null
            if [ $? -ne 0 ]; then # Does not exist in file
                echo "Persistent route \"$route\" does not exist in $filename."
            else
                sed -i -e s/"$route1"//g $filename
                echo "Persistent route \"$route\" removed from $filename."
            fi
        else
            echo "Persistent route file $filename does not exist."
        fi
        ;;
        debian)
            debianpreconf
            matchstr=""
            v6flag=0
            #on debian/ubuntu need the network device name
            if [ ! $ifname ];then
                ifname=`netstat -nr | grep "$net" | awk '{print $8}'`
            fi
            filename="/etc/network/interfaces.d/$ifname"

            echo $net | grep : 2>&1 1>/dev/null
            #ipv6
            if [ $? -eq 0 ];then
	        if [ $gw = "" -o $gw = "0.0.0.0" ] ; then
                    matchstr="$net/$mask dev $ifname"
		else
                    matchstr="$net/$mask gw $gw"
		fi
                v6flag=1
            else
	        if [ $gw = "" -o $gw = "0.0.0.0" ] ; then
                    matchstr="net $net netmask $mask dev $ifname"
		else
                    matchstr="net $net netmask $mask gw $gw"
		fi
            fi

            grep "$matchstr" $filename
            if [ $? -eq 0 ];then
                sed -i -e "/$matchstr/d" $filename
                echo "Persistent route \"$matchstr\" removed from $filename."
            else
                echo "Persistent route \"$matchstr\" does not exist in $filename."
            fi
        ;;
        redhat)
        #echo "rh/fedora/centos"
        #ipv6
        if echo $net | grep : 2>&1 1>/dev/null
        then
            filename="/etc/sysconfig/static-routes-ipv6";
            # $net/$mask does not work with sed
            if [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then
                route="$ifname $net\/$mask 0.0.0.0"
                route1="$ifname $net/$mask 0.0.0.0"
	    else
                route="$ifname $net\/$mask $gw"
                route1="$ifname $net/$mask $gw"
	    fi
        else
            filename="/etc/sysconfig/static-routes";
            if [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then
               route="any net $net netmask $mask dev $ifname";
               route1="any net $net netmask $mask dev $ifname";
            else
               route="any net $net netmask $mask gw $gw $ifname";
               route1="any net $net netmask $mask gw $gw $ifname";
            fi
        fi
        if [ -f $filename ]; then
            grep "$route" $filename 2>&1 1>/dev/null
            if [ $? -ne 0 ]; then # Does not exist in file
                echo "Persistent route \"$route1\" does not exist in $filename."
            else
                sed -i -e s/"$route"//g $filename
                echo "Persistent route \"$route1\" removed from $filename."
            fi
        else
            echo "Persistent route file $filename does not exist."
        fi
        ;;
    esac
    else #AIX
    echo "Removing persistent route on AIX is not supported yet."
    fi
}
   


if [ "$op" = "add" ]; then
    result=$(route_exists $net $mask $gw)
    if [ "$result" = "0" ]; then
        #ipv6
        if echo $net | grep : 2>&1 1>/dev/null
        then
            if [ "$(uname -s)" = "Linux" ]; then
	        if [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then
                    cmd="ip -6 route add $net/$mask dev $ifname"
		else
                    cmd="ip -6 route add $net/$mask via $gw"
		fi
            else 
                # AIX TODO 
                cmd="ip -6 route add $net/$mask via $gw"
            fi
        else
            if [ "$(uname -s)" = "Linux" ]; then
	        if [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then
                    cmd="route add -net $net netmask $mask dev $ifname"
		else
                    cmd="route add -net $net netmask $mask gw $gw"
		fi
            else 
                cmd="route add -net $net -netmask $mask $gw"
            fi
        fi
        echo "Adding temporary route: $cmd"
        result=`$cmd 2>&1`
        code=$?
        if [ $code -ne 0 ]; then
            logger -t xCAT -p local4.err "$cmd\nerror code=$code, result=$result."
            echo "  error code=$code, result=$result."
            if [ -f "/etc/debian_version" ];then
                exit 1;
            fi
        fi
    else
        #ipv6
        if echo $net | grep : 2>&1 1>/dev/null
        then
            echo "The temporary route ($net/$mask $gw) already exists."
        else
            echo "The temporary route ($net $mask $gw) already exists."
        fi
    fi  
  
    #add persistent route
    add_persistent_route $net $mask $gw $ifname
elif [ "$op" = "delete" ]; then
    result=$(route_exists $net $mask $gw)
    if [ "$result" = "1" ]; then
        # ipv6
        if echo $net | grep : 2>&1 1>/dev/null
        then
            if [ "$(uname -s)" = "Linux" ]; then
	        if [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then
                    cmd="ip -6 route delete $net/$mask dev $ifname"
		else
                    cmd="ip -6 route delete $net/$mask via $gw"
		fi
            else 
                # AIX TODO
                cmd="ip -6 route delete $net/$mask via $gw"
            fi
        else
            if [ "$(uname -s)" = "Linux" ]; then
	        if [ "$gw" = "" -o "$gw" = "0.0.0.0" ] ; then
                    cmd="route delete -net $net netmask $mask dev $ifname"
		else
                    cmd="route delete -net $net netmask $mask gw $gw"
		fi
            else 
                cmd="route delete -net $net -netmask $mask $gw"
            fi
        fi

        echo "Removing temporary route: $cmd"
        result=`$cmd 2>&1`
        code=$?
        if [ $code -ne 0 ]; then
            logger -t xCAT  -p local4.err "$cmd\nerror code=$code, result=$result."
            echo "  error code=$code, result=$result."
        fi
    else
        echo "The temporary route ($net $mask $gw) does not exist."
    fi
    
    #remove the persistent route
    rm_persistent_route $net $mask $gw $ifname
fi
exit 0