# Configure radvd

set_eui64_prefix() {
	IFACE=${1}
	ORIG_IFS=${IFS}
	IFS=:
	m=($(cat /sys/class/net/${IFACE}/address))
	IFS=${ORIG_IFS}

	/sbin/ip -6 addr add $(printf "%s%x:%x:%x:%x" ${2} $((((0x${m[0]} ^ 2) << 8) + 0x${m[1]}))  0x${m[2]}ff 0xfe${m[3]} 0x${m[4]}${m[5]})/64 dev ${1} 2>/dev/null | :
}


fixup_pre() {
	ORIG_IFS=${IFS}
	IFS=:;
	pre_a=(${1})
	IFS=${ORIG_IFS}

	if [ ! "${pre_a[3]}" ];then
		pre_a[3]=0
	fi

	if [ ! "${pre_a[2]}" ];then
		pre_a[2]=0
	fi

	if [ ! "${pre_a[1]}" ];then
		pre_a[1]=0
	fi

	printf "%x:%x:%x:%x::/64" 0x${pre_a[0]} 0x${pre_a[1]} 0x${pre_a[2]} $((0x${pre_a[3]} + ${2}))
}



setup_interface() {
	if [ "${3}" ];then
		PREFIX=$(fixup_pre ${2} ${3})
	else
		PREFIX=${2}
	fi

	eval $(ipcalc -p -n ${PREFIX})

	case ${1} in
		eth0.*)
			if [ -e /etc/default/vlan_${interface:5} ];then
				source /etc/default/vlan_${interface:5}
			fi;
		;;
		wlan[01])
			if [ -e /etc/default/wifi ];then
				source /etc/default/wifi
			fi;
		;;
		eth0)
			if [ -e /etc/default/static ];then
				source /etc/default/static
			fi;
		;;
	esac

	if [ "${IPV6PDSUF}" ] && [ "${IPV6PDSUF}" != "0" ];then
		if [[ "${IPV6PDSUF}" =~ .*:.*:.*:.* ]]; then
			/sbin/ip -6 addr add $(printf "%s%s/64" ${NETWORK:0:-1} ${IPV6PDSUF}) dev ${1} 2>/dev/null | :
		else
			/sbin/ip -6 addr add $(printf "%s%s/64" ${NETWORK} ${IPV6PDSUF}) dev ${1} 2>/dev/null | :
		fi;
	fi;

	if [ "${3}" ];then
		/sbin/ip route flush dev ${1} proto dhcp >/dev/null 2>61 | :
		/sbin/ip route add ${NETWORK}/64 dev ${1} proto dhcp >/dev/null 2>61 | :
	fi
	set_eui64_prefix ${1} ${NETWORK:0:-1}
}

remove_snet_ip() {
	ORIG_IFS=${IFS}
	IFS=:
	sn=(${1})
	IFS=${ORIG_IFS}

	if [ "${sn[3]}" ];then
		sn[3]=$((0x${sn[3]} + ${2}))
	else
		sn[3]=${2}
	fi
	PREFIX=$(printf "%s:%s:%s:%x:" ${sn[0]} ${sn[1]} ${sn[2]} ${sn[3]})

	/sbin/ip -6 -s -o addr show scope global |grep ${PREFIX} |awk '{printf "ip addr del %s dev %s\n", $4, $2}'  |sh
}

cleanup_subnet() {
	SUBNETS=$((( 2 << ((64 - ${2}) -1 ))))

	SNET=0
	while [ "${SNET}" -lt "${SUBNETS}" ];do
		remove_snet_ip ${1} ${SNET}
		SNET=$((${SNET} + 1))
	done;
}

case "$reason" in
REBIND6|BOUND6)
		echo "Restart radvd"
		if [ -n "${new_dhcp6_ia_na1_ia_addr1}" ] && [[ -z "${old_dhcp6_ia_na1_ia_addr1}" || "${old_dhcp6_ia_na1_ia_addr1}" != "${new_dhcp6_ia_na1_ia_addr1}" ]];then
			if [ -n "${old_dhcp6_ia_na1_ia_addr1}" ];then
				/sbin/ip -6 addr del ${old_dhcp6_ia_na1_ia_addr1}/128 dev ${interface}
			fi;
			/sbin/ip -6 addr add ${new_dhcp6_ia_na1_ia_addr1}/128 dev ${interface}
			/etc/init.d/netconf radvd
		fi;
	;;
RECONFIGURE)
		/etc/init.d/netconf radvd
	;;
EXPIRE6|RELEASE6)
		cleanup_subnet ${old_dhcp6_ia_pd1_prefix1} ${old_dhcp6_ia_pd1_prefix1_length}
		if [ -n "${old_dhcp6_ia_na1_ia_addr1}" ];then
			/sbin/ip -6 addr del ${old_dhcp6_ia_na1_ia_addr1}/128 dev ${interface}
		fi;
		/etc/init.d/netconf radvd
	;;
STOP6|TIMEOUT|STOPPED)
		if [ -n "${old_dhcp6_ia_na1_ia_addr1}" ];then
			/sbin/ip -6 addr del ${old_dhcp6_ia_na1_ia_addr1}/128 dev ${interface}
		fi;
		/etc/init.d/netconf radvd
	;;
DELEGATED6)
		setup_interface ${interface} ${new_delegated_dhcp6_prefix}
	;;
SETUPPD0)
		setup_interface ${interface} ${new_delegated_dhcp6_prefix} ${ext_prefix-0}
	;;
DEPARTED)
		if [ -n "${old_dhcp6_ia_na1_ia_addr1}" ];then
			/sbin/ip -6 addr del ${old_dhcp6_ia_na1_ia_addr1}/128 dev ${interface}
		fi;
		/etc/init.d/netconf radvd
	;;
esac
