#!/bin/sh
########################################################################
# Begin /lib/services/ip-static
#
# Description : IPV4 Static Boot Script
#
# Authors     : Nathan Coulson - nathan@linuxfromscratch.org
#               Kevin P. Fleming - kpfleming@linuxfromscratch.org
# Update      : Bruce Dubbs - bdubbs@linuxfromscratch.org
# Update      : Jean-Marc Pigeon jmp@osukiss.org
#
# Version     : OK-9.4
#
########################################################################

. /lib/lsb/init-functions
. ${IFCONFIG}

if [ -z "${PREFIX}" -a -z "${PEER}" -a -z "${NETMASK}" ]; then
   PREFIX=24
   args="${args}${IP}/${PREFIX} "

elif [ -n "${PREFIX}" -a -n "${PEER}" ]; then
   log_failure_msg "\nPREFIX and PEER both specified in ${IFCONFIG}, cannot continue."
   exit 1

elif [ -n "${PREFIX}" ]; then
   args="${args}${IP}/${PREFIX} "

elif [ -n "${PEER}" ]; then
   args="${args}${IP} peer ${PEER} "
fi

if [ -n "${LABEL}" ]; then
   args="${args}label ${LABEL} "
fi

if [ -n "${BROADCAST}" ]; then
   args="${args}broadcast ${BROADCAST} "
fi

if [ -n "${NETMASK}" ]; then
   args="${args}${IP} netmask ${NETMASK} "
fi

if [ -z "${PREFIX6}" ] ; then
  PREFIX6=64
  fi

if [ -n "${HWADDR}" -a "${2}" = "up" ] ; then
  NORMHWADDR=`echo ${HWADDR} | tr '[:upper:]' '[:lower:]'`
  for unit in `ls /sys/class/net`
    do
    if [ ! -L /sys/class/net/$unit ] ; then
      continue
      fi
    unithwaddr=`cat /sys/class/net/$unit/address`
    if [ "${NORMHWADDR}" = "${unithwaddr}" ] ; then
      ip link set $unit name ${1}
      break; 
      fi
    done
  fi

set_vrrp()

{
if [ -n "${VRRP}" ] ; then
  case ${2} in
    "up"	)
      if [ -n "${VRRP_IP}" ] ;then
	INTER=${1}-IP-${VRRP}
        log_info_msg "Creating VRRP IP:${VRRP_IP} interface..."
	(
        ip link add ${INTER} link ${1}			\
		type macvlan				\
		mode bridge &&
        ip link set dev ${INTER}			\
		address 00:00:5e:00:01:${VRRP} &&
	ip addr add ${VRRP_IP} dev ${INTER} &&
        ip link set dev ${INTER} ${2}
	) > /dev/null
        evaluate_retval
	fi
      if [ -n "${VRRP_IP6}" ] ;then
	INTER=${1}-IP6-${VRRP}
        log_info_msg "Creating VRRP IPV6:${VRRP_IP6} interface..."
	(
        ip link add ${INTER} link ${1}			\
		type macvlan				\
	       	mode bridge &&
        ip link set dev ${INTER}			\
       		address 00:00:5e:00:02:${VRRP} &&
	ip addr add ${VRRP_IP6} dev ${INTER} &&
        ip link set dev ${INTER} ${2}
	) > /dev/null
        evaluate_retval
	fi
      ;;
    "down"	)
      if [ -n "${VRRP_IP}" ] ;then
	INTER=${1}-IP-${VRRP}
        log_info_msg "Removing VRRP IP:${VRRP_IP} interface..."
	(
	ip link set dev ${INTER} ${2} &&
	ip link delete ${INTER} link ${1}		\
		addrgenmode random type macvlan		\
		mode bridge
	) > /dev/null
        evaluate_retval
	fi
      if [ -n "${VRRP_IP6}" ] ;then
	INTER=${1}-IP6-${VRRP}
        log_info_msg "Removing VRRP IPV6:${VRRP_IP6} interface..."
	(
        ip link set dev ${INTER} ${2} &&
        ip link delete ${INTER} link ${1}		\
		addrgenmode random type macvlan		\
	       	mode bridge
	) > /dev/null
        evaluate_retval
	fi
      ;;
    esac
  fi
}
#------------------------------------------------------------------
#to set the pysical device
#------------------------------------------------------------------
set_device()

