#!/bin/sh /etc/rc.common
# Copyright (C) 2018 Ycarus (Yannick Chabanois) <ycarus@zugaina.org>
# Released under GPL 3. See LICENSE for the full terms.

START=5

USE_PROCD=1

omr_intf_del() {
	[ -z "$1" ] && return
	uci -q delete openmptcprouter.$1
}

omr_intf_check() {
	[ "$(uci -q get network.$1)" = "" ] && omr_intf_del $1
}

omr_intf_set() {
	local device
	local ifname
	local multipath
	config_get multipath "$1" multipath
	config_get ifname "$1" ifname
	config_get device "$1" device
	config_get proto "$1" proto
	config_get addlatency "$1" addlatency "0"
	devicename=$(echo "$device" | cut -d'/' -f3)

	[ -z "$ifname" ] && ifname=$(ifstatus "$1" | jsonfilter -q -e '@["l3_device"]')

	if [ -n "$ifname" ]; then
		if [ "$addlatency" = "0" ] && [ "$(tc qdisc show $ifname | grep delay)" != "" ]; then
			tc qdisc del dev ${ifname} root netem
		fi
		if [ "$addlatency" != "0" ]; then
			if [ "$(tc qdisc show $ifname | grep delay)" != "" ]; then
				tc qdisc add dev ${ifname} root netem delay ${addlatency}ms
			elif [ "$(tc qdisc show $ifname | awk '/delay/ { print $10 }' | sed 's/ms//')" != "$addlatency" ]; then
				tc qdisc replace dev ${ifname} root netem delay ${addlatency}ms
			fi
		fi
	fi

	if [ -n "$ifname" ] && [ -f /sys/class/net/${ifname}/device/uevent ]; then
		devicepath=$(readlink -f /sys/class/net/${ifname})
		if [ -n "$devicepath" ] && [ "$(echo ${devicepath} | grep virtual)" = "" ]; then
			uci -q set network.$1.modalias="$(cat /sys/class/net/${ifname}/device/uevent | grep MODALIAS | cut -d '=' -f2 | tr -d '\n')"
			uci -q set network.$1.product="$(cat /sys/class/net/${ifname}/device/uevent | grep PRODUCT | cut -d '=' -f2 | tr -d '\n')"
		elif [ -n "$devicepath" ] && [ "$(echo ${devicepath} | grep virtual)" != "" ]; then
			uci -q delete network.$1.device
			uci -q delete network.$1.modalias
		fi
	elif [ -n "$device" ] && [ -f /sys/bus/usb-serial/devices/${devicename}/device/uevent ]; then
		uci -q set network.$1.modalias="$(cat /sys/bus/usb-serial/devices/${devicename}/device/uevent | grep MODALIAS | cut -d '=' -f2 | tr -d '\n')"
		uci -q set network.$1.product="$(cat /sys/bus/usb-serial/devices/${devicename}/device/uevent | grep PRODUCT | cut -d '=' -f2 | tr -d '\n')"
	fi

	[ -z "$multipath" ] || [ "$multipath" = "off" ] && [ "$1" != "omrvpn" ] && [ "$1" != "glorytun" ] && return

	uci -q set openmptcprouter.$1=interface
	uci -q set openmptcprouter.$1.multipath="$multipath"
	config_get disable_ipv6 settings disable_ipv6 "0"
	if [ "$disable_ipv6" = "1" ] || [ "$1" != "omr6in4" ]; then
		uci -q set network.$1.ipv6=0
	else
		uci -q set network.$1.ipv6=1
	fi
}

start_service() {
	local scaling_min_freq scaling_max_freq scaling_governor

	config_load openmptcprouter
	config_foreach omr_intf_check interface
	config_load network
	config_foreach omr_intf_set interface
	uci -q commit network
	uci -q commit openmptcprouter

	[ -d /sys/devices/system/cpu/cpufreq/policy0 ] && {
		config_load openmptcprouter
		config_get scaling_min_freq settings scaling_min_freq
		[ -n "$scaling_min_freq" ] && {
			for c in $(ls -d /sys/devices/system/cpu/cpufreq/policy[0-9]*); do
				echo $scaling_min_freq > $c/scaling_min_freq
			done
		}
		config_get scaling_max_freq settings scaling_max_freq
		[ -n "$scaling_max_freq" ] && {
			for c in $(ls -d /sys/devices/system/cpu/cpufreq/policy[0-9]*); do
				echo $scaling_max_freq > $c/scaling_max_freq
			done
		}
		config_get scaling_governor settings scaling_governor
		[ -n "$scaling_governor" ] && {
			for c in $(ls -d /sys/devices/system/cpu/cpufreq/policy[0-9]*); do
				echo $scaling_governor > $c/scaling_governor
			done
		}
	}
	# remove sysctl already defined in /etc/sysctl.d/
	sed -i -e '/tcp_fin_timeout/d' -e '/tcp_keepalive_time/d' -e '/nf_conntrack_max/d' -e '/tcp_syn_retries/d' -e '/tcp_fastopen/d' -e '/tcp_retries2/d' -e '/tcp_retries1/d' -e '/ip_default_ttl/d' /etc/sysctl.conf
	sed -i -e '/tcp_fin_timeout/d' -e '/tcp_keepalive_time/d' -e '/nf_conntrack_max/d' -e '/tcp_syn_retries/d' -e '/tcp_fastopen/d' -e '/tcp_retries2/d' -e '/tcp_retries1/d' -e '/ip_default_ttl/d' /etc/sysctl.d/10-default.conf
}

reload_service() {
	rc_procd start_service
	return 0
}

service_triggers() {
	procd_add_reload_trigger "openmptcprouter" "network"
}