#!/bin/sh
#
# network	Bring up/down networking
#
# chkconfig:	2345 10 90
# description:	Activates/Deactivates all network interfaces configured to \
#		start at boot time.
#
# probe:	true
# $Id: network 10185 2009-03-09 21:12:19Z baggins $

if [ ! -f /etc/sysconfig/network ]; then
	. /etc/rc.d/init.d/functions
	nls "%s is missing. Can't continue." "/etc/sysconfig/network"
	exit 1
fi

. /etc/sysconfig/network

# Source function library.
. /etc/rc.d/init.d/functions
. /etc/sysconfig/network-scripts/functions.network

# Will be removed in the future
if [ -n "$NETWORKING" ] && is_yes "$NETWORKING"; then
	if [ -z "$IPV4_NETWORKING" ]; then
		echo "NETWORKING is set to YES, but IPV4_NETWORKING is empty!"
		echo "Please upgrade your config"
		echo "Assuming you want IPv4 networking"
		IPV4_NETWORKING=yes
	fi
fi

######
# initialize networking:
# - check IPv4, IPv6, IPX can be handled by system
# - setup default IPv{4,6} interfaces policy like:
#   - spoofig protection,
#   - icmp echo ignore broadcasts,
# - setup lo interface
network_init() {
	if [ ! -x /sbin/ip ]; then
		nls "%s is missing. Can't continue." "/sbin/ip"
		exit 1
	fi

	# Modprobe needed devices
	modprobe_net

	# Setup interfaces names
	if [ -x /sbin/nameif -a -f /etc/mactab -a -x /usr/bin/wc ] && [ $(grep -vsE '^(#| *$)' /etc/mactab | wc -l) -gt 0 ]; then
		run_cmd "Setting interfaces names (nameif)" /sbin/nameif
	fi

	# Kernel network parameters
	sysctl -e -p /etc/sysctl.conf > /dev/null 2>&1

	# Set UP loopback interface
	set_up_loopback

	# Setup configuration
	setup_nat on
	setup_routes on
	setup_ip_rules on
	# Setup IPX
	if is_yes "$IPX"; then
		if [ -n $IPXAUTOPRIMARY ] ; then
			if is_yes "$IPXAUTOPRIMARY"; then
				IPXAUTOPRIMARY="on"
			else
				IPXAUTOPRIMARY="off"
			fi
			/sbin/ipx_configure --auto_primary=$IPXAUTOPRIMARY
		fi
		if [ -n $IPXAUTOFRAME ] ; then
			if is_yes "$IPXAUTOFRAME"; then
				IPXAUTOFRAME="on"
			else
				IPXAUTOFRAME="off"
			fi
			/sbin/ipx_configure --auto_interface=$IPXAUTOFRAME
		fi
		if [ -n "$IPXINTERNALNETNUM" -a "$IPXINTERNALNETNUM" != "0" ]; then
			/sbin/ipx_internal_net add $IPXINTERNALNETNUM $IPXINTERNALNODENUM
		fi
	fi
}

network_postinit() {
	# Set static RARP table
	static_rarp

	# Set static ARP table
	static_arp
}

######
# deinitialize networking
# - down lo interface.
network_deinit() {
	setup_routes off
	setup_ip_rules off

	# Set down NAT rules
	setup_nat off
	# Set DOWN loopback interface
	set_down_loopback
}

# Get list of interface configs
# ignores editor backup files and rpm blackups
network_interface_configs() {
	local match="$1"
	for a in /etc/sysconfig/interfaces/$match; do
		case "$a" in
		*rpmorig|*rpmnew|*rpmsave|*~|*.orig)
			continue
			;;
		*)
			echo $a
		;;
		esac
	done
}

