#!/bin/sh

###########################################
# hotplug environment variable :
#        ACTION - ifup/ifdown
#        INTERFACE - profile name (wan1)
#        DEVICE - interface name (wan-wan1)
#        PROTO - static/dhcp/pppoe/pptp

LOG="/usr/bin/logger -t network -p local4.info"
JSON_FILE="/var/cd_status"
JSON="json -f $JSON_FILE"

uptime=`cat /proc/uptime | cut -d. -f 1`
model=$(head -n 1 /etc/version)
iface_status=`uci get network.$INTERFACE.status`
DEFAULT_RT_AUTOLB_BASE=39000

#failover: tell my backup iface to down when i am going up
failover_tell_down()
{
	backup=`$JSON get interface.$INTERFACE.backup`
	[ -n "$backup" ] && {
		for bak_if in $backup; do
			$LOG "$INTERFACE($PROTO):(Failover)Tell my backup($bak_if) to down"
			$JSON set interface.$bak_if bak_down=1
		done
	}
}
#failover: tell my backup iface to up when i am going down
failover_tell_up()
{
	backup=`$JSON get interface.$INTERFACE.backup`
	[ -n "$backup" ] && {
		for bak_if in $backup; do
			$LOG "$INTERFACE($PROTO):(Failover)Tell my backup($bak_if) to up"
			$JSON set interface.$bak_if bak_down=0
		done
	}
}


