#!/bin/sh

. /lib/functions.sh
. /lib/functions/network.sh

proto="4"
[ -f /proc/net/ipv6_route ] && proto="4 6"

config_load freifunk-policyrouting
config_get enable pr enable
config_get fallback pr fallback
config_get strict pr strict
config_get zones pr zones

if [ "$ACTION" = "ifup" ] && [ "$enable" = "1" ]; then
	network_get_subnet net $INTERFACE
	network_get_subnet6 net6 $INTERFACE
	network_get_physdev dev $INTERFACE

	if [ "$net" != "" -a -n "$dev" ]; then
		eval $(/bin/ipcalc.sh $net)
		if [ "$PREFIX" != "0" -a "$NETWORK" != "127.0.0.0" ]; then
			if [ ! "$(ip r s t localnets |grep "$NETWORK/$PREFIX dev")" ]; then
				cmd="ip r a $NETWORK/$PREFIX dev $dev table localnets"
				$cmd
				if [ "$?" = 0 ]; then
					logger -s -t policyrouting "Add route: $cmd"
				else
					logger -s -t policyrouting "Error! Could not add route: $cmd"
				fi
			fi

		fi

		if [ -n "$net6" ]; then
			cmd="ip -6 r a $net6 dev $dev table localnets"
			$cmd 2>&1 > /dev/null
			if [ "$?" = 0 ]; then
				logger -s -t policyrouting "Add route: $cmd (IPv6)"
			fi

		fi

		networks=""
		for z in $zones; do
			network_zone="$(uci -q get firewall.zone_${z}.network)"
			if [ -z "$network_zone" ]; then
				network_zone="$z"
			fi
			networks="$networks $network_zone"
		done
		for n in $networks; do
			if [ "$INTERFACE" = "$n" ]; then
				for p in $proto; do
					if [ ! "$(ip -$p ru s | grep "from all iif $dev lookup olsr-default")" ]; then
						ip -$p rule add dev "$dev" lookup olsr-default prio 20000
						if [ "$strict" != 0 ]; then
							ip -$p rule add dev "$dev" unreachable prio 20001
						fi
						if [ "$?" = 0 ]; then
							logger -s -t policyrouting "Use mesh gateway for interface $dev (IPv$p)"
							if [ -z "$(uci -P /var/state get freifunk-policyrouting.${INTERFACE})" ]; then
								uci -P /var/state set freifunk-policyrouting.${INTERFACE}="state"
							fi
							uci -P /var/state set freifunk-policyrouting.${INTERFACE}.device="$dev"
						else
							logger -s -t policyrouting "Error: Could not add rule: dev "$dev" lookup olsr-default prio 20000 (IPv$p)"
						fi
					fi
				done
			fi
		done
	fi

fi

if [ "$ACTION" = "ifdown" ]; then
	dev="$(uci -q -P /var/state get freifunk-policyrouting.${INTERFACE}.device)"
	if [ -n "$dev" ]; then
		networks=""
		for z in $zones; do
			network_zone="$(uci -q get firewall.zone_${z}.network)"
			if [ -z "$network_zone" ]; then
				network_zone="$z"
			fi
			networks="$networks $network_zone"
		done
		for n in $networks; do
			if [ "$INTERFACE" = "$n" ]; then
				for p in $proto; do
					if [ "$(ip -$p ru s | grep "from all iif $dev lookup olsr-default")" ]; then
						ip -$p rule del dev "$dev" lookup olsr-default prio 20000
						ip -$p rule del dev "$dev" unreachable prio 20001
						if [ "$?" = 0 ]; then
							logger -s -t policyrouting "Remove rule: dev "$dev" lookup olsr-default prio 20000 (IPv$p)"
						else
							logger -s -t policyrouting "Error! Could not remove rule: dev "$dev" lookup olsr-default prio 20000 (IPv$p)"
						fi
					fi
				done
			fi
		done
	fi
fi
