#!/bin/bash

# This script continues configuration of an interface started by ifup,
# ifup-removable or ifup-ifplugd scripts. We assume that all necessary
# checks are done yet.

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

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

. $SCRIPTDIR/functions

init_netprofile
pickup_options

#----------------+------+------+------+
# USE_IFPLUGD:   | yes  | no   | auto |
#----------------+------+------+------+
# IN_IFPLUGD=yes |  A   |  B   |  C   |
#----------------+------+------+------+
# IN_IFPLUGD=no  |  D   |  E   |  F   |
#----------------+------+------+------+
# A: do nothing and continue
# B: print error and exit
# C: X ? A : B
# D: start/resume ifplugd, then exit 0
# E: do nothing and continue
# F: X ? D : E
# X: we have ifplugd and a good network card

: ${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)
		# A and D
		if ! is_yes "$IN_IFPLUGD"; then
			# D
			! is_yes "$HAVE_IFPLUGD" && exit 1
			if is_yes "$PERSISTENT_IFPLUGD"; then
				if ! ifplugd_runs; then
					start_ifplugd
				else
					resume_ifplugd
				fi
			else
				ifplugd_runs && stop_ifplugd
				start_ifplugd
			fi
			exit 0
		fi
		# A
	;;
	[Aa][Uu][Tt][Oo])
		# C and F
		# Look for ifplugd existance.
		if is_yes "$HAVE_IFPLUGD" && need_detection auto; then
			# X
			if ! is_yes "$IN_IFPLUGD"; then
				# F/D
				if is_yes "$PERSISTENT_IFPLUGD"; then
					if ! ifplugd_runs; then
						start_ifplugd
					else
						resume_ifplugd
					fi
				else
					ifplugd_runs && stop_ifplugd
					start_ifplugd
				fi
				exit 0
			fi
			# C/A
		elif is_yes "$IN_IFPLUGD" ; then
			# not X
			# C/B
			print_error "ERROR: USE_IFPLUGD=auto for $NAME, but IN_IFPLUGD=yes and card is unsupported"
			exit 1
		fi
		# F/E
	;;
	*)
		# B and E
		if is_yes "$IN_IFPLUGD"; then
			# B
			print_error "ERROR: USE_IFPLUGD=no for $NAME, but IN_IFPLUGD=yes"
			exit 1
		fi
		# E
	;;
esac

process_sysctl_conf()
{
	local SRCFILE=${1:?missing 1st arg to $FUNCNAME}
	local NAME=$2
	local ONELINE
	local VARPREFIX
	[ -s $SRCFILE ] || return 0
	$DENOISE $SRCFILE | sed "s/ //g" | while read ONELINE; do
		local VARNAME=`echo $ONELINE  | cut -d'=' -f1`
		local VARVALUE=`echo $ONELINE | cut -d'=' -f2`
		# If variable name contains dot(s), we use it as is. Otherwise
		# we append interface prefix.
		if echo $VARNAME | fgrep -vq .; then
			[ -z $NAME ] && {
				print_error "Can't autocomplete sysctl variable name '$VARNAME' in file '$SRCFILE'. Please fix"
				return 1
			}
			# try to guess prefix from variable name
			# There should be a better way to build this case block...
			case $VARNAME in
				force_igmp_version|disable_policy|disable_xfrm|arp_ignore|arp_announce)
					VARPREFIX="net.ipv4.conf.$NAME."
				;;
				arp_filter|tag|log_martians|bootp_relay|medium_id|proxy_arp)
					VARPREFIX="net.ipv4.conf.$NAME."
				;;
				accept_source_route|send_redirects|rp_filter|shared_media)
					VARPREFIX="net.ipv4.conf.$NAME."
				;;
				secure_redirects|accept_redirects|mc_forwarding|forwarding)
					VARPREFIX="net.ipv4.conf.$NAME."
				;;
				locktime|proxy_delay|anycast_delay|proxy_qlen|unres_qlen)
					VARPREFIX="net.ipv4.neigh.$NAME."
				;;
				gc_stale_time|delay_first_probe_time|base_reachable_time)
					VARPREFIX="net.ipv4.neigh.$NAME."
				;;
				retrans_time|app_solicit|ucast_solicit|mcast_solicit)
					VARPREFIX="net.ipv4.neigh.$NAME."
				;;
				*)
					print_error "Can't autocomplete sysctl variable name '$VARNAME' in file '$SRCFILE'. Please fix"
					return 1
			esac
		fi
		$SYSCTL -q -w $VARPREFIX$VARNAME=$VARVALUE
	done
	return 0
}

