#!/bin/sh
#macvlan及PPPoE拨号接口配置批量自动生成脚本
#Copyright (C) 2016
. /lib/functions.sh

#检测IP列表
chk_ip_list="www.baidu.com 114.114.114.114 119.29.29.29"
origfirewall=$(uci get firewall.@zone[1].network)
backupdev=$(uci get syncdial.config.devbackup)
norun=$(echo $origfirewall|grep vwan)
nomwan=$(uci get syncdial.config.nomwan)
wanselect=$(uci get syncdial.config.wanselect)
wannum=$(uci get syncdial.config.wannum)
oldframe=$(uci get syncdial.config.old_frame)
bindwan=$(uci -q get syncdial.config.bindwan)

dial_type=$(uci get syncdial.config.dial_type)
[ "$dial_type" -eq 2 ] && {
	wanselect2=$(uci get syncdial.config.wanselect2)
	[ $? -ne 0 ] && {
		logger -t Syncppp  "You must select another pppoe interface ! 启用双线多拨必须同时选择第二个外网接口！"
		return 0
	}

	wannum2=$(uci get syncdial.config.wannum2)
	[ $? -ne 0 ] && {
		logger -t Syncppp  "When dualdial is enabled, the number of the second virtual WAN cannot be blank! 启用双线多拨时第二个虚拟WAN接口数不能为空！"
		return 0
	}
	bindwan2=$(uci -q get syncdial.config.bindwan2)
}

#添加MWAN负载均衡相关配置
#$1:接口名称
mwan_cfg_add() {
	#gen mwan3_interface
	uci set mwan3.${1}=interface
	uci set mwan3.${1}.enabled=1
	uci set mwan3.${1}.count=2
	uci set mwan3.${1}.timeout=2
	uci set mwan3.${1}.interval=5
	uci set mwan3.${1}.down=4
	uci set mwan3.${1}.up=1
	for i in $chk_ip_list
	do
		uci add_list mwan3.${1}.track_ip="$i"
	done
	uci set mwan3.${1}.reliability=1
	uci set mwan3.${1}.initial_state=online
	uci set mwan3.${1}.family=ipv4
	uci set mwan3.${1}.track_method=ping
	uci set mwan3.${1}.size=56
	uci set mwan3.${1}.failure_interval=5
	uci set mwan3.${1}.recovery_interval=5
	uci set mwan3.${1}.flush_conntrack=never
	#gen mwan3_member
	uci set mwan3.${1}_m1_w1=member
	uci set mwan3.${1}_m1_w1.interface=${1}
	uci set mwan3.${1}_m1_w1.metric=1
	uci set mwan3.${1}_m1_w1.weight=1
	#gen mwan3_policy
	uci add_list mwan3.balanced.use_member=${1}_m1_w1
}

#删除MWAN负载均衡相关配置
#$1:接口名称
mwan_cfg_del() {
	uci del mwan3.${1}
	uci del mwan3.${1}_m1_w1
	uci del_list mwan3.balanced.use_member=${1}_m1_w1
}

#添加macvlan设备
#$1:设虚拟备名称 $2:原始设备名称
macvlan_dev_add() {
	uci set network.macvlandev_${1}=device
	uci set network.macvlandev_${1}.name=${1}
	uci set network.macvlandev_${1}.device=${2}
	uci set network.macvlandev_${1}.type=macvlan
}

#添加PPPoE接口
#$1:接口名称 $2:设备名称 $3:账户 $4:密码 $5:网关跃点
pppoe_if_add() {
	#gen vwan macaddr
	NEW_MACADDR=$(openssl rand -hex 6 | sed 's/\(..\)/\1:/g; s/.$//')
	#gen wan if
	uci set network.${1}=interface
	uci set network.${1}.device=${3}
	uci set network.${1}.proto=pppoe
	uci set network.${1}.username=${4}
	uci set network.${1}.password=${5}
	uci set network.${1}.metric=${2}
	uci set network.${1}.macaddr=$NEW_MACADDR
	#gen firewall
	uci add_list firewall.@zone[1].network=${1}
}