{
case "${2}" in
  up)
    case "${TYPE}" in
      bond	)
	modprobe -q bonding
	#in case the interface is already existing
	/sbin/ip link del ${1} 2> /dev/null
        log_info_msg "Creating the ${1} interface..."
	/sbin/ip link add ${1} type bond
	if [ -n "${BONDING_OPTS}" ] ; then
	  /sbin/ip link set ${1} type bond ${BONDING_OPTS}
	  fi
        evaluate_retval
        ;;
      bridge	)
        log_info_msg "Creating the ${1} interface..."
        brctl addbr ${1}
        evaluate_retval
        for I in ${INTERFACE_COMPONENTS}; do
           log_info_msg "Adding ${I} to ${1}..."
           brctl addif ${1} ${I}
           evaluate_retval
           done
         if is_true ${STP}; then
	   log_info_msg "Setting spanning tree protocol"
           brctl stp ${1} on
           evaluate_retval
           fi
         if is_true ${IP_FORWARD}; then
           log_info_msg "Setting net.ipv4.ip_forward = 1"
           sysctl -w net.ipv4.ip_forward=1 > /dev/null
           evaluate_retval
           fi
        ;;
      sit	)
	if [ -n "${LOCAL_IPV4_ADDR}" -a -n "${REMOTE_IPV4_ADDR}" ] ; then
          log_info_msg "Creating the ${1} interface..."
	  /sbin/ip link						\
		 add ${1}					\
		 type sit					\
		 mode ip6ip					\
		 remote ${REMOTE_IPV4_ADDR}			\
		 local ${LOCAL_IPV4_ADDR}
          evaluate_retval
	  /sbin/ip link						\
		set ${1} up
	  fi
        ;;
      slave	)
	if [ -n "${MASTER}" ] ; then
	  /sbin/ip link set ${1} down
	  log_info_msg "Adding slave device ${1} to master ${MASTER}..."
	  /sbin/ip link set ${1} master ${MASTER}
	  evaluate_retval
	  /sbin/ip link set ${1} up
	  fi
        ;;
      *		)
        log_info_msg "Creating the ${1} interface..."
        ip link set ${1} up
	evaluate_retval
        ;;
      esac
    ;;
  down)
    case "${TYPE}" in
      bond	)
	/sbin/ip link del ${1} type bond
        ;;
      bridge	)
        for I in ${INTERFACE_COMPONENTS}; do
          log_info_msg "Removing ${I} from ${1}..."
          /sbin/ip link set ${I} down &&
          brctl delif ${1} ${I}
          evaluate_retval
          done
        log_info_msg "Bringing down the ${1} interface..."
        /sbin/ip link set ${1} down
        brctl delbr ${1}
        evaluate_retval
        ;;
      slave	)
	if [ -n "${MASTER}" ] ; then
	  log_info_msg "Detaching slave device ${1} from master ${MASTER}..."
	  /sbin/ip link set ${1} nomaster
	  evaluate_retval
	  fi
        ;;
      sit	)
        log_info_msg "Bringing down the ${1} interface..."
        /sbin/ip link set ${1} down
	evaluate_retval
        /sbin/ip link del ${1}
        ;;
      *		)
        log_info_msg "Bringing down the ${1} interface..."
        /sbin/ip link set ${1} down
	evaluate_retval
        ;;
      esac
    ;;
  esac
}
#------------------------------------------------------------------
#to set interface ${1} with IPV4 number
#------------------------------------------------------------------
set_ipv4()

{
case "${2}" in
  up)
	if [ "$(ifconfig  ${1} 2>/dev/null | grep ${IP}/)" = "" ]; then
	  log_info_msg "Adding IPv4 ${args}to ${1} interface..."
	  /sbin/ip addr add ${IP}/${PREFIX} dev ${1}
	  evaluate_retval
	  fi
	;;

  down)
	rdev=`echo ${1} | cut -d ':' -f1`
	log_info_msg "Removing IPv4 ${args}from ${1} interface..."
	# ifconfig ${rdev} ${args} down
	/sbin/ip addr del ${IP}/${PREFIX} dev ${1}
	evaluate_retval
	;;

  esac
}

#------------------------------------------------------------------
#to set interface ${1} with IPV6 number
#------------------------------------------------------------------
set_ipv6()