find_boot_interfaces() {
	ifcfg_files="$(network_interface_configs 'ifcfg-*')"
	bootprio=$(grep '^BOOTPRIO=' $ifcfg_files)

	if [ -n "$bootprio" ]; then
		# find all the interfaces besides loopback.
		interfaces_boot=`
			for a in $(echo "$bootprio" | sort -t= -n -k2,2); do
				i="${a%:BOOTPRIO*}"
				case $i in
					*ifcfg-lo) continue ;;
				esac
				ONBOOT=""; . "$i" 2>/dev/null
				[ ${ONBOOT:-no} = yes ] && echo "${i##*/ifcfg-}"
			done
		`
	else
		interfaces_boot=`
			for i in $ifcfg_files; do
				case ${i##*/} in
					ifcfg-lo|ifcfg-sit*|ifcfg-atm*|ifcfg-lec*|ifcfg-nas*|ifcfg-br*|ifcfg-*.*) continue ;;
				esac
				ONBOOT=""; . "$i" 2>/dev/null
				[ ${ONBOOT:-no} = yes ] && echo "${i##*/ifcfg-}"
			done
		`

		interfaces_vlan_boot=`
			for i in $ifcfg_files; do
				case ${i##*/} in
					ifcfg-*.*) ;;
					*) continue ;;
				esac
				ONBOOT=""; . "$i" 2>/dev/null
				[ ${ONBOOT:-no} = yes ] && echo "${i##*/ifcfg-}"
			done
		`

		interfaces_br_boot=`
			for i in $ifcfg_files; do
				case ${i##*/} in
					ifcfg-br*) ;;
					*) continue ;;
				esac
				ONBOOT=""; . "$i" 2>/dev/null
				[ ${ONBOOT:-no} = yes ] && echo "${i##*/ifcfg-}"
			done
		`

		interfaces_sit_boot=`
			for i in $ifcfg_files; do
				case ${i##*/} in
					ifcfg-sit*) ;;
					*) continue ;;
				esac
				ONBOOT=""; . "$i" 2>/dev/null
				[ ${ONBOOT:-no} = yes ] && echo "${i##*/ifcfg-}"
			done
		`
	fi

	tunnels=$(
		for i in $(network_interface_configs 'tnlcfg-*'); do
			ONBOOT=""; . "$i" 2>/dev/null
			[ ${ONBOOT:-no} = yes ] && echo "${i##*/tnlcfg-}"
		done
	)
}

start() {
	rc_splash "bootnetwork start"
	network_init

	for i in $interfaces_boot $interfaces_vlan_boot $interfaces_sit_boot; do
		run_cmd -a "$(nls 'Bringing up interface %s' "$i")" /sbin/ifup $i boot
	done

	for i in $interfaces_br_boot ; do
		run_cmd -a "$(nls 'Bringing up bridge interface %s' "$i")" /sbin/ifup $i boot
	done

	for i in $tunnels; do
		run_cmd -a "$(nls 'Setting tunnel %s' "$i")" /sbin/tnlup $i boot
		run_cmd -a "$(nls 'Bringing up tunnel interface %s' "$i")" /sbin/ifup tnlcfg-$i boot
	done

	network_postinit

	touch /var/lock/subsys/network
}

stop() {
	# If we go to runlevel 0, 1 or 6 then umount all network fs
	if [ "$RUNLEVEL" = "6" -o "$RUNLEVEL" = "0" -o "$RUNLEVEL" = "1" ]; then
		if [ -x /etc/rc.d/init.d/netfs -a -f /var/lock/subsys/netfs ];
		then
			/etc/rc.d/init.d/netfs stop
		else
			netmtab=$(awk '{ if ($3 ~ /^(smbfs|ncpfs|cifs)$/ ) print $3}' /proc/mounts)
			if (echo "$netmtab" | grep -q smbfs); then
				run_cmd "Unmounting SMB filesystems" umount -at smbfs
			fi
			if (echo "$netmtab" | grep -q ncpfs); then
				run_cmd "Unmounting NCP filesystems" umount -at ncpfs
			fi
			if (echo "$netmtab" | grep -q cifs); then
				run_cmd "Unmounting CIFS filesystems" umount -at cifs
			fi
		fi
	fi

	for i in $tunnels; do
		run_cmd -a "$(nls 'Shutting down tunnel interface %s' "$i")" /sbin/ifdown tnlcfg-$i boot
		run_cmd -a "$(nls 'Removing tunnel %s' "$i")" /sbin/tnldown $i boot
	done

	for i in $interfaces_br_boot ; do
		run_cmd -a "$(nls 'Shutting down bridge interface %s' "$i")" /sbin/ifdown $i boot
	done

	for i in $interfaces_sit_boot $interfaces_vlan_boot $interfaces_boot ; do
		run_cmd -a "$(nls 'Shutting down interface %s' "$i")" /sbin/ifdown $i boot
	done

	network_deinit

	rm -f /var/lock/subsys/network
}