case "$model" in
"Vigor300B")
	if   [ "$ACTION" = "ifup" ]; then
		if [ "$iface_status" = "enable" ] ;then
			$LOG "$INTERFACE($PROTO) is up."
			if [ "$INTERFACE" = "wan1" ] || [ "$INTERFACE" = "wan2" ] || [ "$INTERFACE" = "wan3" ] || [ "$INTERFACE" = "wan4" ] ;then
				sh /sbin/SendAlert.sh "2" "$INTERFACE($PROTO) is up." >/dev/console
				sh /sbin/MailSendAlert.sh "2" "$INTERFACE($PROTO) is up." >/dev/console
				logger -p local4.alert "$INTERFACE($PROTO) is up."
			fi
			json set network.$INTERFACE connection=up uptime=$uptime
			/etc/bind/restart_my_dns 4 $INTERFACE &
			#Upadte LED status
			case "$INTERFACE" in
			"wan1")
				[ -d "/sys/class/leds/draytek-x2-led-csm" ] && echo 255 > /sys/class/leds/draytek-x2-led-csm/brightness
			;;
			"wan2")
				[ -d "/sys/class/leds/draytek-x2-led-vpn" ] && echo 255 > /sys/class/leds/draytek-x2-led-vpn/brightness
			;;
			"wan3")
				[ -d "/sys/class/leds/draytek-x2-led-wan1" ] && echo 255 > /sys/class/leds/draytek-x2-led-wan1/brightness
			;;
			"wan4")
				[ -d "/sys/class/leds/draytek-x2-led-wan2" ] && echo 255 > /sys/class/leds/draytek-x2-led-wan2/brightness
			;;
			*)
			;;
			esac
			####DMZ LED on
			if [ "$PROTO" = "dmz" ]; then
				echo "255" > /sys/class/leds/draytek-x2-led-qos/brightness
				json -f /var/status_system_interface set "led.dmz"  \
						link="up"
			fi
			
			physical_iface=`uci get network.$INTERFACE.physical`
			if [ "$physical_iface" != "eth0" ]; then
				#G43777: Remove drop rule for packets to a "down" status WAN interface, add route for failover
				rt_table_id=`json get policy_rt.table_map.$INTERFACE`
				#iptables -t mangle -D ROUTE_DOWN_DROP -o wan-$INTERFACE -m mset ! --set lan_net_set dst ! --set exception_subnet_set dst ! --set exception_subnet_gre_set dst -j DROP
				auto_lb_status=`uci get network.default_route.auto_lb`
				if [ "$auto_lb_status" = "enable" ] ;then
					MNGT_WAN=`uci get acc_ctrl.access_control.mngt_wan`
					[ "$INTERFACE" = "$MNGT_WAN" ] || {
						/usr/sbin/ip rule del pref `expr $DEFAULT_RT_AUTOLB_BASE + $rt_table_id` >/dev/null 2>/dev/null
						/usr/sbin/ip rule add pref `expr $DEFAULT_RT_AUTOLB_BASE + $rt_table_id` table $rt_table_id >/dev/null 2>/dev/null
					}
				fi
				#G40727: support load balance auto failover
				/etc/init.d/lb_rule "do_auto_failover" "$rt_table_id" "UP"
				/etc/init.d/addr_map "do_auto_failover" "$rt_table_id" "UP"
				/etc/route_down_drop.sh "10-status#ifup" "$rt_table_id" "UP" "$INTERFACE"
				/etc/init.d/cwmp "do_auto_failover" "$INTERFACE" "UP"
				/etc/init.d/dnsmasq restart & >/dev/null 2>/dev/null
			elif [ "$physical_iface" = "eth0" ] ;then
				echo "10-status: UP $INTERFACE" >/dev/console
				/usr/sbin/set_lan_df_route.sh ifup $INTERFACE
				kill -47 `pidof lighttpd`
				#G46945:(HA related issue)If HA LAN is ifup(ex:restart_lan_ipv6.sh) need to renew ucarp process
				#ha_status=`uci get ucarp_mode.general.status`
				#[ "$ha_status" == "enable" ] && {
				#	$LOG "$INTERFACE($PROTO) has ifuped, renew HA ucarp"
				#	killall ucarp 2>/dev/null
				#	/etc/init.d/ucarp_mode renew
				#}
			fi
			failover_tell_down
			/etc/init.d/igmpproxy_script restart & >/dev/null 2>/dev/null
		else
			$LOG "$INTERFACE($PROTO) is disabled, abort status update."
		fi
	else
		if [ "$iface_status" = "enable" ] ;then
			$LOG "$INTERFACE($PROTO) is down."
			if [ "$INTERFACE" = "wan1" ] || [ "$INTERFACE" = "wan2" ] || [ "$INTERFACE" = "wan3" ] || [ "$INTERFACE" = "wan4" ] ;then
				sh /sbin/SendAlert.sh "1" "$INTERFACE($PROTO) is down." >/dev/console
				sh /sbin/MailSendAlert.sh "1" "$INTERFACE($PROTO) is down." >/dev/console
				logger -p local4.alert "$INTERFACE($PROTO) is down."
			fi
			uci get network.$INTERFACE >/dev/null && {
				json set network.$INTERFACE connection=down uptime=$uptime
				json -f /var/status_system_interface set network.$INTERFACE connection=down rx_packets=0 tx_packets=0 rx_bytes=0 tx_bytes=0	rx_rate=0 tx_rate=0	rx_overf_count=0 tx_overf_count=0 
			}
			/etc/bind/restart_my_dns 4 $INTERFACE &
			
			#Upadte LED status
			case "$INTERFACE" in
			"wan1")
				[ -d "/sys/class/leds/draytek-x2-led-csm" ] && echo 0 > /sys/class/leds/draytek-x2-led-csm/brightness
			;;
			"wan2")
				[ -d "/sys/class/leds/draytek-x2-led-vpn" ] && echo 0 > /sys/class/leds/draytek-x2-led-vpn/brightness
			;;
			"wan3")
				[ -d "/sys/class/leds/draytek-x2-led-wan1" ] && echo 0 > /sys/class/leds/draytek-x2-led-wan1/brightness
			;;
			"wan4")
				[ -d "/sys/class/leds/draytek-x2-led-wan2" ] && echo 0 > /sys/class/leds/draytek-x2-led-wan2/brightness
			;;
			esac
			####DMZ LED off 
			if [ "$PROTO" = "dmz" ]; then
				echo "0" > /sys/class/leds/draytek-x2-led-qos/brightness
				json -f /var/status_system_interface set "led.dmz"  \
						link="down"
			fi
			
			physical_iface=`uci get network.$INTERFACE.physical`
			if [ "$physical_iface" != "eth0" ] ;then
				rt_table_id=`json get policy_rt.table_map.$INTERFACE`
				#G43777: Drop packets to a "down" status WAN interface
				#iptables -t mangle -D ROUTE_DOWN_DROP -o wan-$INTERFACE -m mset ! --set lan_net_set dst ! --set exception_subnet_set dst ! --set exception_subnet_gre_set dst -j DROP 2>/dev/null
				#iptables -t mangle -A ROUTE_DOWN_DROP -o wan-$INTERFACE -m mset ! --set lan_net_set dst ! --set exception_subnet_set dst ! --set exception_subnet_gre_set dst -j DROP 2>/dev/null
				/usr/sbin/ip rule del pref `expr $DEFAULT_RT_AUTOLB_BASE + $rt_table_id` >/dev/null 2>/dev/null
				/etc/init.d/lb_rule "do_auto_failover" "$rt_table_id" "DOWN"
				/etc/init.d/addr_map "do_auto_failover" "$rt_table_id" "DOWN"
				/etc/route_down_drop.sh "10-status#ifdown" "$rt_table_id" "DOWN" "$INTERFACE"
				/etc/init.d/cwmp "do_auto_failover" "$INTERFACE" "DOWN"
			elif [ "$physical_iface" = "eth0" ] ;then
				echo "10-status: DOWN $INTERFACE" >/dev/console
				#sed "/^$INTERFACE /d" -i /tmp/enabled_lan_attr 	#moved to ifdown:must do this before calling hotplug(racy event)
				#Signal lighttpd to update new LAN subnet attributes
				kill -47 `pidof lighttpd`
			fi
			failover_tell_up
			/etc/init.d/igmpproxy_script restart & >/dev/null 2>/dev/null
		else
			$LOG "$INTERFACE($PROTO) is disabled, abort status update."
		fi
	fi
	#must also flush WAN's subnet IPs in route cache
	ip=`json get network.$INTERFACE.ipaddr`
	mask=`json get network.$INTERFACE.netmask`
	if [ -n "$ip" -a -n "$mask" ] ;then
		eval $(ipcalc -ps $ip $mask)
		/usr/sbin/flush_route_cache.sh "10-status#SUBNET" all "$ip/$PREFIX"
	fi
	
	#clear DEVICE-related conntrack
	#/usr/sbin/flush_conn_by_dev.sh "10-status" "$INTERFACE" "alias" "all_dir"
	conntrack -F >/dev/null 2>/dev/null
	#Todo: allow conntrack tool flush by subnet
	
	
	#ip route flush cache #Comment off by Vincent F. 2013/02/01
	#Following commands already clear route cache, not necessary to flush cache here.
	#1. ip route flush
	#2. ip route flush table
	#3. ip addr flush dev
	#4. ip link set device down
