#!/bin/sh
#

OP=$1
IFACE=$2
IP=$3
MASKBITS=$4
READD_BASE=$5
READD_SCRIPT=$6

add_ip_to_iface()
{
	local _iface=$1
	local _ip=$2
	local _maskbits=$3
	local _readd_base=$4
	local _script_dir="$_readd_base/$_ip.$_maskbits"

	# we make sure the interface is up first
	ip link set $_iface up || {
		echo "Failed to bringup interface $_iface"
		return 1;
	}
	ip addr add $_ip/$_maskbits brd + dev $_iface || {
		echo "Failed to add $_ip/$_maskbits on dev $_iface"
		return 1;
	}

	mkdir -p $_script_dir || {
		echo "Failed to mkdir -p $_script_dir"
		return 1;
	}

	rm -f $_script_dir/*

	return 0;
}

delete_ip_from_iface()
{
	local _iface=$1
	local _ip=$2
	local _maskbits=$3
	local _readd_base=$4
	local _script_dir="$_readd_base/$_ip.$_maskbits"

	# the ip tool will delete all secondary IPs if this is the primary. To work around
	# this _very_ annoying behaviour we have to keep a record of the secondaries and re-add
	# them afterwards. yuck
	local _secondaries=""
	if ip addr list dev $_iface primary | grep -q "inet $_ip/$_maskbits " ; then
	    _secondaries=`ip addr list dev $_iface secondary | grep " inet " | awk '{print $2}'`
	fi
	local _failed=0
	ip addr del $_ip/$_maskbits dev $_iface || _failed=1
	[ -z "$_secondaries" ] || {
	    local _i=""
	    for _i in $_secondaries; do
		if ip addr list dev $_iface | grep -q "inet $_i" ; then
		    echo "kept secondary $_i on dev $_iface"
		else
		    echo "re-adding secondary address $_i to dev $_iface"
		    ip addr add $_i brd + dev $_iface || _failed=1
		fi
		local _s_ip=`echo "$_i" | cut -d '/' -f1`
		local _s_maskbits=`echo "$_i" | cut -d '/' -f2`
		local _s_script_dir="$_readd_base/$_s_ip.$_s_maskbits"

		local _s_script=""
		for _s_script in $_s_script_dir/*; do
			test -x "$_s_script" || {
				continue
			}
			echo "call $_s_script '$_iface' '$_s_ip' '$_s_maskbits'"
			$_s_script "$_iface" "$_s_ip" "$_s_maskbits" || {
				ret=$?
				echo "$_s_script '$_iface' '$_s_ip' '$_s_maskbits' - failed - $ret"
				_failed=1
			}
		done

	    done
	}

	test -d $_script_dir && {
		rm -f $_script_dir/*
	}

	[ $_failed = 0 ] || {
		echo "Failed to del $_ip on dev $_iface"
		return 1;
	}
	return 0;
}

setup_iface_ip_readd_script()
{
	local _iface=$1
	local _ip=$2
	local _maskbits=$3
	local _readd_base=$4
	local _readd_script=$5
	local _script_dir="$_readd_base/$_ip.$_maskbits"

	test -x "$_readd_script" || {
		echo "Script '$_readd_script' isn't executable"
		return 1;
	}

	local _readd_basename=`basename $_readd_script`
	local _readd_final="$_script_dir/$_readd_basename"

	mkdir -p $_script_dir || {
		echo "Failed to mkdir -p $_script_dir"
		return 1;
	}

	cp -a $_readd_script $_readd_final || {
		echo "Failed to - cp -a $_readd_script $_readd_final"
		return 1;
	}

	return 0
}

case "$OP" in
	add)
		add_ip_to_iface $IFACE $IP $MASKBITS $READD_BASE
		exit $?
		;;
	delete)
		delete_ip_from_iface $IFACE $IP $MASKBITS $READD_BASE
		exit $?
		;;
	readd_script)
		setup_iface_ip_readd_script $IFACE $IP $MASKBITS $READD_BASE $READD_SCRIPT
		exit $?
		;;
esac

echo "$0: unknown operation[$OP]"
exit 1
