#!/bin/sh /etc/rc.common

. /lib/network/config.sh

extra_help() {
	cat <<EOF

	ifup <iface>	Start service on interface
	ifdown <iface>	Stop service on interface
	interfaces	Show interfaces status
	policies	Show policies status
	rules		Show rules status
	status		Show all status
EOF
}

EXTRA_COMMANDS="ifdown ifup interfaces policies rules status"
EXTRA_HELP="$(extra_help)"
IP="/usr/sbin/ip -4"
IPT="/usr/sbin/iptables -t mangle -w"

ifdown()
{
	local device

	if [ -z "$1" ]; then
		echo "Error: Expecting interface. Usage: mwan3 ifdown <interface>" && exit 0
	fi

	if [ -n "$2" ]; then
		echo "Error: Too many arguments. Usage: mwan3 ifdown <interface>" && exit 0
	fi

	device=$(uci get -p /var/state network.$1.ifname) &> /dev/null
	
	if [ -e /var/run/mwan3track-$1.pid ] ; then
		kill $(cat /var/run/mwan3track-$1.pid)
		rm /var/run/mwan3track-$1.pid
	fi

	if [ -n "$device" ] ; then
		ACTION=ifdown INTERFACE=$1 DEVICE=$device /sbin/hotplug-call iface
	fi
}

ifup()
{
	local device enabled

	config_load mwan3

	if [ -z "$1" ]; then
		echo "Expecting interface. Usage: mwan3 ifup <interface>" && exit 0
	fi

	if [ -n "$2" ]; then
		echo "Too many arguments. Usage: mwan3 ifup <interface>" && exit 0
	fi
	
	config_get enabled "$1" enabled 0

	device=$(uci get -p /var/state network.$1.ifname) &> /dev/null
	
	if [ -n "$device" ] ; then
		[ "$enabled" -eq 1 ] && ACTION=ifup INTERFACE=$1 DEVICE=$device /sbin/hotplug-call iface
	fi
}

interfaces()
{
	local device enabled iface_id tracking

	config_load mwan3

	echo "Interface status:"
	
	check_iface_status()
	{
		device=$(uci get -p /var/state network.$1.ifname) &> /dev/null

		if [ -z "$device" ]; then
			echo "Interface $1 is unknown"
			return 0
		fi

		config_get enabled "$1" enabled 0
		let iface_id++

		if [ -n "$(ps -w | grep mwan3track | grep -v grep | sed '/.*\/usr\/sbin\/mwan3track \([^ ]*\) .*$/!d;s//\1/' | awk '$1 == "'$1'"')" ]; then
			tracking="active"
		else
			tracking="down"
		fi

		if [ -n "$($IP rule | awk '$5 == "'$device'"')" -a -n "$($IPT -S mwan3_iface_$1 2> /dev/null)" -a -n "$($IP route list table $iface_id default dev $device 2> /dev/null)" ]; then
			if [ -n "$(uci get -p /var/state mwan3.$1.track_ip 2> /dev/null)" ]; then
				echo "Interface $1 is online (tracking $tracking)"
			else
				echo "Interface $1 is online"
			fi
		elif [ -n "$($IP rule | awk '$5 == "'$device'"')" -o -n "$($IPT -S mwan3_iface_$1 2> /dev/null)" -o -n "$($IP route list table $iface_id default dev $device 2> /dev/null)" ]; then
			echo "Interface $1 error"
		else
			if [ "$enabled" -eq 1 ]; then
				if [ -n "$(uci get -p /var/state mwan3.$1.track_ip 2> /dev/null)" ]; then
					echo "Interface $1 is offline (tracking $tracking)"
				else
					echo "Interface $1 is offline"
				fi
			else
				echo "Interface $1 is disabled"
			fi
		fi
	}
	config_foreach check_iface_status interface
	echo -e
}

policies()
{
	local percent policy share total_weight weight iface

	for policy in $($IPT -S | awk '{print $2}' | grep mwan3_policy_ | sort -u); do
		echo "Policy $policy:" | sed 's/mwan3_policy_//g'

		[ -n "$total_weight" ] || total_weight=$($IPT -S $policy | cut -s -d'"' -f2 | head -1 | awk '{print $3}')

		if [ ! -z "${total_weight##*[!0-9]*}" ]; then
			for iface in $($IPT -S $policy | cut -s -d'"' -f2 | awk '{print $1}'); do
				weight=$($IPT -S $policy | cut -s -d'"' -f2 | awk '$1 == "'$iface'"' | awk '{print $2}')
				percent=$(($weight*100/$total_weight))
				echo " $iface ($percent%)"
			done
		else
			echo " $($IPT -S $policy | sed '/.*--comment \([^ ]*\) .*$/!d;s//\1/;q')"
		fi

		echo -e

		unset iface
		unset total_weight
	done
}
rules()
{
	if [ -n "$($IPT -S mwan3_connected 2> /dev/null)" ]; then
		echo "Known networks:"
		echo "destination policy hits" | awk '{ printf "%-19s%-19s%-9s%s\n",$1,$2,$3}' | awk '1; {gsub(".","-")}1'
		$IPT -L mwan3_connected -n -v 2> /dev/null | tail -n+3 | sed 's/mark.*//' | sed 's/mwan3_policy_//' | awk '{printf "%-19s%-19s%-9s%s\n",$9,"default",$1}'
		echo -e
	fi

	if [ -n "$($IPT -S mwan3_rules 2> /dev/null)" ]; then
		echo "Active rules:"
		echo "source destination proto src-port dest-port policy hits" | awk '{ printf "%-19s%-19s%-7s%-14s%-14s%-16s%-9s%s\n",$1,$2,$3,$4,$5,$6,$7}' | awk '1; {gsub(".","-")}1'
		$IPT -L mwan3_rules -n -v 2> /dev/null | tail -n+3 | sed 's/mark.*//' | sed 's/mwan3_policy_//' | awk '{ printf "%-19s%-19s%-7s%-14s%-14s%-16s%-9s%s\n",$8,$9,$4,$12,$15,$3,$1}'
		echo -e
	fi
}

status()
{
	interfaces
	policies
	rules
}

start()
{
	config_load mwan3
	config_foreach ifup interface
}

stop()
{
	local route rule table

	killall mwan3track &> /dev/null
	rm /var/run/mwan3track-* &> /dev/null

	for route in $($IP route list table all | sed 's/.*table \([^ ]*\) .*/\1/' |  awk '{print $1}' | awk '{for(i=1;i<=NF;i++) if($i+0>0) if($i+0<255) {print;break}}'); do
		$IP route flush table $route &> /dev/null
	done

	for rule in $($IP rule list | egrep '^[1-2][0-9]{3}\:' | cut -d ':' -f 1); do
		$IP rule del pref $rule &> /dev/null
	done

	$IPT -D PREROUTING -j mwan3_hook &> /dev/null
	$IPT -D OUTPUT -j mwan3_hook &> /dev/null
	$IPT -D OUTPUT -j mwan3_output_hook &> /dev/null

	for table in $($IPT -S | awk '{print $2}' | grep mwan3 | sort -u); do
		$IPT -F $table &> /dev/null
	done

	for table in $($IPT -S | awk '{print $2}' | grep mwan3 | sort -u); do
		$IPT -X $table &> /dev/null
	done
}

restart() {
	stop
	start
}