{
normipv6=`sipcalc -t ${IPV6}| grep Compressed | cut -d '-' -f2 |tr -d ' '`
case "${2}" in
  up)
	add="Adding"
	if [ "$(ifconfig  ${1} 2>/dev/null | grep $normipv6)" = "" ]; then
	  modprobe -q ipv6
	  log_info_msg "$add Main IPv6 ${IPV6}/${PREFIX6} to ${1} interface..."
	  #ifconfig ${1} inet6 add ${IPV6}/${PREFIX6}
	  /sbin/ip -6 addr add ${IPV6}/${PREFIX6} dev ${1}
	  evaluate_retval
          if [ -n "${IPV6SECONDARIES}" ] ; then
	    for ipv6_sec in ${IPV6SECONDARIES} 
	      do
              log_info_msg "$add Secondary IPv6 ${ipv6_sec} to ${1} interface..."
	      #ifconfig ${1} inet6 add ${ipv6_sec}
	      /sbin/ip -6 addr add ${ipv6_sec} dev ${1}
              evaluate_retval
	      done
	    fi
	  fi
	;;

  down)
	rm="Removing"
	if [ "$(ifconfig  ${1} 2>/dev/null | grep $normipv6)" != "" ]; then
          if [ -n "${IPV6SECONDARIES}" ] ; then
	    for ipv6_sec in ${IPV6SECONDARIES} 
	      do
              log_info_msg "$rm Secondary IPv6 ${ipv6_sec} from ${1} interface..."
	      #ifconfig ${1} inet6 del ${ipv6_sec}
	      /sbin/ip -6 addr del ${ipv6_sec} dev ${1}
              evaluate_retval
	      done
	    fi
	  log_info_msg "$rm Main IPv6 ${IPV6}/${PREFIX6} from ${1}..."
	  #ifconfig ${1} ${args} down
	  /sbin/ip -6 addr del ${IPV6}/${PREFIX6} dev ${1}
	  evaluate_retval
	  fi
	;;

  esac
}

#------------------------------------------------------------------
#to set interface ${1} IPV4 static routing
#------------------------------------------------------------------
set_route_ipv4()

{
if [ -n "${GATEWAY}" ]; then
  /sbin/ip link set ${1} up
  case "${2}" in
    up)
	# Set the route default gateway if requested
	add="Adding default gateway"
   	if /sbin/ip route show dev ${1} | grep -q default; then
          log_warning_msg "Gateway already setup; skipping."
   	else
      	  log_info_msg "$add ${GATEWAY} to the ${IFACE} interface..."
      	  /sbin/ip route add default via ${GATEWAY} dev ${IFACE} 
      	  evaluate_retval
   	  fi
	;;

    down)
	rm="Removing default gateway"
	if [ "$(/sbin/ip addr show ${1} 2>/dev/null | grep 'inet ')" != "" ]; then
          log_info_msg "$rm..."
          /sbin/ip route del default dev ${1}
          evaluate_retval
	  fi	
	;;

    esac
  fi
}

#------------------------------------------------------------------
#to set interface ${1} IPV6 static routing
#------------------------------------------------------------------
set_route_ipv6()

{
if [ -n "${IPV6_GATEWAY}" ]; then
  case "${2}" in
    up)
	# Set the route default gateway if requested
	add="Adding IPV6 default gateway"
   	if /sbin/ip -6 route show dev ${1} | grep -q default; then
          log_warning_msg "IPV6 Gateway already setup; skipping."
   	else
      	  /sbin/ip route add ${IPV6_GATEWAY} dev ${IFACE} 
      	  log_info_msg "$add ${IPV6_GATEWAY} to the ${IFACE} interface..."
      	  /sbin/ip route add default via ${IPV6_GATEWAY}
      	  evaluate_retval
   	  fi
	;;

    down)
	rm="Removing IPV6 default gateway"
	if [ "$(/sbin/ip -6 addr show ${1} 2>/dev/null|grep 'inet6 ')" != "" ]; then
          log_info_msg "$rm..."
          /sbin/ip -6 route del default dev ${1}
          evaluate_retval
	  fi	
	;;
    esac
  fi
}

#------------------------------------------------------------------
#Script main entry
#------------------------------------------------------------------
case "${2}" in
  up)
	set_device ${1} ${2}
        if [ -n "${IP}" ] ; then
	  set_ipv4 ${1} ${2}
	  set_route_ipv4 ${1} ${2}
	  fi
        if [ -n "${IPV6}" ] ; then
	  set_ipv6 ${1} ${2}
	  set_route_ipv6 ${1} ${2}
	  fi
	set_vrrp ${1} ${2}
	;;

  down)
	set_vrrp ${1} ${2}
        if [ -n "${IPV6}" ] ; then
	  set_route_ipv6 ${1} ${2}
	  set_ipv6 ${1} ${2}
	  fi
        if [ -n "${IP}" ] ; then
	  set_route_ipv4 ${1} ${2}
	  set_ipv4 ${1} ${2}
	  fi
	set_device ${1} ${2}
	;;

  *)
	echo "Usage: ${0} [interface] {up|down}"
	exit 1
	;;
  esac

# End /lib/services/ip-static
