#!/bin/sh
#============================================================================
# network-multinet
#
# Version = 2.0.1
# Date = 2007-11-29
#
# Maintainer(s) = Ron Terry - ron (at) pronetworkconsulting (dot) com
#
# The latest version can be found at:
#
#    http://pronetworkconsulting.com/linux/scripts/network-multinet.html
#
# Description:
#
# Replacement for the xen network-bridge, network-nat and network-route 
#  scripts.  This script allows for the creation of multiple networks.
#
# This script can create 4 types of networks:
#
#  bridged:    -Networks that contain both a physical network device (ethX)
#               and a virtual network device (vethX) from Dom0.
#              -This is the traditional type of network created in xen by 
#               the basic network-bridge script.
#              -VMs on these network(s) appear to be on the real network(s)
#
#  nohost:     -Networks that contain a physical network device but not a 
#               virtual network device from Dom0.
#              -These can be used to allow virtual machines to communicate 
#               with the outside world but not with Dom0. 
#               (Usefull if you want to isolate traffic away from Dom0)
#
#  hostonly:   -Networks that contain only a virtual network device (vethX)
#               from Dom0.
#              -This type of network will allow VMs connected to it to 
#               access only Dom0 and other VMs connected to the network.
#              -This type of network is similiar to a VMware "HOST ONLY" 
#               network.
#
#  nat:        -Networks that contain only a virtual network device (vethX)
#               from Dom0.
#              -This type of network will allow VMs connected to it to access 
#               Dom0,the "outside world" via NAT and other VMs connected to it.
#              -This type of network is similiar to a VMware "NAT" network.
#
#  routed:     -Networks that contain only a virtual network device (vethX)
#               from Dom0.
#              -This type of network will allow VMs connected to it to access 
#               Dom0,the "outside world" via routing through Dom0 and other VMs 
#               connected to it.
#
#  empty:      -Networks that do not contain any physical or virtual network 
#               devices from Dom0.
#              -These can be used to allow VMs in DomUs to communicate only 
#               with other DomUs and not Dom0.
#

#
# This script accepts the (start|stop|restart|status) parameters.
#
# This script requires that the vif-bridge script be used as the vif 
#  creation script (as opposed to vif-nat/vif-route).
#
# This script will test for the presence of the physical interfaces
#  configured to be connected to bridged networks and only attempt to 
#  create networks on the ones that are present and up.  It will also test 
#  for the presence of virtual interfaces configured to be connected to
#  other networks and only create networks for the ones that exist and 
#  are not already connected to an existing network.
#
# Edit the NETWORK_LIST variable to define which networks to create on which 
#  interfaces. The default is to create a bridged network on the first 
#  interface active network interface.
#
# To enable this script edit the network-script field in the
#  /etc/xen/xend-config.sxp file.
#
#  Example:  (network-script network-multinet)
#
# Depends on:         $SCRIPT_PATH/multinet-common.sh
#
# Calls if present:   $SCRIPT_PATH/xen-dhcpd 
#
# Config file:        /etc/sysconfig/xend
#
# Usage:              network-multinet (start|stop|restart|status)
#
# Vars:
#
#  --------------------------- In this script ----------------------------
#  SCRIPT_PATH        -Path to the directory containing the xen network-bridge 
#                      script (typically /etc/xen/scripts)
#
#  CONFIG_FILE_PATH   -Path to extra config files
#                      (not used currently by this script)
#
#  NETWORK_SAVE_PATH  -Path to save network configuration information in
#
#  IPTABLES_SAVE_FILE -File in which to save backed-up iptables rules so that they 
#                      may be restored when the script is stopped
#
#  XEN_DHCP_SCRIPT    -Script called to manage the DHCP server on the specified networks
#
#  ------------------------- In the config file --------------------------
#  NETWORK_LIST       -Space delimited list of network devices to create networks 
#                      on using the following format:
#
#  <network type>,<number of network type>,<network device>,<mac address>,<IP address/CIDR NetMask>,<dhcp server status>
#
#           Example with 3 virtual devices:
#
# "bridge,0,eth0,,,dhcp-off nat,0,veth2,00:16:3E:01:00:03,172.23.0.1/16,dhcp-off hostonly,0,veth3,00:16:3E:01:00:03,172.23.0.1/16,dhcp-off" 
#
#  NAT_EXTERNAL_INTERFACE -Network interface to use as the external interface
#                          for NATed and Routed networks
#
#============================================================================

####  Read config files and set variables  ##################################


# Source the configuration File

. /etc/sysconfig/xend

