#!/sbin/sh
#
# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#
#ident	"@(#)nhcgtps	1.14	06/01/23 SMI"
#
# the script exists immediately if CMM.UseCGTP!=True

NH_INCLUDE=/etc/opt/SUNWcgha/init.d/nhinclude.sh
. $NH_INCLUDE

PROG=`basename $0`

NHCONFDIR=/etc/opt/SUNWcgha
USER_FILE=/etc/opt/SUNWcgha/nhfs.conf

AWK=/usr/bin/awk
IFCONFIG=/usr/sbin/ifconfig
ROUTE=/usr/sbin/route
GREP=/usr/bin/grep
PGREP=/usr/bin/pgrep
CAT=/usr/bin/cat
UNAME=/usr/bin/uname
NHGETCONF=/opt/SUNWcgha/sbin/nhgetconf
NHNETCFG=/opt/SUNWcgha/sbin/nhnetcfg

# Tune TCP parameters to decrease NFS client downtime.
/usr/sbin/ndd -set /dev/tcp tcp_rexmit_interval_initial 100
/usr/sbin/ndd -set /dev/tcp tcp_rexmit_interval_min 400
/usr/sbin/ndd -set /dev/tcp tcp_rexmit_interval_max 400

# the code of the function wait_for_dhcp is also present in nhcgtp
# (CGTP for NHAS diskless). Do not forget to make change in both
# scripts

wait_for_dhcp () {

    # Get name of the network interfaces
    nic0=`$NHGETCONF -u file://$USER_FILE -s Node.Nic0`	\
    || error "Property \"Node.Nic0\" not found in $USER_FILE"

    nic1=`$NHGETCONF -u file://$USER_FILE -s Node.Nic1`	\
    || error "Property \"Node.Nic1\" not found in $USER_FILE"

    $NH_ECHO "Waiting for DHCP interfaces to be configured\c"

    # wait until both interfaces has been configured
    nic0_done=0
    nic1_done=0
    loop=20
    end=0
    while [ ${end} -eq 0 ]
    do
	$NH_ECHO ".\c"

	# check if the interfaces have been configured
	if [ ${nic0_done} -eq 0 ]
	then
	    result=`$IFCONFIG ${nic0} | $GREP -c 0.0.0.0`
	    if [ ${result} -eq 0 ]
	    then
		nic0_done=1
		$NH_ECHO "\n${nic0} configured."
	        if [ ${nic1_done} -eq 0 ]; then
		    $NH_ECHO "Waiting for ${nic1} to be configured.\c"
		fi
	    fi
	fi
	if [ ${nic1_done} -eq 0 ]
	then
	    result=`$IFCONFIG ${nic1} | $GREP -c 0.0.0.0`
	    if [ ${result} -eq 0 ]
	    then
		nic1_done=1
		$NH_ECHO "\n${nic1} configured."
	        if [ ${nic0_done} -eq 0 ]; then
		    $NH_ECHO "Waiting for ${nic0} to be configured.\c"
		fi
	    fi
	fi

	# if still not done, make some actions
	if [ ${nic0_done} -eq 0 ] || [ ${nic1_done} -eq 0 ]
	then
	    # check if dhcpagent is still there
	    result=`$PGREP -x dhcpagent`
	    if [ -z "${result}" ]
	    then
		    error "dhcpagent not present"
		    exit $NH_EXIT_ERROR
	    fi

	    # do not loop forever
	    loop=`expr ${loop} - 1`
	    if [ ${loop} -le 0 ]
	    then
		$NH_ECHO "timeout: interface not initialized by DHCP"
		end=1
	    else
		# wait before looping
		sleep 1
            fi
	 else
	    end=1
	 fi
    done

    # by default, dhcpinfo will use nic0 as the primary interface
    # whatever the boot interface.
    # if nic0 is not configured by DHCP at startup, the DHCP info will not be
    # available on nic0 but on nic1
    # -> use nic1 for all dhcpinfo requests.

    dhcp_itf=${nic0}
    if [ ${nic0_done} -eq 0 ]; then
	# nic1 is the DHCP interface
	dhcp_itf=${nic1}
	local_nic0_addr=`/sbin/dhcpinfo -i ${dhcp_itf} NhNic0Addr 2> /dev/null`
        $NH_ECHO "Forcing ${nic0} configuration"
	$IFCONFIG ${nic0} ${local_nic0_addr} netmask + broadcast + up
    fi
    if [ ${nic1_done} -eq 0 ]; then
	local_nic1_addr=`/sbin/dhcpinfo -i ${dhcp_itf} NhNic1Addr 2> /dev/null`
        $NH_ECHO "Forcing ${nic1} configuration"
	$IFCONFIG ${nic1} ${local_nic1_addr} netmask + broadcast + up
    fi

    # if the boot interface is nic1, we have to set it as primary dhcp
    # interface, to let dhcpinfo (without -i option) work correctly
    if [ "$nic1" = "$dhcp_itf" ]; then
	$NH_ECHO "Setting $nic1 as dhcp primary interface .. \c"
	$IFCONFIG $nic1 dhcp primary ping
	case $? in
	    0) $NH_ECHO "ok" ;;
	    *) $NH_ECHO "failed" ;;
	esac
    fi
}

