#!/bin/bash

# ifdown script for usual, removable and ifplugd interfaces

usage()
{
	echo "Usage: $0 <interface> [skiphot]" >&2
	exit 1
}

[ -z "$1" ] && usage
export NAME=$1

if [ -z "$SCRIPTDIR" ]; then
	export SCRIPTDIR=/etc/net/scripts
	. $SCRIPTDIR/functions
fi

pickup_defaults
init_nethost
if [ -d $IFACEDIR/$NAME@$NETHOST ]; then
	MYIFACEDIR=$IFACEDIR/$NAME@$NETHOST
else
	MYIFACEDIR=$IFACEDIR/$NAME
fi

export MYIFACEDIR NETPROFILE
init_netprofile
pickup_options

if [ "$2" = "skiphot" ]; then
	is_yes "$USE_HOTPLUG" && {
		print_message -n " skipping hotplug iface '$NAME' "
		exit 2
	}

	is_yes "$USE_PCMCIA" && {
		print_message -n " skipping PCMCIA iface '$NAME' "
		exit 2
	}
fi

# 1. check constraints
is_yes "$DISABLED" && exit 0
iface_exists $NAME || exit 0
seen_iface $NAME && exit 0
export SEEN_IFACES
add_seen_iface $NAME

# 2. prepare for shutdown
# Don't destroy ifplugd iface itself, but process children.
if is_yes "$IFDOWN_CHILDREN"; then
	ifdown_children || {
		print_error "Could not ifdown children for parent iface '$NAME'"
		exit 1
	}
fi
xargise_file $MYIFACEDIR/ipneigh "$IP neigh del dev $NAME"

# Look if there is DHCP agent hanging around.
case "$BOOTPROTO" in
	dhcp|dhcp[\ -,]static|dhcp[\ -,]ipv4ll|dhcp[\ -,]ipv4ll[\ -,]static)
		stop_dhcp_client
	;;
	*)
	;;
esac

# Kill ipv4ll agent, if any.
case "$BOOTPROTO" in
	ipv4ll|dhcp[\ -,]ipv4ll|dhcp[\ -,]ipv4ll[\ -,]static)
		stop_ipv4ll_client
	;;
	*)
	;;
esac

#----------------+------+------+------+
# USE_IFPLUGD:   | yes  | no   | auto |
#----------------+------+------+------+
# IN_IFPLUGD=yes |  A   |  B   |  C   |
#----------------+------+------+------+
# IN_IFPLUGD=no  |  D   |  E   |  F   |
#----------------+------+------+------+
# A: print error and exit
# B: print error and exit
# C: print error and exit
# D: stop ifplugd and continue
# E: do nothing and continue
# F: X ? D : E
# X: we have ifplugd and a good network card
if is_yes "$IN_IFPLUGD"; then
	print_error "ERROR: IN_IFPLUGD is set in ifdown"
	exit 1
fi
: ${IFPLUGD:=$DEFAULT_IFPLUGD}
[ -z "$HAVE_IFPLUGD" ] && HAVE_IFPLUGD=`have_ifplugd`
. $SCRIPTDIR/functions-eth
case "$USE_IFPLUGD" in
	[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|[Yy]|1)
		# D
		if is_yes "$PERSISTENT_IFPLUGD"; then
			suspend_ifplugd && print_progress
		else
			while ifplugd_runs; do
				stop_ifplugd
				print_progress
				usleep 100000
			done
		fi
	;;
	[Aa][Uu][Tt][Oo])
		# F
		if is_yes "$HAVE_IFPLUGD" && need_detection auto; then
			# F/D
			if is_yes "$PERSISTENT_IFPLUGD"; then
				suspend_ifplugd && print_progress
			else
				ifplugd_runs && stop_ifplugd && print_progress
			fi
		fi
		# F/E
	;;
	# E
esac

# get ipv4 and/or ipv6 addresses of the interface. get them in any way
# (interface can be "down", but has addresses)
is_yes "$CONFIG_IPV4" && SourceIfNotEmpty $SCRIPTDIR/functions-ipv4 && IPV4ADDRESS="$(get_ipv4_addresses $NAME)"
is_yes "$CONFIG_IPV6" && SourceIfNotEmpty $SCRIPTDIR/functions-ipv6 && IPV6ADDRESS="$(get_ipv6_addresses $NAME)"

# stop QoS and FireWall before iproute2 rules stop
is_yes "$CONFIG_QOS"  && $SCRIPTDIR/config-qos $NAME stop "${IPV4ADDRESS[*]}" "${IPV6ADDRESS[*]}"
is_yes "$CONFIG_FW"  && $SCRIPTDIR/config-fw $NAME stop "${IPV4ADDRESS[*]}" "${IPV6ADDRESS[*]}"

# ifup-common reverse order
is_yes "$CONFIG_IPX"  && $SCRIPTDIR/config-ipx $NAME stop
is_yes "$CONFIG_IPV6" && $SCRIPTDIR/config-ipv6 $NAME stop "${IPV4ADDRESS[*]}" "${IPV6ADDRESS[*]}"
is_yes "$CONFIG_IPV4" && $SCRIPTDIR/config-ipv4 $NAME stop "${IPV4ADDRESS[*]}" "${IPV6ADDRESS[*]}"


if iface_is_up $NAME; then
	ExecIfExecutable $SCRIPTDIR/shutdown-$TYPE $NAME && print_progress
	ExecIfExecutable $LOCALSCRIPTDIR/ifdown-pre-local $NAME && print_progress
	ExecIfExecutable $MYIFACEDIR/ifdown-pre $NAME && print_progress
	$IP link set dev $NAME down && print_progress
fi

# handle resolver config
if profiled_filename MYRESOLVCONF "$MYIFACEDIR/resolv.conf"; then
	if [ -x "${RESOLVCONFTOOL:=$DEFAULT_RESOLVCONFTOOL}" ]; then
		$RESOLVCONFTOOL -d $NAME
		print_progress
	fi
fi

ExecIfExecutable $LOCALSCRIPTDIR/ifdown-post-local $NAME && print_progress
ExecIfExecutable $MYIFACEDIR/ifdown-post $NAME && print_progress

# Get rid of the iface.
ExecIfExecutable $SCRIPTDIR/destroy-$TYPE $NAME && print_progress

# Shutdown parent only if requested.
if is_yes "$IFDOWN_PARENTS"; then
	ifdown_parents || {
		print_error "Could not ifdown dependency for interface '$NAME'"
		exit 1
	}
fi
