#!/bin/sh
#######
# This script is used to maintain index of all normal route tables
#######

DEFIND_RULE_TABLE_PRIO_START=32767
MAX_TABLE_COUNT=100
SCRIPT_LOCK="/tmp/web_apply_lock/get_route_table_id"

[ -z "$1" ] && {
	echo -e "usage:\n\t$0 table_name\n\t$0 vs_name vs_vlan_name"
	return 1;
}

local table_name="$1"
local vs_vlan_name="$2"
vpn_l2l_lb="$3"
execute_result=0

if [ "$vpn_l2l_lb" = "VPN_L2L_LB" ]; then	# call from ipsec_lb_pool for load balance POOL
	table_name="${table_name}_VPNLBPOOL"
fi

lock $SCRIPT_LOCK

[ -z "$vs_vlan_name" ] && rt_table_id=`json get policy_rt.table_map.$table_name`
#Check PPTP over static/dhcp uses eth2.xx. The character '.' will makes json ambiguous and reply null value
[ -z "$rt_table_id" ] && {
	over_iface=`json show policy_rt.table_map |awk -F"policy_rt.table_map." '{print $2}' |cut -d '=' -f 1`
	#don't worry about string table_name containing "=" at end, WebUI will block any interface names defined as "xxx="
	echo "$over_iface" |grep "^${table_name}$" >/dev/null 2>/dev/null
	if [ "$?" = 0 ] ;then
		over_iface_id=`json show policy_rt.table_map |awk -F"policy_rt.table_map.${table_name}=" '{print $2}'`
		rt_table_id=$over_iface_id
	fi
}
[ -z "$rt_table_id" ] && {
	if [ -z "$vs_vlan_name" ]; then
		rt_table_id=`json get policy_rt.index_ptr`
		[ "$rt_table_id" -gt "$MAX_TABLE_COUNT" ] && execute_result=1
		json set policy_rt.table_map $table_name=$rt_table_id
		json set policy_rt index_ptr=`expr $rt_table_id + 1`
		#MAX_TABLE_COUNT=100=01100100; 0x7f:01111111
		/usr/sbin/ip rule add prio `expr $DEFIND_RULE_TABLE_PRIO_START + $rt_table_id` fwmark $rt_table_id/0x7F table $rt_table_id
		/usr/sbin/ip -6 rule add prio `expr $DEFIND_RULE_TABLE_PRIO_START + $rt_table_id` fwmark $rt_table_id/0x7F table $rt_table_id
		if   [ "$vpn_l2l_lb" = "" ]; then
			let "CMrt_table_id = rt_table_id << 5"
			/usr/sbin/iptables -t mangle -A CTMARK -m mark --mark $rt_table_id/0x7f -j CONNMARK --set-mark $CMrt_table_id/0x0FE00FE0
		fi
		
		if   [ "$vpn_l2l_lb" = "VPN_L2L_GRE" ]; then	# call from ipsec_lb_pool for GRE interface
			let "CMrt_table_id = rt_table_id << 5"
			let "CMrt_table_id_REPLY = CMrt_table_id << 16"
			# GRE -original-> LAN
			/usr/sbin/iptables -t mangle -I IPSEC_LB_RULE -i $table_name -m mset --set lan_net_set dst -m conntrack --ctstate NEW -j MARK --set-mark $rt_table_id	# mark new conntrack and will be set to conn mark in CTMARK; only MARK those DST to LAN subnet and not mark those dst to internet
			#/usr/sbin/iptables -t mangle -A IPSEC_LB_RULE -i $table_name -m conntrack --ctdir REPLY -j MARK --set-mark $rt_table_id	# mark packet mark for those replay session via GRE
			
			# LAN -reply-> GRE
			/usr/sbin/iptables -t mangle -A IPSEC_LB_RULE -m mset --set lan_net_set src -m connmark --mark $CMrt_table_id_REPLY/0x0FE00000 -m conntrack --ctdir REPLY -j MARK --set-mark $rt_table_id	# set packet mark from connmark(from CTMARK) to get the orig GRE to reply
			/usr/sbin/iptables -t mangle -A IPSEC_LB_RULE -m mset --set lan_net_set src -m connmark --mark $CMrt_table_id_REPLY/0x0FE00000 -m conntrack --ctdir REPLY -j RETURN
			
			
			#/usr/sbin/iptables -t mangle -A CTMARK -o lan-+ -m mark --mark $rt_table_id/0x7F -m conntrack --ctdir REPLY -j CONNMARK --set-mark $CMrt_table_id_REPLY/0x0FE00000		# mark reply (to lan) conn mark
			# GRE -original-> LAN 
			/usr/sbin/iptables -t mangle -A CTMARK -o lan-+ -m mark --mark $rt_table_id/0x7F -m conntrack --ctdir ORIGINAL -j CONNMARK --set-mark $CMrt_table_id_REPLY/0x0FE00000		# mark this for LAN reply reference in IPSEC_LB_RULE
			/usr/sbin/iptables -t mangle -A CTMARK -o lan-+ -m mark --mark $rt_table_id/0x7F -m conntrack --ctdir ORIGINAL -j RETURN
			
			# conn mark for orig and reply in CTMARK
			/usr/sbin/iptables -t mangle -A CTMARK -o $table_name -m conntrack --ctdir ORIGINAL -j CONNMARK --set-mark $CMrt_table_id/0x00000FE0
			/usr/sbin/iptables -t mangle -A CTMARK -o $table_name -m conntrack --ctdir ORIGINAL -j MARK --set-mark $rt_table_id		# update packet to the final GRE tableID
			
			#let "CMrt_table_id = CMrt_table_id << 16"
			/usr/sbin/iptables -t mangle -A CTMARK -o $table_name -m conntrack --ctdir REPLY -j CONNMARK --set-mark $CMrt_table_id_REPLY/0x0FE00000			
		fi
	else
		rt_table_id=`get_route_table_id $vs_vlan_name`
		[ -z "rt_table_id" ] && execute_result 1
		rt_table_id=`expr $rt_table_id + $MAX_TABLE_COUNT`
		current_rt_table_id=`json get policy_rt.table_map.$table_name`
		[ "$current_rt_table_id" != "$rt_table_id" ] && {
			json set policy_rt.table_map $table_name=$rt_table_id
			ip rule show | grep " $(printf 0x%x $rt_table_id) " >/dev/null || {
				/usr/sbin/ip rule add prio `expr $DEFIND_RULE_TABLE_PRIO_START + $rt_table_id` fwmark $rt_table_id table $rt_table_id
				let "CMrt_table_id = rt_table_id << 5"
				/usr/sbin/iptables -t mangle -A CTMARK -m mark --mark $rt_table_id/0x7F -j CONNMARK --set-mark $CMrt_table_id/0x0FE00FE0
			}
		}
	fi
}

if [ "$execute_result" = 0 ] ;then
	echo $rt_table_id
	lock -u $SCRIPT_LOCK
	return 0
else
	echo "error: exceed the max route table id:$MAX_TABLE_COUNT" >/dev/console
	lock -u $SCRIPT_LOCK
	return 1
fi
