#!/bin/bash
# Bridge service on SME
# This service will configure a bridge interface on your server
# allowing each enslaved interfaces to act as a switch port.

# Source function library.
. /etc/rc.d/init.d/functions

# Bridge Interface
BRIDGE_IF=$(/sbin/e-smith/db configuration getprop bridge bridgeInterface)
BRIDGE_PROMISC=$(/sbin/e-smith/db configuration getprop bridge Promiscuous)

# Define list of TAP interfaces to be bridged,
# for example tap="tap0 tap1 tap2".
# Defaults is tap0
TAP_IF=$(/sbin/e-smith/db configuration getprop bridge tapInterface)
# Replace ; and , with spaces
TAP_IF=$(echo $TAP_IF | sed -e "s/[,;]/ /g")

# Define physical ethernet interface to be bridged
# with TAP interface(s) above.
ETH_IF=$(/sbin/e-smith/db configuration getprop bridge ethernetInterface)
ETH_MAC=$(/sbin/e-smith/db configuration getprop InternalInterface HWAddress)
ETH_IP=$(/sbin/e-smith/db configuration get LocalIP)
ETH_MASK=$(/sbin/e-smith/db configuration getprop InternalInterface Netmask)

# System mode: serveronly, server&gateway ...
MODE=$(/sbin/e-smith/db configuration get SystemMode)

# Path of openvpn binary
openvpn=""
openvpn_locations="/usr/sbin/openvpn /usr/local/sbin/openvpn"
for location in $openvpn_locations
do
  if [ -f "$location" ]
  then
    openvpn=$location
  fi
done

# Check that binary exists
if ! [ -f  $openvpn ]
then
  echo "openvpn binary not found"
  exit 0
fi



# Sub to reconfigure the firewall
firewall(){
	/sbin/e-smith/expand-template /etc/rc.d/init.d/masq >/dev/null 2>&1
	/sbin/service masq restart >/dev/null 2>&1
}

# Sub to restart dhcpd
dhcpd(){
	/usr/bin/sv t dhcpd
}

# Sub to reconfigures routes and defaults gateway
routes(){
	# We need to push all the routes of local networks as the interface has changed
	for NET in $(/sbin/e-smith/db networks keys); do
		SYSTEM=$(/sbin/e-smith/db networks getprop $NET SystemLocalNetwork)
		if (! test $SYSTEM); then
			NETMASK=$(/sbin/e-smith/db networks getprop $NET Mask)
			ROUTER=$(/sbin/e-smith/db networks getprop $NET Router)
			/sbin/route add -net $NET netmask $NETMASK gw $ROUTER >/dev/null 2>&1
		fi
	done

	# If the server runs in serveronly, we need to reconfigure the default gateway:
	if [ $MODE == 'serveronly' ]; then
		GW=$(/sbin/e-smith/db configuration get GatewayIP)
		/sbin/route add default gw $GW >/dev/null 2>&1
	fi
}

start(){
	# First, create the bridge interface
	/usr/sbin/brctl addbr $BRIDGE_IF

	# Then, create the tap interface(s) and enslave it in the bridge one
	for t in $TAP_IF; do
	    $openvpn --mktun --dev $t >/dev/null 2>&1
	    /sbin/ifconfig $t 0.0.0.0 promisc up >/dev/null 2>&1
	    /usr/sbin/brctl addif $BRIDGE_IF $t >/dev/null 2>&1
	done

	# Now make the real ethernet interface promiscuous
	/sbin/ifconfig $ETH_IF 0.0.0.0 promisc up >/dev/null 2>&1
	sleep 1

	# And add it to the bridge
	/usr/sbin/brctl addif $BRIDGE_IF $ETH_IF >/dev/null 2>&1

	[ -n "$ETH_MAC" ] && /sbin/ifconfig $BRIDGE_IF hw ether $ETH_MAC

	[ "$BRIDGE_PROMISC" == "yes" ] && /sbin/ifconfig $BRIDGE_IF promisc

	# Now configure the LocalIP on the bridge interface
	/sbin/e-smith/db configuration setprop InternalInterface Name $BRIDGE_IF
	/sbin/ifconfig $BRIDGE_IF $ETH_IP netmask $ETH_MASK >/dev/null 2>&1

	# Push the routes for the new interface
	routes

	# Now we have to reconfigure the firewall
	firewall

	# And dhcpd (the configuration file is expanded each time the service starts
	# so no need to do it manually
	dhcpd
}

stop(){
	# Shutdown the bridge and remove it
	/sbin/ifconfig $BRIDGE_IF down >/dev/null 2>&1
	/usr/sbin/brctl delbr $BRIDGE_IF >/dev/null 2>&1
	
	# Then delete each tap interfaces
	for t in $TAP_IF; do
            $openvpn --rmtun --dev $t >/dev/null 2>&1
	done
	
	# Reconfigure the ethernet interface
	/sbin/e-smith/db configuration setprop InternalInterface Name $ETH_IF
	/sbin/ifconfig $ETH_IF $ETH_IP netmask $ETH_MASK up -promisc >/dev/null 2>&1
	
	# Push the routes
	routes
	
	# restart the firewall
	firewall
	
	# and dhcp
	dhcpd
}

case "$1" in
  start)
	echo -n $"Starting Bridge Service: "
  	start
	RETVAL=$?
  	;;
  stop)
	echo -n $"Stoping Bridge Service: "
  	stop
	RETVAL=$?
  	;;
  restart)
	echo -n $"Restarting Bridge Service: "
  	stop && start
	RETVAL=$?
  	;;
  adjust)
	echo -n $"Restarting Bridge Service: "
	stop && start
	RETVAL=$?
  	;;
  *)
  	echo "Usage: $0 start|stop|restart"
  ;;
esac

if [ $RETVAL -eq 0 ]; then
        echo_success
else 
        echo_failure
fi
echo

exit $RETVAL