# setup link-level params
xargise_file $IFACEDIR/default/iplink "$IP link set dev $NAME"
xargise_file $IFACEDIR/default/iplink-$TYPE "$IP link set dev $NAME"
xargise_file $MYIFACEDIR/iplink "$IP link set dev $NAME"

# bring iface up
if ! is_yes $KEEP_DOWN; then
	$IP link set dev $NAME up && print_progress
fi

# handle wireless extensions
is_yes "$CONFIG_WIRELESS" && ExecIfExecutable $SCRIPTDIR/config-wireless $NAME && print_progress

# process ip neighbours
xargise_file $MYIFACEDIR/ipneigh "$IP neigh replace dev $NAME"

# setup addresses and (only if iface is up) routes
# don't flush IPv6 auto-generated link-level addresses
is_yes $DONT_FLUSH || {
	flush_addresses $NAME
	print_progress
}
# Start firewall before all
is_yes "$CONFIG_FW"  && ExecIfExecutable $SCRIPTDIR/config-fw $NAME start
is_yes "$CONFIG_IPV4" && ExecIfExecutable $SCRIPTDIR/config-ipv4 $NAME
is_yes "$CONFIG_IPV6" && ExecIfExecutable $SCRIPTDIR/config-ipv6 $NAME
is_yes "$CONFIG_IPX"  && ExecIfExecutable $SCRIPTDIR/config-ipx $NAME
is_yes "$CONFIG_QOS"  && ExecIfExecutable $SCRIPTDIR/config-qos $NAME

# handle resolver config
MYRESOLVCONF=`profiled_filename $MYIFACEDIR/resolv.conf`
if [ -s $MYRESOLVCONF ]; then
	rm -f /etc/resolv.conf
	cp $MYRESOLVCONF /etc/resolv.conf
	[ -x "$RESOLV_POSTIN_CMD" ] && $RESOLV_POSTIN_CMD $RESOLV_POSTIN_ARGS
	print_progress
fi

# handle sysctl file
GLOBAL_SYSCTL=`profiled_filename $IFACEDIR/sysctl.conf`
TYPESPEC_SYSCTL=`profiled_filename $IFACEDIR/default/sysctl.conf-$TYPE`
MY_SYSCTL=`profiled_filename $MYIFACEDIR/sysctl.conf`
[ -s $GLOBAL_SYSCTL ] && process_sysctl_conf $GLOBAL_SYSCTL && print_progress
[ -s $TYPESPEC_SYSCTL ] && process_sysctl_conf $TYPESPEC_SYSCTL $NAME && print_progress
[ -s $MY_SYSCTL ] && process_sysctl_conf $MY_SYSCTL $NAME && print_progress

# type-specific additional optional configuration
ExecIfExecutable $SCRIPTDIR/setup-$TYPE $NAME && print_progress

# ifup-post
iface_is_up $NAME && {
	ExecIfExecutable $SCRIPTDIR/ifup-post-local $NAME && print_progress
	ExecIfExecutable $MYIFACEDIR/ifup-post $NAME && print_progress
}

# process deps
if is_yes "$IFUP_CHILDREN"; then
	IN_IFPLUGD=
	ifup_children || {
		print_error "Could not ifup children for parent iface '$NAME'"
		exit 1
	}
fi

exit 0