orig_firewall_add() {
	need_del_rule=`uci -q get firewall.@zone[1].network | awk -F"'" '{print $2}'`
	uci del_list firewall.@zone[1].network="$need_del_rule"
	for k in $( seq 1 250 )
	do
		origdev=$(echo $origfirewall | cut -d " " -f$k)
		if [ -z "$origdev" ]; then
			break
		fi
		[ -z "$(uci get firewall.@zone[1].network | grep -w $origdev)" ] && uci add_list firewall.@zone[1].network=$origdev
	done
}

apply_cfg() {
	uci commit
	#/etc/init.d/network restart &
	logger -t Syncppp  "Apply syncdial configuaration."
	ifup wan &
	killall pppconnectcheck
}

general_config_load() {
	config_load 'syncdial'
	config_get_bool enabled 'config' 'enabled'
	config_get_bool old_frame 'config' 'old_frame'
	congig_get_bool dial_type 'config' 'dial_type'

	if [ "$enabled" -eq 0 ]; then
		if [ "$old_frame" -eq 1 ]; then
			mwan_cfg_add $wanselect
			if [ "$dial_type" -eq 2 ]; then
				mwan_cfg_add $wanselect2
			fi
		fi
		echo "Disabled.Exit now."
		apply_cfg
		exit 1
	fi
  
	config_load 'network'
	config_get pppoe_user $wanselect 'username'
	config_get pppoe_password $wanselect 'password'
	pppoe_device=$(uci get network.$wanselect.device)
	[ "$dial_type" -eq 2 ] && {
		config_get pppoe_user2 $wanselect2 'username'
		config_get pppoe_password2 $wanselect2 'password'
		pppoe_device2=$(uci get network.$wanselect2.device)
	}

}

check_remove_device() {
	local devcfg=${1}
	[ ${devcfg::11} == 'macvlandev_' ] && uci del network.${devcfg}
}

check_remove_interface() {
	local ifcfg=${1}
	[ ${ifcfg::4} == 'vwan' ] && {
		uci del network.${ifcfg}
		uci del_list firewall.@zone[1].network=${ifcfg}
		[ "$nomwan" -ne 1 ] && mwan_cfg_del ${ifcfg} 
	}
	uci set firewall.@zone[1].network="$backupdev"
}

general_config_remove() {
	config_load network
	config_foreach check_remove_device 'device'
	config_foreach check_remove_interface 'interface'
	all_macvlans=`ip link show |grep macvlan | awk -F":" '{print $2}' | awk -F"@" '{print $1}'`
	[ -n "$all_macvlans" ] && {
		for macvlan in $all_macvlans
		do
			ip link delete $macvlan
		done
	}
	[ "$(uci get network.$wanselect.proto)" == "none" ] && {
		uci set network.$wanselect.proto=pppoe
	}

	if [ "$oldframe" -eq 0 ]; then
		[ "$wanselect" != "$(echo $(uci get syncdial.config.devbackup)| cut -d " " -f1)" ] && \
		[ "$wanselect" != "$(echo $(uci get syncdial.config.devbackup)| cut -d " " -f2)" ] && \
			[ "$nomwan" -ne 1 ] && mwan_cfg_del $wanselect
	else
		[ "$nomwan" -ne 1 ] && mwan_cfg_del $wanselect
	fi

	[ "$dial_type" -eq 2 ] && {
		[ $(uci get network.$wanselect2.proto) == "none" ] && {
			uci set network.$wanselect2.proto=pppoe
		}
		
		if [ "$oldframe" -eq 0 ]; then
			[ "$wanselect2" != "$(echo $(uci get syncdial.config.devbackup)| cut -d " " -f1)" ] && \
			[ "$wanselect2" != "$(echo $(uci get syncdial.config.devbackup)| cut -d " " -f2)" ] && \
				[ "$nomwan" -ne 1 ] && mwan_cfg_del $wanselect2
		else
			[ "$nomwan" -ne 1 ] && mwan_cfg_del $wanselect2
		fi
	}
}


