#!/bin/sh

CONFIG=/bin/config

wan_hwifname="eth0"
usage()
{
	echo "  bond-ctrl [add|del] <bond-id> mode [manual|dynamic] <port-list>"
	echo "		<bond-id>  --- 1~3"
	echo "		mode:"
	echo "		      manual  -- xor"
	echo "		      dynamic -- lacp"
	echo "		<port-list>   -- p1,p2,p3,p4 (etc. \"p1,p2\")"
	echo ""
	echo " example:"
	echo " 		Add a new bond1 with port 1 and port2 mode is lacp."
	echo " 		bond-ctrl add 1 mode dynamic p1,p2"
	echo ""
	echo " 		Delete bond1"
	echo " 		bond-ctrl del 1"
	echo ""

	exit 0
}

wanmac()
{
	local mac typesign
	local wantype=$($CONFIG get wan_proto)

	case "$wantype" in
		dhcp|static) 	typesign="ether" ;;
		pppoe) 		typesign="pppoe" ;;
		pptp) 		typesign="pptp" ;;
		bigpond)	typesign="bpa" ;;
		l2tp) 		typesign="l2tp" ;;
		*) 		typesign="ether" ;;
	esac

	case "$($CONFIG get wan_${typesign}_mac_assign)" in
		1) mac="wan_remote_mac" ;;
		2) mac="wan_${typesign}_this_mac" ;;
		*) mac="wan_factory_mac" ;;
	esac

	echo $($CONFIG get $mac)
}


add_to_br()
{
	ifname=$1

	ifconfig $ifname up
	[ "x$brname" != "x" ] && brctl addif $brname $ifname
}

del_from_br()
{
	ifname=$1
	#brname=`ls /sys/devices/virtual/net/$ifname/ | grep upper | awk -F"_" '{printf $2}' 2> /dev/null`

	[ "x$brname" != "x" ] && brctl delif $brname $ifname
	ifconfig $ifname down
}

_del_bond()
{
	bid=$1
	[ ! -d /sys/devices/virtual/net/bond$bid ] && exit 1

    	[ -e /var/run/bond-monitor$bid.pid ] && {
        	start-stop-daemon -K -p /var/run/bond-monitor$bid.pid
    	}
	ifconfig bond$bid down
	slave_list=`cat /sys/devices/virtual/net/bond$bid/bonding/slaves`
	brname_bak=`cat /sys/class/net/bond$bid/master/uevent | grep INTERFACE | cut -d = -f 2`
	for s in $slave_list
	do
		brname=$brname_bak
		echo -$s > /sys/devices/virtual/net/bond$bid/bonding/slaves
		[ $bid = 3 ] && [ $s != $wan_hwifname ] && brname="br0" &&  ifconfig $s down && ifconfig $s hw ether $($CONFIG get lan_factory_mac)
		add_to_br $s
	done

	brname=$brname_bak
	brctl delif $brname bond$bid

	echo -bond$bid > /sys/class/net/bonding_masters &
}

_add_bond()
{
	bid=$1
	mode=$2
	port_list=$3
	
	[ $1 -lt 1 ] && usage
	[ $1 -gt 3 ] && usage

	case $mode in
	man*) ;;
	dyn*) ;;
	   *) usage;;
	esac
	
	if [ -d /sys/devices/virtual/net/bond$bid ]
	then
		echo "!! You should delete bond $bid first!!"
		exit 0
	else
		echo +bond$bid > /sys/class/net/bonding_masters
	fi

	ifconfig bond$bid down

	case $mode in
	man*) echo balance-xor > /sys/devices/virtual/net/bond$bid/bonding/mode ;;
	dyn*) echo 802.3ad     > /sys/devices/virtual/net/bond$bid/bonding/mode ;;
	   *) usage;;
	esac

	echo 1000 > /sys/devices/virtual/net/bond$bid/bonding/miimon
	[ $bid = 2 ] && echo "layer2+3" > /sys/devices/virtual/net/bond$bid/bonding/xmit_hash_policy	
	[ $bid = 3 ] && echo "layer3+4" > /sys/devices/virtual/net/bond$bid/bonding/xmit_hash_policy	
	
	curr_slave_list=`cat /sys/devices/virtual/net/bond$bid/bonding/slaves`
	port_list=`echo $port_list | sed "s/,/ /g"`
	for s in $port_list
	do
		[ "$s" == "p0" ] && s="eth0"
		[ "$s" == "p1" ] && s="eth1"
		[ "$s" == "p2" ] && s="eth2"
		[ "$s" == "p3" ] && s="eth3"
		[ "$s" == "p4" ] && s="eth4"
		[ "${s:0:3}" != "eth" ] && usage

		p_existed=`echo $curr_slave_list | grep $s`
		if [ -z $p_existed ]
		then
			brname=`cat /sys/class/net/$s/master/uevent | grep INTERFACE | cut -d = -f 2`
			del_from_br $s

            [ $bid = 3 ] && ifconfig $s down && ifconfig $s hw ether $(wanmac)
			echo +$s > /sys/devices/virtual/net/bond$bid/bonding/slaves
		fi
	done

	[ $bid = 3 ] && brname=brwan	

	ifconfig bond$bid up

	brctl addif $brname bond$bid

    [ -e /var/run/bond-monitor$bid.pid ] && {
        start-stop-daemon -K -p /var/run/bond-monitor$bid.pid
    }

	start-stop-daemon -b -S -q -m -p /var/run/bond-monitor$bid.pid -x /usr/sbin/bond-monitor -- $bid
	#[ $bid = 3 ] && /etc/init.d/net-wan restart
}

[ $# -lt 1 ] && usage

case $1 in
add) _add_bond $2 $4 $5;;
del) _del_bond $2 ;;
  *) usage ;;
esac