SCRIPT_PATH="/etc/xen/scripts"
CONF_FILE_PATH="/etc/xen/conf"
NETWORK_SAVE_PATH="/var/lib/xend/network_save"
IPTABLES_SAVE_FILE="$NETWORK_SAVE_PATH/iptables-save"
XEN_DHCP_SCRIPT="$SCRIPT_PATH/xen-dhcpd"

####  Script Functions  #####################################################

usage() {
# Gives hlep about usage parameters
  echo "Usage: $0 {start|stop|restart|status}"
  exit 1
}

get_option() {
# Determine which option was passed from the command line.
  case "$1" in
    start|stop|restart|status)
      CMD_OPT="$1"
    ;;
    *)
      usage
    ;;
  esac
}

make_config_dirs() {
# Create temporary storage directory if needed.
  if ! [ -d "$NETWORK_SAVE_PATH" ]
  then
    mkdir $NETWORK_SAVE_PATH
  fi
  
  if ! [ -d $CONF_FILE_PATH ]
  then
    mkdir $CONF_FILE_PATH
  fi
}


. $SCRIPT_PATH/multinet-common.sh

#*****  Network Creation Main Function  *************************************

create_networks() {

  VIF_COUNT=0

  case $NAT_EXTERNAL_INTERFACE in
    default)
      NAT_EXTERNAL_INTERFACE=`ip route list | awk '/^default / { print $NF }'`
    ;;
  esac

  for NETWORK in $NETWORK_LIST
  do
    local NET_TYPE=`echo $NETWORK | cut -d "," -f 1`
    local NET_NUMBER=`echo $NETWORK | cut -d "," -f 2`
    local NET_DEV=`echo $NETWORK | cut -d "," -f 3`
    local NET_DEV_MAC=`echo $NETWORK | cut -d "," -f 4`
    local NET_DEV_IP=`echo $NETWORK | cut -d "," -f 5`
    local NET_DHCP_SRV=`echo $NETWORK | cut -d "," -f 6`

    case $NET_DEV in
      default)
        local NET_DEV=`ip route list | awk '/^default / { print $NF }'`
      ;;
    esac

    case $NET_TYPE in
      bridge)
        create_bridged_networks $NET_DEV $NET_NUMBER
        ((VIF_COUNT++))
      ;;
      nat|route|hostonly)
        create_local_networks $NET_DEV $NET_TYPE $NET_NUMBER $NET_DEV_MAC $NET_DEV_IP $NET_DHCP_SRV
        ((VIF_COUNT++))
      ;;
      nohost)
        create_nohost_networks $NET_DEV $NET_NUMBER 
      ;;
      empty)
        create_empty_networks $NET_NUMBER
      ;;
    esac
  done
}

####  Start, Stop, Status Functions  ########################################

start_xend_network() {
  echo ""
  echo "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
  echo "          Starting the xend network environment"
  echo "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
  make_config_dirs
  manage_susefirewall2 stop || manage_iptables stop
  #manage_susefirewall2 start
  manage_routing start
  create_networks
}

stop_xend_network() {
  echo ""
  echo "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
  echo "          Stopping the xend network environment"
  echo "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
  manage_susefirewall2 stop
  create_networks
  manage_routing stop
  manage_susefirewall2 start || manage_iptables start
}

show_xend_network_status() {
  create_networks
}

####  Main Code Body  #######################################################

get_option "$1"

case $CMD_OPT in
  start)
    # Start the Xen network
    start_xend_network
    
    # Start the DHCP server if it exists
    if [ -e $XEN_DHCP_SCRIPT ]
    then
      $XEN_DHCP_SCRIPT start
    fi
  ;;
  stop)
    # Stop the DHCP server if it exists
    if [ -e $XEN_DHCP_SCRIPT ]
    then
      $XEN_DHCP_SCRIPT stop
    fi
    
    # Stop the Xen network
    stop_xend_network
  ;;
  restart)
    # Stop the DHCP server if it exists
    if [ -e $XEN_DHCP_SCRIPT ]
    then
      $XEN_DHCP_SCRIPT stop
    fi
    
    # Stop the Xen network
    CMD_OPT="stop"
    stop_xend_network

    # Start the Xen network
    CMD_OPT="start"
    start_xend_network
    
    # Start the DHCP server if it exists
    if [ -e $XEN_DHCP_SCRIPT ]
    then
      $XEN_DHCP_SCRIPT start
    fi
  ;;
  status)
    show_xend_network_status
    if [ -e $XEN_DHCP_SCRIPT ]
    then
      $XEN_DHCP_SCRIPT status
    fi
  ;;
esac

exit 0