;;
*)
	if [ "$ACTION" = "ifup" ] ;then
		if [ "$iface_status" = "enable" ] ;then
			$LOG "$INTERFACE($PROTO) is up."
			if [ "$INTERFACE" = "wan1" ] || [ "$INTERFACE" = "wan2" ] || [ "$INTERFACE" = "wan3" ] || [ "$INTERFACE" = "wan4" ] ;then
				sh /sbin/SendAlert.sh "2" "$INTERFACE($PROTO) is up." >/dev/console
				sh /sbin/MailSendAlert.sh "2" "$INTERFACE($PROTO) is up." >/dev/console
				logger -p local4.alert "$INTERFACE($PROTO) is up."
			fi
			json set network.$INTERFACE connection=up uptime=$uptime
			/etc/bind/restart_my_dns 4 $INTERFACE &
			[ -d "/sys/class/leds/draytek-x2-led-wan1" ] && {
				[ "$INTERFACE" = "wan1" -o "$INTERFACE" = "wan2" ] && {
					echo 255 > /sys/class/leds/draytek-x2-led-$INTERFACE/brightness
					json -f /var/status_system_interface set "led.$INTERFACE"  \
						link="up"
				}
			}
			
			physical_iface=`uci get network.$INTERFACE.physical`
			if [ "$physical_iface" != "eth0" ]; then
				rt_table_id=`json get policy_rt.table_map.$INTERFACE`
				#G43777: Remove drop rule for packets to a "down" status WAN interface, add route for failover
				#iptables -t mangle -D ROUTE_DOWN_DROP -o wan-$INTERFACE -m mset ! --set lan_net_set dst ! --set exception_subnet_set dst ! --set exception_subnet_gre_set dst -j DROP 2>/dev/null
				auto_lb_status=`uci get network.default_route.auto_lb`
				if [ "$auto_lb_status" = "enable" ] ;then
					MNGT_WAN=`uci get acc_ctrl.access_control.mngt_wan`
					[ "$INTERFACE" = "$MNGT_WAN" ] || {
						/usr/sbin/ip rule del pref `expr $DEFAULT_RT_AUTOLB_BASE + $rt_table_id` >/dev/null 2>/dev/null
						/usr/sbin/ip rule add pref `expr $DEFAULT_RT_AUTOLB_BASE + $rt_table_id` table $rt_table_id >/dev/null 2>/dev/null
					}
				fi
				#G40727: support load balance auto failover 
				/etc/init.d/lb_rule "do_auto_failover" "$rt_table_id" "UP"
				/etc/init.d/addr_map "do_auto_failover" "$rt_table_id" "UP"
				/etc/route_down_drop.sh "10-status#ifup" "$rt_table_id" "UP" "$INTERFACE"
				/etc/init.d/cwmp "do_auto_failover" "$INTERFACE" "UP"
				/etc/init.d/dnsmasq restart & >/dev/null 2>/dev/null
			elif [ "$physical_iface" = "eth0" ] ;then
				echo "10-status: UP $INTERFACE" >/dev/console
				/usr/sbin/set_lan_df_route.sh ifup $INTERFACE
				kill -47 `pidof lighttpd`
				#G46945:(HA related issue)If HA LAN is ifup(ex:restart_lan_ipv6.sh) need to renew ucarp process
				#ha_status=`uci get ucarp_mode.general.status`
				#[ "$ha_status" == "enable" ] && {
				#	$LOG "$INTERFACE($PROTO) has ifuped, renew HA ucarp"
				#	killall ucarp 2>/dev/null
				#	/etc/init.d/ucarp_mode renew
				#}
			fi
			failover_tell_down
			/etc/init.d/igmpproxy_script restart & >/dev/null 2>/dev/null
		else
			$LOG "$INTERFACE($PROTO) is disabled, abort status update."
		fi
	else
		if [ "$iface_status" = "enable" ] ;then
			$LOG "$INTERFACE($PROTO) is down."
			if [ "$INTERFACE" = "wan1" ] || [ "$INTERFACE" = "wan2" ] || [ "$INTERFACE" = "wan3" ] || [ "$INTERFACE" = "wan4" ] ;then
				sh /sbin/SendAlert.sh "1" "$INTERFACE($PROTO) is down." >/dev/console
				sh /sbin/MailSendAlert.sh "1" "$INTERFACE($PROTO) is down." >/dev/console
				logger -p local4.alert "$INTERFACE($PROTO) is down."
			fi
			uci get network.$INTERFACE >/dev/null && {
				json set network.$INTERFACE connection=down uptime=$uptime
				json -f /var/status_system_interface set network.$INTERFACE connection=down rx_packets=0 tx_packets=0 rx_bytes=0 tx_bytes=0	rx_rate=0 tx_rate=0	rx_overf_count=0 tx_overf_count=0 
			}
			[ "$PROTO" = "3g" ] && {
				json set network.$INTERFACE connection=down uptime=$uptime ipaddr= netmask= gateway= dns=
				json -f /var/status_system_interface set network.$INTERFACE connection=down rx_packets=0 tx_packets=0 rx_bytes=0 tx_bytes=0	rx_rate=0 tx_rate=0	rx_overf_count=0 tx_overf_count=0 
			}
			/etc/bind/restart_my_dns 4 $INTERFACE &
			[ -d "/sys/class/leds/draytek-x2-led-wan1" ] && {
				[ "$INTERFACE" = "wan1" -o "$INTERFACE" = "wan2" ] && {
					echo 0 > /sys/class/leds/draytek-x2-led-$INTERFACE/brightness
					json -f /var/status_system_interface set "led.$INTERFACE"  \
						link="down"
				}
			}
			
			physical_iface=`uci get network.$INTERFACE.physical`
			if [ "$physical_iface" != "eth0" ] ;then
				rt_table_id=`json get policy_rt.table_map.$INTERFACE`
				#G43777: Drop packets to a "down" status WAN interface
				#iptables -t mangle -D ROUTE_DOWN_DROP -o wan-$INTERFACE -m mset ! --set lan_net_set dst ! --set exception_subnet_set dst ! --set exception_subnet_gre_set dst -j DROP 2>/dev/null
				#iptables -t mangle -A ROUTE_DOWN_DROP -o wan-$INTERFACE -m mset ! --set lan_net_set dst ! --set exception_subnet_set dst ! --set exception_subnet_gre_set dst -j DROP 2>/dev/null
				/usr/sbin/ip rule del pref `expr $DEFAULT_RT_AUTOLB_BASE + $rt_table_id` >/dev/null 2>/dev/null
				/etc/init.d/lb_rule "do_auto_failover" "$rt_table_id" "DOWN"
				/etc/init.d/addr_map "do_auto_failover" "$rt_table_id" "DOWN"
				/etc/route_down_drop.sh "10-status#ifdown" "$rt_table_id" "DOWN" "$INTERFACE"
				/etc/init.d/cwmp "do_auto_failover" "$INTERFACE" "DOWN"
			elif [ "$physical_iface" = "eth0" ] ;then
				echo "10-status: DOWN $INTERFACE" >/dev/console
				#sed "/^$INTERFACE /d" -i /tmp/enabled_lan_attr		#moved to ifdown:must do this before calling hotplug(racy event)
				#Signal lighttpd to update new LAN subnet attributes
				kill -47 `pidof lighttpd`
			fi
			failover_tell_up
			/etc/init.d/igmpproxy_script restart & >/dev/null 2>/dev/null
		else
			$LOG "$INTERFACE($PROTO) is disabled, abort status update."
		fi
	fi
	#flush DEVICE-related cache
	/usr/sbin/flush_route_cache.sh "10-status#DEVICE" "$DEVICE"
	#must also flush WAN's subnet IPs in route cache
	ip=`json get network.$INTERFACE.ipaddr`
	mask=`json get network.$INTERFACE.netmask`
	if [ -n "$ip" -a -n "$mask" ] ;then
		eval $(ipcalc -ps $ip $mask)
		/usr/sbin/flush_route_cache.sh "10-status#SUBNET" all "$ip/$PREFIX"
	fi
	
	#clear DEVICE-related conntrack
	#/usr/sbin/flush_conn_by_dev.sh "10-status" "$INTERFACE" "alias" "all_dir"
	conntrack -F >/dev/null 2>/dev/null
	#Todo: allow conntrack tool flush by subnet
	
	#ip route flush cache #Comment off by Vincent F. 2013/02/01
	#Following commands already clear route cache, not necessary to flush cache here.
	#1. ip route flush
	#2. ip route flush table
	#3. ip addr flush dev
	#4. ip link set device down
;;
esac

# G41129: send arp to gw from alias
if [ "$ACTION" = "ifup" -a "${INTERFACE%%[0-9]*}" = "wan" ] ;then
	ip_alias=`json get network.$INTERFACE.ip_alias`
	gateway=`json get network.$INTERFACE.gateway`
	for ip2 in $ip_alias; do
		alias=$(echo $ip2 | cut -d '/' -f 1)
		arping -f -c 2 -w 3 -i $DEVICE -s $alias $gateway & >/dev/null 2>/dev/null 
	done
fi