# Reload all active interfaces
reload() {
	if [ ! -f /var/lock/subsys/network ]; then
		msg_not_running network
		RETVAL=7
		return
	fi

	set_dhcpclient

	# if no DHCP client found we can't reload anything
	if [ -z "$DHCP_CLIENT" ]; then
		return
	fi

	local DHCP_ARGS
	case ${DHCP_CLIENT##*/} in
#	  pump)
#		DHCP_ARGS=""
#		;;
	  dhcpcd)
		DHCP_ARGS="-n"
		;;
#	  dhcpxd)
#		DHCP_ARGS=""
#		;;
#	  dhclient)
#		DHCP_ARGS=""
#		;;
	  *)
		echo "Reloading using $DHCP_CLIENT DHCP Client is not implmemented in rc-scripts"
		RETVAL=1
		return
		;;
	esac

	# for IPv4 DHCP interfaces send signal to refresh interface
	local dev devs=${*-$(/sbin/ip link show | awk -F: '/UP/{print $2}')}
	for dev in $devs; do
		if [ ! -f /etc/sysconfig/interfaces/ifcfg-$dev ]; then
			continue
		fi
		. /etc/sysconfig/interfaces/ifcfg-$dev

		if [ -n "$BOOTPROTO" -a "$BOOTPROTO" != "none" -a "$BOOTPROTO" != "static" ] && is_yes "$IPV4_NETWORKING"; then
			case ${DHCP_CLIENT##*/} in
			  pump)
				DHCP_ARGS="$DHCP_ARGS -i $DEVICE"
				;;
			  dhcpcd)
				DHCP_ARGS="$DHCP_ARGS $DEVICE"
				;;
			  dhcpxd)
				DHCP_ARGS="$DHCP_ARGS $DEVICE"
				;;
			  dhclient)
				DHCP_ARGS="$DHCP_ARGS $DEVICE"
				;;
			esac
			DHCP_ARGS="$DHCP_OPTIONS $DHCP_ARGS"

			show 'Reloading interface %s' $dev
			if $DHCP_CLIENT $DHCP_ARGS; then
				ok
			else
				fail
			fi
		fi
	done

}

find_boot_interfaces

# See how we were called.
case "$1" in
  start)
	if is_yes "$VSERVER"; then
		touch /var/lock/subsys/network
		exit 0
	fi
  	start
	;;

  stop)
	if is_yes "$VSERVER"; then
		rm -f /var/lock/subsys/network
		exit 0
	fi
	stop
	;;

  status)
	nls "Configured devices:"
	echo "lo $interfaces"
	nls "Configured tunnels:"
	echo "$tunnels"
	echo
	nls "Currently inactive devices and tunnels:"
	/sbin/ip link show | awk -F":" '(/^[0-90-90-9]:/) && ! (/UP/) { print $2 }' | xargs
	nls "Currently active devices and tunnels:"
	/sbin/ip link show | awk -F":" ' (/UP/) { print $2 }' | xargs
	;;

  reload)
	if is_yes "$VSERVER"; then
		exit 0
	fi
	shift
	reload ${1:+"$@"}
	;;

  restart)
	if is_yes "$VSERVER"; then
		exit 0
	fi

	stop
	start
	;;

  *)
	msg_usage "$0 {start|stop|reload|restart|status}"
	exit 3
esac

exit 0
