#!/bin/sh  /etc/rc.common
#
# Copyright (c) 2014, 2019-2020 The Linux Foundation. All rights reserved.
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

# The shebang above has an extra space intentially to avoid having
# openwrt build scripts automatically enable this package starting
# at boot.

START=19

get_front_end_mode() {
	config_load "ecm"
	config_get front_end global acceleration_engine "auto"

	case $front_end in
	auto)
		echo '0'
		;;
	nss)
		echo '1'
		;;
	sfe)
		echo '2'
		;;
	*)
		echo 'uci_option_acceleration_engine is invalid'
	esac
}

support_bridge() {
	#NSS support bridge acceleration
	[ -d /sys/kernel/debug/ecm/ecm_nss_ipv4 ] && return 0
	#SFE doesn't support bridge acceleration
	[ -d /sys/kernel/debug/ecm/ecm_sfe_ipv4 ] && return 1
}

load_sfe() {
	local kernel_version=$(uname -r)

	[ -e "/lib/modules/$kernel_version/shortcut-fe.ko" ] && {
		[ -d /sys/module/shortcut_fe ] || insmod shortcut-fe
	}

	[ -e "/lib/modules/$kernel_version/shortcut-fe-ipv6.ko" ] && {
		[ -d /sys/module/shortcut_fe_ipv6 ] || insmod shortcut-fe-ipv6
	}

	[ -e "/lib/modules/$kernel_version/shortcut-fe-drv.ko" ] && {
		[ -d /sys/module/shortcut_fe_drv ] || insmod shortcut-fe-drv
	}
}

load_ecm() {
	[ -d /sys/module/ecm ] || {
		[ ! -e /proc/device-tree/MP_256 ] && load_sfe
		insmod ecm front_end_selection=$(get_front_end_mode)
	}

	support_bridge && {
		sysctl -w net.bridge.bridge-nf-call-ip6tables=1
		sysctl -w net.bridge.bridge-nf-call-iptables=1
	}
}

unload_ecm() {
	sysctl -w net.bridge.bridge-nf-call-ip6tables=0
	sysctl -w net.bridge.bridge-nf-call-iptables=0

	if [ -d /sys/module/ecm ]; then
		#
		# Stop ECM frontends
		#
		echo 1 > /sys/kernel/debug/ecm/front_end_ipv4_stop
		echo 1 > /sys/kernel/debug/ecm/front_end_ipv6_stop

		#
		# Defunct the connections
		#
	        echo 1 > /sys/kernel/debug/ecm/ecm_db/defunct_all
		sleep 5;

		rmmod ecm
		sleep 1
	fi
}

start() {
	# If SFE CM is loaded, return.
	if [ -d /sys/module/shortcut_fe_cm ]; then
		echo "shortcut_fe CM is loaded, unload it first"
		echo "cmd: /etc/init.d/shortcut_fe stop"
		return
	fi

	load_ecm

	# If the acceleration engine is NSS, enable wifi redirect.
	[ -d /sys/kernel/debug/ecm/ecm_nss_ipv4 ] && sysctl -w dev.nss.general.redirect=1

	support_bridge && {
		echo 'net.bridge.bridge-nf-call-ip6tables=1' >> /etc/sysctl.d/qca-nss-ecm.conf
		echo 'net.bridge.bridge-nf-call-iptables=1' >> /etc/sysctl.d/qca-nss-ecm.conf
	}

	if [ -d /sys/module/qca_ovsmgr ]; then
		insmod ecm_ovs
	fi

}

stop() {
	# If ECM is already not loaded, just return.
	if [ ! -d /sys/module/ecm ]; then
		return
	fi

	# If the acceleration engine is NSS, disable wifi redirect.
	[ -d /sys/kernel/debug/ecm/ecm_nss_ipv4 ] && sysctl -w dev.nss.general.redirect=0

	sed '/net.bridge.bridge-nf-call-ip6tables=1/d' -i /etc/sysctl.d/qca-nss-ecm.conf
	sed '/net.bridge.bridge-nf-call-iptables=1/d' -i /etc/sysctl.d/qca-nss-ecm.conf

	if [ -d /sys/module/ecm_ovs ]; then
		rmmod ecm_ovs
	fi

	unload_ecm
}