diskless_conf () 
{ 

# For diskless nodes, get information from DHCP.
# BootSrvA symbol contains cgtp master dynamic address
# NhCgtpAddr symbol contains : local cgtp addr
# Subnet symbol contains cgtp netmask (assumption is made
# that cgtp netmask is identifical to primary nics one).

    # wait for the interface to be configured
    wait_for_dhcp

    # set the hostname from /etc/nodename
    HOSTNAME=`$CAT /etc/nodename`
    $UNAME -S $HOSTNAME

    local_cgtp_addr=`/sbin/dhcpinfo -i ${dhcp_itf} NhCgtpAddr 2> /dev/null`
    cgtp_netmask=`/sbin/dhcpinfo -i ${dhcp_itf} Subnet 2> /dev/null`
    master_cgtp=`/sbin/dhcpinfo -i ${dhcp_itf} BootSrvA 2> /dev/null`
    router=`/sbin/dhcpinfo -i ${dhcp_itf} Router 2> /dev/null`

    master_nic0=`$NHNETCFG nic0 masterdyn`				\
	|| error "Cannot retrieve master's dynamic NIC0 address"
    master_nic0=`echo ${master_nic0} | $AWK '{print$2}'`

    master_nic1=`$NHNETCFG nic1 masterdyn`				\
	|| error "Can't retrieve master's dynamic NIC1 address"
    master_nic1=`echo ${master_nic1} | $AWK '{print$2}'`

    # add a host route to the IP master address, cannot use setsrc
    # as soon as cgtp0 will be plumbed, we need a proper route (not
    # the default one)

    if [ "${router}" = "${master_nic0}" ]
    then
        #we used nic0 to boot
        $ROUTE add  ${master_cgtp} ${master_nic0} -multirt
        cgtpintf_plumb ${local_cgtp_addr} 
        # now the CGTP address is configured, use setsrc
        cgtp_route_add ${master_nic1} 
        #this route is already partialy configured
        cgtp_route_update ${master_nic0}
    else
        #we used nic1 to boot
        $ROUTE add  ${master_cgtp} ${master_nic1} -multirt
        cgtpintf_plumb ${local_cgtp_addr} 
        # now the CGTP address is configured, use setsrc
        cgtp_route_add ${master_nic0} 
        #this route is already partialy configured
        cgtp_route_update ${master_nic1}
    
    fi

    # create brodcast CGTP routing
    cgtp_broadcast=`$NHNETCFG cgtp broadcast | awk '{print$2}'`  
    nic0_broadcast=`$NHNETCFG nic0 broadcast | awk '{print$2}'`  
    nic1_broadcast=`$NHNETCFG nic1 broadcast | awk '{print$2}'`  
    $ROUTE add ${cgtp_broadcast} ${nic0_broadcast} -multirt -setsrc ${local_cgtp_addr}
    $ROUTE add ${cgtp_broadcast} ${nic1_broadcast} -multirt -setsrc ${local_cgtp_addr}

    # disconnect TCP connections to the master
    # so that NFS re-open it using new CGTP routing
    /opt/SUNWcgha/sbin/tcpdiscs ${master_cgtp}
}


cgtp_route_update () 
{ 
    $ROUTE change ${master_cgtp} $1 -multirt -setsrc ${local_cgtp_addr}
}

cgtp_route_add ()
{
    $ROUTE add  ${master_cgtp} $1 -multirt -setsrc ${local_cgtp_addr}
}

cgtpintf_plumb () 
{ 
    $IFCONFIG ${cgtp_ifname} plumb
    $IFCONFIG ${cgtp_ifname} $1 netmask ${cgtp_netmask} broadcast + up
}


if [ "`$NHGETCONF -u file://$USER_FILE -s Node.UseCGTP | tr '[:lower:]' '[:upper:]'`" != "TRUE" ]
then
    exit $NH_EXIT_OK
fi

# Check the configuration has an entry for Node Type.
Node_type=`$NHGETCONF -u file://$USER_FILE -s Node.Type`
if [ $? != 0 ]
then
    $NH_ECHO "Property \"Node.type\" not found in $USER_FILE"
    $NH_ECHO "Can't configure CGTP routes"
    exit $NH_EXIT_ERROR 
fi

# Get information about type of node and master node floating address
Node_type=`$NHGETCONF -u file://$USER_FILE -s Node.Type | tr '[:lower:]' '[:upper:]'`

# Get CGTP interface name
cgtp_ifname=`$NHGETCONF -u file://$USER_FILE -s Node.NICCGTP`
if [ $? != 0 ]
then
    $NH_ECHO "Property \"Node.NICCGTP\" not found in $USER_FILE"
    $NH_ECHO "Can't configure CGTP routes"
    exit $NH_EXIT_ERROR 
fi


case "${Node_type}" in
'DISKLESS')
        diskless_conf
        ;;
*)
        $NH_ECHO "Wrong value for property \"Node.type\", should be \"Diskless\""
        exit $NH_EXIT_ERROR
        ;;
esac
exit $NH_EXIT_OK

