#!/bin/sh

test -n "$FAILSAFE" && exit
test -z "$(l=$(grep : /proc/net/wireless);l=${l%:*};echo ${l##* })" && exit

. /etc/functions.sh

set_wireless()
{
	OLSRDEV=$WIFIDEV
	OLSRDEVLIST=$WIFIDEV

	if [ -n "$WIFIADR" ] && [ "$LANADR" != "$WIFIADR" ]; then
		if [ -n "$LANOLSR" ]; then
			OLSRDEVLIST="$OLSRDEVLIST $LANDEV"
		fi
	else
		OLSRDEV=$LANDEV
		OLSRDEVLIST=$LANDEV
	fi

	if [ -n "$WANOLSR" ]; then
		OLSRDEVLIST="$OLSRDEVLIST $WANDEV"
	fi

	test -n "$(nvram get ff_txpwr)" && wl -i $WIFIDEV txpwr $(nvram get ff_txpwr)
	FFMTU=$(nvram get ff_mtu)
	if [ -n "$FFMTU" ] && [ 1500 -gt $FFMTU ]; then
		ip link set dev $OLSRDEV mtu $FFMTU
		for i in D I; do
			iptables -$i FORWARD -o $OLSRDEV -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu 2>/dev/null
		done
	fi
}

write_config()
{
	test -d /var/etc || mkdir -p /var/etc

	HNA4=$(nvram get ff_hna4)
	DMZS=$(nvram get ff_dmz)
	IFS=\;
	for DMZ in $DMZS; do
		SRCIP=${DMZ%[:,]*}
		if [ -n "$HNA4" ]; then
			HNA4="$HNA4;$SRCIP/32"
		else
			HNA4="$SRCIP/32"
		fi
	done
	unset IFS

	SPEED=$(nvram get ff_olsrspeed)
	test -z "$SPEED" && SPEED=6

	FEYE=$(nvram get ff_fisheye)
	if [ "0" != "$FEYE" ];then
		TCINT=$(( 1 + 1 * SPEED / 2 ))
		TCVAL=3
		COVER=7
		FEYE=1
	else
		TCINT=$(( 2 * SPEED ))
		TCVAL=1
		COVER=3
		FEYE=0
	fi

	REYE="LinkQualityDijkstraLimit 0 $(( 3 * SPEED / 2 )).0"
	if [ "0" = "$(nvram get ff_rfisheye)" ];then
		REYE=
	fi

	cat>/var/etc/olsrd.conf<<EOM
DebugLevel		0
IpVersion		4
AllowNoInt		yes
Pollrate		0.1
TcRedundancy		2
MprCoverage		$COVER
LinkQualityFishEye	$FEYE
LinkQualityWinSize	100
$REYE
EOM

	if [ "$(nvram get ff_dyngw)" != "0" ]; then
		cat>>/var/etc/olsrd.conf<<EOM
LoadPlugin "olsrd_dyn_gw_plain.so.0.4"
{
}
EOM
		if [ -n "$(nvram get ff_ping)" ]; then
			ff_ping=$(nvram get ff_ping)
			eval $(ip route list exact 0/0|while read l;do
				set $l
				eval "LAST0=\$$#"
				eval "LAST1=\$$(( $# - 1 ))"
				if [ "default" = "$1" ] && [ "via" = "$2" ] && ( [ "metric" != "$LAST1" ] || [ "0" = "$LAST0" ] );then
					echo DEFGW=$3
					break
				fi
			done)
			if [ -n "$DEFGW" ]; then
				ip rule add iif lo table dyngw
				IFS=\;
				for IP in $ff_ping; do
					ip route add $IP via $DEFGW table dyngw
				done
				unset IFS
			fi
		fi
	fi

	WAN_HOSTNAME=$(nvram get wan_hostname)
	if [ -n "$WAN_HOSTNAME" ] && [ "$(nvram get ff_nameservice)" != "0" ]; then
		cat>>/var/etc/olsrd.conf<<EOM
LoadPlugin "olsrd_nameservice.so.0.2"
{
	PlParam	"name"		"$WAN_HOSTNAME"
	PlParam	"hosts-file"	"/var/etc/hosts"
	PlParam	"suffix"	".olsr"
EOM
		SRV="$(nvram get ff_service)"
		if [ -n "$SRV" ]; then
			IFS=\;
			for ENT in $SRV; do
				echo "	PlParam	\"service\"	\"$ENT\"">>/var/etc/olsrd.conf
			done
			unset IFS
		fi
		echo "}">>/var/etc/olsrd.conf
	fi

	if [ "$(nvram get ff_httpinfo)" != "0" ]; then
		cat>>/var/etc/olsrd.conf<<EOM
LoadPlugin "olsrd_txtinfo.so.0.1"
{
	PlParam	"Accept" "127.0.0.1"
}
EOM
	fi

	bmf=$(ls /usr/lib/olsrd_bmf.so.* 2>/dev/null)
	if [ -n "$bmf" ] && [ "$(nvram get ff_bmf)" != "0" ]; then
		insmod tun>/dev/null 2>&1
		cat>>/var/etc/olsrd.conf<<EOM
LoadPlugin "olsrd_bmf.so.1.1"
{
}
EOM
	fi

	if [ -n "$HNA4" ]; then
		IFS=\;
		echo "Hna4">>/var/etc/olsrd.conf
		echo "{">>/var/etc/olsrd.conf
		for ENT in $HNA4; do
			if [ -z "${ENT##*/*}" ]; then
				echo "	$(ipcalc -n $ENT|cut -d'=' -f2) $(ipcalc -m $ENT|cut -d'=' -f2)">>/var/etc/olsrd.conf
			fi
		done
		echo "}">>/var/etc/olsrd.conf
		unset IFS
	fi

	IPC_PARA=
	if [ -z "$LANOLSR" ] && [ -n "$LANADR" ]; then
		# Allow Ipc on LAN
		IPC_PARA="Net $LANNET $LANMSK"
	fi
	cat>>/var/etc/olsrd.conf<<EOM
IpcConnect
{
	MaxConnections	1
	Host		127.0.0.1
	$IPC_PARA
}
EOM

	ff_qos=2
	ff_qoslev=$(nvram get ff_qoslev)
	case "$ff_qoslev" in
		0|1|2)
			ff_qos=$ff_qoslev
		;;
	esac
	echo "LinkQualityLevel $ff_qos">>/var/etc/olsrd.conf
	if [ -z "$ff_qos" ] || [ "$ff_qos" = "0" ]; then
		ff_hyst=$(nvram get ff_hyst)
		test -n "$ff_hyst" && echo "UseHysteresis $ff_hyst">>/var/etc/olsrd.conf
		ff_scale=$(nvram get ff_scale)
		test -n "$ff_scale" && echo "HystScaling $ff_scale">>/var/etc/olsrd.conf
		ff_thrh=$(nvram get ff_thrh)
		test -n "$ff_thrh" && echo "HystThrHigh $ff_thrh">>/var/etc/olsrd.conf
		ff_thrl=$(nvram get ff_thrl)
		test -n "$ff_thrl" && echo "HystThrLow $ff_thrl">>/var/etc/olsrd.conf
	else
		echo "UseHysteresis no">>/var/etc/olsrd.conf
	fi

	ff_lqmult=
	LQMS=$(nvram get ff_lqmult)
	IFS=\;
	for LQM in $LQMS; do
		SRCIP=${LQM%[:,]*}
		LQVAL=${LQM#*[:,]}
		if [ -n "$SRCIP" ] && [ -n "$LQVAL" ]; then
			ff_lqmults="$ff_lqmults
	LinkQualityMult	$SRCIP $LQVAL"
		fi
	done
	unset IFS

	ff_will=$(nvram get ff_will)
	test -n "$ff_will" && echo "Willingness $ff_will">>/var/etc/olsrd.conf

	ff_ip4broad=$(nvram get ff_ip4broad)
	test -n "$ff_ip4broad" && ff_ip4broad="Ip4Broadcast $(nvram get ff_ip4broad)"

	for DEV in $OLSRDEVLIST; do
		cat>>/var/etc/olsrd.conf<<EOM
Interface "$DEV"
{
	HelloInterval		$(( 1 * SPEED )).0
	HelloValidityTime	$(( 18 * SPEED )).0
	TcInterval		$TCINT.0
	TcValidityTime		$(( 18 * SPEED * TCVAL )).0
	MidInterval		$(( 3 * SPEED )).0
	MidValidityTime		$(( 18 * SPEED * TCVAL )).0
	HnaInterval		$(( 3 * SPEED )).0
	HnaValidityTime		$(( 18 * SPEED )).0
	$ff_ip4broad
	$ff_lqmults
	$(test -f /etc/local.olsrd.conf.$DEV && cat /etc/local.olsrd.conf.$DEV)
}
EOM
	done
	for i in /etc/local.olsrd.conf /etc/local.olsrd.conf-*; do
		test -f $i && cat>>/var/etc/olsrd.conf<$i
	done
}

case $1 in
	start)
		echo "Starting olsrd..."
		export NVRAM_wan_ifname
		export NVRAM_lan_ifname
		export NVRAM_lan_ifnames
		eval $(/usr/bin/netparam)
		set_wireless
		write_config
		# olsrd will disable per iface, but on wrt that is not enough
		echo 0 >/proc/sys/net/ipv4/conf/all/send_redirects
		olsrd -f /var/etc/olsrd.conf -d 0
	;;
	stop)
		echo "Stopping olsrd..."
		killall olsrd>/dev/null 2>&1
		olsrd-clearroutes
	;;
	restart)
		$0 stop
		if [ "$(nvram get ff_dyngw)" != "0" ] && [ -n "$(nvram get ff_ping)" ]; then
			eval $(ip route list table dyngw|while read line;do
				set $line
				if [ "via" = "$2" ];then
					echo DEFGW=$3
					break
				fi
			done)
			if [ -n "$DEFGW" ]; then
				ip route add default via $DEFGW 2>/dev/null
			fi
			ip route flush table dyngw 2>/dev/null
			ip rule del iif lo table dyngw 2>/dev/null
			rm /var/run/dyngw.hyst 2>/dev/null
		fi
		$0 start
	;;
	*)
		echo "Usage: $0 start|stop|restart"
	;;
esac
