#!/bin/sh
#============================================================================
# Xend calls a network script when it starts.
# The script name to use is defined in /etc/xen/xend-config.sxp
# in the network-script field.
#
# This script creates a bridge (default xenbr)
#
# Usage:
#
# network-bridge (start|stop|status) {VAR=VAL}*
#
# Vars:
#
# bridge     The bridge to use (default xenbr).
#
# start:
# Creates the bridge
#
# stop:
# Deletes bridge
#
# status:
# Print addresses, interfaces, routes
#
#============================================================================


dir=$(dirname "$0")
. "$dir/xen-script-common.sh"
. "$dir/xen-network-common.sh"

findCommand "$@"
evalVariables "$@"

bridge=${bridge:-xenbr}


get_ip_info() {
	addr_pfx=`ip addr show dev $1 | egrep '^ *inet' | sed -e 's/ *inet //' -e 's/ .*//'`
	gateway=`ip route show dev $1 | fgrep default | sed 's/default via //'`
}


do_ifup() {
	if ! ifup $1 ; then
		if [ ${addr_pfx} ] ; then
			# use the info from get_ip_info()
			ip addr flush $1
			ip addr add ${addr_pfx} dev $1
			ip link set dev $1 up
			# [ ${gateway} ] && ip route add default via ${gateway}
		fi
	fi
}


##
# link_exists interface
#
# Returns 0 if the interface named exists (whether up or down), 1 otherwise.
#
link_exists() {
	if ip link show "$1" >/dev/null 2>/dev/null ; then
		return 0
	else
		return 1
	fi
}


# Usage: create_bridge bridge
create_bridge () {
	local bridge=$1

	# Don't create the bridge if it already exists.
	if ! brctl show | grep -q ${bridge} ; then
		brctl addbr ${bridge}
		brctl stp ${bridge} off
		brctl setfd ${bridge} 0
	fi
	ip link set ${bridge} up
}


# Usage: add_to_bridge bridge dev
add_to_bridge () {
	local bridge=$1
	local dev=$2
	# Don't add $dev to $bridge if it's already on a bridge.
	if ! brctl show | grep -q ${dev} ; then
		brctl addif ${bridge} ${dev}
	fi
}


# Usage: show_status dev bridge
# Print ifconfig and routes.
show_status () {
	local dev=$1
	local bridge=$2
    
	echo '============================================================'
	ip addr show ${dev}
	ip addr show ${bridge}
	echo ' '
	brctl show ${bridge}
	echo ' '
	ip route list
	echo ' '
	route -n
	echo '============================================================'
}


op_start () {
	if [ "${bridge}" = "null" ] ; then
		return
	fi

	create_bridge ${bridge}

	add_to_bridge2 ${bridge} eth1
	ip link set eth1 up
}


op_stop () {
	if [ "${bridge}" = "null" ]; then
		return
	fi
	if ! link_exists "$bridge"; then
		return
	fi

	brctl delif ${bridge} eth1
	ip link set ${bridge} down

	brctl delbr ${bridge}
}


# adds $dev to $bridge but waits for $dev to be in running state first
add_to_bridge2() {
	local bridge=$1
	local dev=$2
	local maxtries=10

	echo -n "Waiting for ${dev} to negotiate link."
	for i in `seq ${maxtries}` ; do
		if ifconfig ${dev} | grep -q RUNNING ; then
			break
		else
			echo -n '.'
			sleep 1
		fi
	done

	if [ ${i} -eq ${maxtries} ] ; then echo '(link isnt in running state)' ; fi

	add_to_bridge ${bridge} ${dev}
}


case "$command" in
	start)
		op_start
		;;

	stop)
		op_stop
		;;

	status)
		show_status ${netdev} ${bridge}
		;;

	*)
		echo "Unknown command: $command" >&2
		echo 'Valid commands are: start, stop, status' >&2
		exit 1
esac