[ -z "$norun" ] && uci set syncdial.config.devbackup="$origfirewall" && uci commit syncdial
general_config_remove
general_config_load

uci set network.$wanselect.metric=40
if [ "$wannum" -gt 0 ]; then
	[ "$old_frame" -eq 1 ] && {
		uci set network.$wanselect.proto=none
		device=$(uci get network.$wanselect.device)
		for i in $(seq 1 $wannum)
		do
			ip link add link $device name macvlan$i type macvlan
			ifconfig macvlan$i hw ether $(echo $(cat /sys/class/net/$device/address|awk -F ":" '{print $1":"$2":"$3":"$4":"$5":" }')$(echo "" | awk -F ":" '{printf("%X\n", 16+i);}' i=$i))
			ifconfig macvlan$i up
		done
	}
	[ "$wanselect" != "$(echo $(uci get syncdial.config.devbackup)| cut -d " " -f1)" ] && \
		[ "$wanselect" != "$(echo $(uci get syncdial.config.devbackup)| cut -d " " -f2)" ] && \
			[ "$old_frame" -eq 0 -a "$nomwan" -ne 1 ] && mwan_cfg_add $wanselect
	
	
	for i in $(seq 1 $wannum)
	do
		[ "$old_frame" -eq 0 ] && macvlan_dev_add macvlan$i $pppoe_device
		if [ "$bindwan" != "" -a "$bindwan" == "1" ]; then
			pppoe_if_add vwan$i $((40+$i)) $pppoe_device $pppoe_user $pppoe_password 
		else
			pppoe_if_add vwan$i $((40+$i)) macvlan$i $pppoe_user $pppoe_password 
		fi
		[ "$nomwan" -ne 1 ] && mwan_cfg_add vwan$i $((40+$i))
	done
else
	[ "$nomwan" -ne 1 ] && mwan_cfg_add $wanselect
fi

###dualdial configuration
[ "$(uci -q get syncdial.config.dial_type)" = "2" ] && {

	uci set network.$wanselect2.metric=60
	if [ "$wannum2" -gt 0 ]; then
		[ "$old_frame" -eq 1 ] && {
			uci set network.$wanselect2.proto=none
			device2=$(uci get network.$wanselect2.device)
			for i in $(seq 1 $wannum2)
			do
				ip link add link $device2 name macvlan$(($wannum+$i)) type macvlan
				ifconfig macvlan$(($wannum+$i)) hw ether $(echo $(cat /sys/class/net/$device2/address|awk -F ":" '{print $1":"$2":"$3":"$4":"$5":" }')$(echo "" | awk -F ":" '{printf("%X\n", 16+i);}' i=$i))
				ifconfig macvlan$(($wannum+$i)) up
			done
		}
		[ "$wanselect2" != "$(echo $(uci get syncdial.config.devbackup)| cut -d " " -f1)" ] && \
			[ "$wanselect2" != "$(echo $(uci get syncdial.config.devbackup)| cut -d " " -f2)" ] && \
				[ "$old_frame" -eq 0 -a "$nomwan" -ne 1 ] && mwan_cfg_add $wanselect2
		
		
		for i in $(seq 1 $wannum2)
		do
			[ "$old_frame" -eq 0 ] && macvlan_dev_add macvlan$(($wannum+$i)) $pppoe_device2
			if [ "$bindwan2" != "" -a "$bindwan2" == "1" ]; then
				pppoe_if_add vwan$(($wannum+$i)) $((60+$i)) $pppoe_device2 $pppoe_user2 $pppoe_password2 
			else
				pppoe_if_add vwan$(($wannum+$i)) $((60+$i)) macvlan$(($wannum+$i)) $pppoe_user2 $pppoe_password2 
			fi
			[ "$nomwan" -ne 1 ] && mwan_cfg_add vwan$(($wannum+$i)) $((60+$i)) 
		done
	else
		[ "$nomwan" -ne 1 ] && mwan_cfg_add $wanselect2
	fi
}

orig_firewall_add
apply_cfg

return 0
