515 lines
15 KiB
Bash
515 lines
15 KiB
Bash
#!/bin/bash
|
|
#============================================================================
|
|
# xend-network
|
|
#
|
|
# Version = 1.1.1
|
|
# Date = 2008-01-10
|
|
#
|
|
# 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:
|
|
#
|
|
# This script creates, deletes, and modifies virtual networks on the fly
|
|
# without having to restart the Xen network script. The same functions
|
|
# are used to create/delete virtual networks in this script as are used
|
|
# in the network-multinet network script.
|
|
#
|
|
# Vars:
|
|
#
|
|
# SCRIPT_PATH- -Path to the directory that contains the Xen
|
|
# network helper scripts
|
|
#
|
|
# DEFAULT_SNM -Default subnet mask value to use (number of bits)
|
|
# if not defined from the command line
|
|
#
|
|
# MODE -Mode that the xend-network script is running in:
|
|
# (add, del, delall, mod, show)
|
|
#
|
|
# NET_DEV -Network interface name
|
|
# NET_DEV_MAC -MAC address to be assigned to the network interface
|
|
# NET_DEV_IP -IP address to be assigned to the network interface
|
|
# NET_TYPE -Type of netowrk
|
|
# (bridge, nat, hostonly, route, nohost, empty)
|
|
# NET_NUMBER -Number of the specifed network type
|
|
# NET_NAME -Name of the specified network
|
|
# (xenbr, xennat, xenhost, xenroute, xennohost, xenempty)
|
|
# NAT_EXTERNAL_INTERFACE -Network interface to masquerade all NAT network
|
|
# trafic with
|
|
# NET_DHCP_SRV -Parameter defining whether or not the DHCP server
|
|
# should be enabled on the specified network:
|
|
# (dhcp-on, dhcp-off)
|
|
#============================================================================
|
|
|
|
#### Read config files and set variables ##################################
|
|
|
|
SCRIPT_PATH="/etc/xen/scripts"
|
|
|
|
DEFAULT_SNM="24"
|
|
|
|
. $SCRIPT_PATH/multinet-common.sh
|
|
|
|
#### Script Functions #####################################################
|
|
|
|
usage() {
|
|
echo "Usage: xend-network add|del|mod {options}"
|
|
echo
|
|
echo " Options: -t <bridge type> :bridged|nat|hostonly|routed|nohost|empty"
|
|
echo " -i <dev> :Virtual network interface - vethX"
|
|
echo " (for nat, hostonly and routed bridges only)"
|
|
echo " -I <Pdev> :Physical network interface - ethX"
|
|
echo " (for bridged and nohost bridges only)"
|
|
echo " -m <MAC addr> :MAC address"
|
|
echo " (for nat, hostonly and routed bridges only)"
|
|
echo " -a <IP Address> :IP address"
|
|
echo " (for nat, hostonly and routed bridges only)"
|
|
echo " -n <bridge #> :Bridge number (optional)"
|
|
echo " -N <bridge name> :Bridge name (optional)"
|
|
echo " -M <bridge name> :New Bridge name (used with rename option only)"
|
|
echo " -e <ext iface> :External network interface"
|
|
echo " (optional - for nat and routed networks only)"
|
|
echo " -d :Enable DHCP on this network"
|
|
|
|
|
|
echo
|
|
echo "Examples:"
|
|
echo
|
|
echo " bridged network: xend-network add -t bridge -i eth0"
|
|
echo " nat network: xend-network add -t nat -i veth0 -m 00:11:22:aa:bb:cc -a 10.0.0.1"
|
|
echo " hostonly network: xend-network add -t hostonly -i veth0 -m 00:11:22:aa:bb:cc -a 10.0.0.1"
|
|
echo " routed network: xend-network add -t route -i veth0 -m 00:11:22:aa:bb:cc -a 10.0.0.1"
|
|
echo " nohost network: xend-network add -t nohost -i eth0"
|
|
echo " empty network: xend-network add -t empty"
|
|
echo " empty network: xend-network del -N nat1"
|
|
|
|
}
|
|
|
|
get_mode() {
|
|
if ! [ -z "$1" ] && ! echo "$1" | grep -q "^-"
|
|
then
|
|
case $1 in
|
|
add)
|
|
MODE="add"
|
|
echo "Running in add mode"
|
|
;;
|
|
del)
|
|
MODE="del"
|
|
echo "Running in delete mode"
|
|
;;
|
|
delall)
|
|
MODE="delall"
|
|
echo "Running in delete-all mode"
|
|
;;
|
|
mod)
|
|
MODE="mod"
|
|
echo "Running in modify mode"
|
|
;;
|
|
show)
|
|
MODE="show"
|
|
echo "Running in show mode"
|
|
;;
|
|
esac
|
|
|
|
shift
|
|
echo "Options: $*"
|
|
get_options $*
|
|
else
|
|
usage
|
|
exit 1
|
|
fi
|
|
|
|
}
|
|
|
|
get_options() {
|
|
while getopts "t:i:I:m:a:n:N:M:e:dh" OPTIONS
|
|
do
|
|
case $OPTIONS in
|
|
i)
|
|
NET_DEV=$OPTARG
|
|
echo "Network Interface = $NET_DEV"
|
|
echo "----------------------------"
|
|
;;
|
|
I)
|
|
NET_DEV=$OPTARG
|
|
echo "Network Interface = $NET_DEV"
|
|
echo "----------------------------"
|
|
;;
|
|
m)
|
|
NET_DEV_MAC=$OPTARG
|
|
echo "MAC Address = $NET_DEV_MAC"
|
|
echo "----------------------------"
|
|
;;
|
|
a)
|
|
NET_DEV_IP=$OPTARG
|
|
echo "IP Address = $NET_DEV_IP"
|
|
echo "----------------------------"
|
|
;;
|
|
t)
|
|
NET_TYPE=$OPTARG
|
|
echo "Network type = $NET_TYPE"
|
|
echo "----------------------------"
|
|
;;
|
|
n)
|
|
NET_NUMBER=$OPTARG
|
|
echo "Number of Network Type = $NET_NUMBER"
|
|
echo "----------------------------"
|
|
;;
|
|
N)
|
|
NET_NAME=$OPTARG
|
|
echo "Network Name = $NET_NAME"
|
|
echo "----------------------------"
|
|
;;
|
|
M)
|
|
NEW_NET_NAME=$OPTARG
|
|
echo "New Network Name = $NEW_NET_NAME"
|
|
echo "----------------------------"
|
|
;;
|
|
e)
|
|
NAT_EXTERNAL_INTERFACE=$OPTARG
|
|
echo "NAT External Interface = $NAT_EXTERNAL_INTERFACE"
|
|
echo "----------------------------"
|
|
;;
|
|
d)
|
|
NET_DHCP_SRV="dhcp-on"
|
|
;;
|
|
h)
|
|
usage
|
|
exit 0
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [ -z $NET_DHCP_SRV ]
|
|
then
|
|
NET_DHCP_SRV="dhcp-off"
|
|
fi
|
|
}
|
|
|
|
#***** Address Generating Functions ***************************************
|
|
gen_mac_addr() {
|
|
local RANDOM=`od -An -N2 -i /dev/random`
|
|
local MAC="00:16:3E"
|
|
|
|
MAC="$MAC:"`printf "%02X\n" $[ ( $RANDOM % 255 ) + 1 ] `
|
|
MAC="$MAC:"`printf "%02X\n" $[ ( $RANDOM % 255 ) + 1 ] `
|
|
MAC="$MAC:"`printf "%02X\n" $[ ( $RANDOM % 255 ) + 1 ] `
|
|
echo $MAC
|
|
#NET_DEV_MAC="$MAC"
|
|
}
|
|
|
|
gen_ip_addr(){
|
|
local DUP=""
|
|
until [ "$DUP" = "N" ]
|
|
do
|
|
local IP=10.$(( 1+(`od -An -N2 -i /dev/random` )%(254-1+1) )).$(( 1+(`od -An -N2 -i /dev/random` )%(254-1+1) )).$(( 1+(`od -An -N2 -i /dev/random` )%(254-1+1) ))
|
|
local NET_ID=`echo $IP|cut -d "." -f 1-3`.0\/$DEFAULT_SNM
|
|
if ! ip route show | grep "$NET_ID" && ! ip addr show | grep "$IP"
|
|
then
|
|
DUP="N"
|
|
fi
|
|
done
|
|
echo "$IP"/$DEFAULT_SNM
|
|
#NET_DEV_IP="$IP"\/24
|
|
}
|
|
|
|
#***** Option Finding Functions *******************************************
|
|
find_next_net_number() {
|
|
# Variables passed in (only one of the following):
|
|
# $BRIDGE_NAME $NAT_NAME $HOSTONLY_NAME $ROUTE_NAME $NOHOST_NAME $EMPTY_NAME
|
|
|
|
local TYPE_NAME="$1"
|
|
if [ -z $NET_NUMBER ]
|
|
then
|
|
local BRIDGE_TYPE_LIST=`ip addr show | grep ".*: $TYPE_NAME" | cut -d ":" -f 2 | cut -d " " -f 2`
|
|
for BRIDGE in $BRIDGE_TYPE_LIST
|
|
do
|
|
NET_NUMBER=${BRIDGE##${BRIDGE%%[0-9]*}}
|
|
done
|
|
((NET_NUMBER++))
|
|
|
|
if [ "$NET_NUMBER" -eq "1" ] && ! ip addr show | grep -q ".*: $TYPE_NAME"0
|
|
then
|
|
#((NET_NUMBER--))
|
|
NET_NUMBER="0"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
find_next_net_device() {
|
|
# Variables passed in (only one fo the following):
|
|
# $BRIDGE_NAME $NAT_NAME $HOSTONLY_NAME $ROUTE_NAME $NOHOST_NAME
|
|
|
|
local DEV_NUMBER
|
|
local TYPE_NAME="$1"
|
|
if [ -z $NET_DEV ]
|
|
then
|
|
case $NET_TYPE in
|
|
bridge|nohost)
|
|
DEV_NAME="$DEFAULT_PDEV"
|
|
;;
|
|
nat|hostonly|route)
|
|
DEV_NAME="$DEFAULT_VDEV"
|
|
;;
|
|
esac
|
|
|
|
local DEV_LIST=`ip addr show | grep ".*: $DEV_NAME" | cut -d ":" -f 2 | cut -d " " -f 2`
|
|
for DEVICE in $DEV_LIST
|
|
do
|
|
DEV_NUMBER=${DEVICE##${DEVICE%%[0-9]*}}
|
|
done
|
|
NEXT_DEV_NUMBER="$DEV_NUMBER"
|
|
((NEXT_DEV_NUMBER++))
|
|
|
|
case $NET_TYPE in
|
|
bridge|nohost)
|
|
if ! ip addr show | grep -q ".*: $DEV_NAME$DEV_NUMBER" && ! ip addr show | grep -q ".*: $TYPE_NAME$DEV_NUMBER"
|
|
then
|
|
NET_DEV="$DEFAULT_DEV$DEV_NUMBER"
|
|
VIF_COUNT="$DEV_NUMBER"
|
|
else
|
|
NET_DEV="$DEFAULT_DEV$NEXT_DEV_NUMBER"
|
|
VIF_COUNT="$NEXT_DEV_NUMBER"
|
|
fi
|
|
;;
|
|
nat|hostonly|route)
|
|
if ! ip addr show | grep -q ".*: $TYPE_NAME$DEV_NUMBER"
|
|
then
|
|
NET_DEV="$DEV_NAME$DEV_NUMBER"
|
|
VIF_COUNT="$DEV_NUMBER"
|
|
else
|
|
NET_DEV="$DEV_NAME$NEXT_DEV_NUMBER"
|
|
VIF_COUNT="$NEXT_DEV_NUMBER"
|
|
fi
|
|
;;
|
|
esac
|
|
fi
|
|
}
|
|
|
|
find_network_type() {
|
|
if echo "$1" | grep -q "$BRIDGE_NAME"
|
|
then
|
|
NET_TYPE="bridge"
|
|
elif echo "$1" | grep -q "$NAT_NAME"
|
|
then
|
|
NET_TYPE="nat"
|
|
elif echo "$1" | grep -q "$HOSTONLY_NAME"
|
|
then
|
|
NET_TYPE="hostonly"
|
|
elif echo "$1" | grep -q "$ROUTE_NAME"
|
|
then
|
|
NET_TYPE="route"
|
|
elif echo "$1" | grep -q "$NOHOST_NAME"
|
|
then
|
|
NET_TYPE="nohost"
|
|
elif echo "$1" | grep -q "$EMPTY_NAME"
|
|
then
|
|
NET_TYPE="empty"
|
|
fi
|
|
}
|
|
|
|
#***** Network Creation/Deletion Functions ********************************
|
|
create_network() {
|
|
# The variable CMD_OPT must be set to one of the following before calling
|
|
# this function: start, stop, status
|
|
|
|
case $MODE in
|
|
add)
|
|
case $NET_TYPE in
|
|
bridge)
|
|
find_next_net_number $BRIDGE_NAME
|
|
find_next_net_device $BRIDGE_NAME
|
|
|
|
echo "Creating network of type: $NET_TYPE"
|
|
echo " Named: $BRIDGE_NAME$NET_NUMBER"
|
|
echo " On interface: $NET_DEV"
|
|
echo " Switchport: vif0.$VIF_COUNT"
|
|
|
|
|
|
# Create the network
|
|
#---------------------------------------------------------------------
|
|
create_bridged_networks $NET_DEV $NET_NUMBER
|
|
|
|
;;
|
|
nat|hostonly|route)
|
|
if [ -z $NET_NUMBER ]
|
|
then
|
|
case $NET_TYPE in
|
|
nat)
|
|
find_next_net_number $NAT_NAME
|
|
find_next_net_device $NAT_NAME
|
|
;;
|
|
hostonly)
|
|
find_next_net_number $HOSTONLY_NAME
|
|
find_next_net_device $HOSTONLY_NAME
|
|
;;
|
|
route)
|
|
find_next_net_number $ROUTE_NAME
|
|
find_next_net_device $ROUTE_NAME
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
if [ -z $NET_DEV_MAC ]
|
|
then
|
|
echo "No MAC address was not supplied. Generating MAC"
|
|
NET_DEV_MAC="`gen_mac_addr`"
|
|
fi
|
|
|
|
if [ -z $NET_DEV_IP ]
|
|
then
|
|
echo "The IP address was not supplied. Generating IP"
|
|
NET_DEV_IP="`gen_ip_addr`"
|
|
fi
|
|
|
|
echo "Creating network of type: $NET_TYPE"
|
|
case $NET_TYPE in
|
|
nat)
|
|
echo " Named: $NAT_NAME$NET_NUMBER"
|
|
;;
|
|
hostonly)
|
|
echo " Named: $HOSTONLY_NAME$NET_NUMBER"
|
|
;;
|
|
route)
|
|
echo " Named: $ROUTE_NAME$NET_NUMBER"
|
|
;;
|
|
esac
|
|
echo " On interface: $NET_DEV"
|
|
echo " Switchport: vif0.$VIF_COUNT"
|
|
echo " MAC Addr: $NET_DEV_MAC"
|
|
echo " IP Address: $NET_DEV_IP"
|
|
echo " DHCP: $NET_DHCP_SRV"
|
|
|
|
|
|
# Create the network
|
|
#---------------------------------------------------------------------
|
|
create_local_networks $NET_DEV $NET_TYPE $NET_NUMBER $NET_DEV_MAC $NET_DEV_IP $NET_DHCP_SRV
|
|
|
|
;;
|
|
nohost)
|
|
if [ -z $NET_NUMBER ]
|
|
then
|
|
find_next_net_number $NOHOST_NAME
|
|
fi
|
|
|
|
find_next_net_device $NOHOST_NAME
|
|
|
|
echo "Creating network of type: $NET_TYPE"
|
|
echo " Named: $NOHOST_NAME$NET_NUMBER"
|
|
echo " On interface: $NET_DEV"
|
|
|
|
|
|
# Create the network
|
|
#---------------------------------------------------------------------
|
|
create_nohost_networks $NET_DEV $NET_NUMBER
|
|
|
|
;;
|
|
empty)
|
|
if [ -z $NET_NUMBER ]
|
|
then
|
|
find_next_net_number $EMPTY_NAME
|
|
fi
|
|
|
|
echo "Creating network of type: $NET_TYPE"
|
|
echo " Named: $EMPTY_NAME$NET_NUMBER"
|
|
|
|
|
|
# Create the network
|
|
#---------------------------------------------------------------------
|
|
create_empty_networks $NET_NUMBER
|
|
|
|
;;
|
|
*)
|
|
echo "Error: Incorrect Bridge Type: $NET_TYPE"
|
|
exit 1
|
|
;;
|
|
esac
|
|
;;
|
|
del)
|
|
VIF_COUNT=`grep $NET_NAME $NETWORK_SAVE_FILE | cut -d "," -f 2`
|
|
NET_TYPE=`grep $NET_NAME $NETWORK_SAVE_FILE | cut -d "," -f 3`
|
|
NET_NUMBER=`grep $NET_NAME $NETWORK_SAVE_FILE | cut -d "," -f 4`
|
|
NET_DEV=`grep $NET_NAME $NETWORK_SAVE_FILE | cut -d "," -f 5`
|
|
NET_DEV_MAC=`grep $NET_NAME $NETWORK_SAVE_FILE | cut -d "," -f 6`
|
|
NET_DEV_IP=`grep $NET_NAME $NETWORK_SAVE_FILE | cut -d "," -f 7`
|
|
NET_DEV_DHCP_SRV=`grep $NET_NAME $NETWORK_SAVE_FILE | cut -d "," -f 8`
|
|
|
|
echo "Removing network: $NET_NAME"
|
|
|
|
# Remove the network
|
|
#---------------------------------------------------------------------
|
|
case $NET_TYPE in
|
|
bridge)
|
|
create_bridged_networks $NET_DEV $NET_NUMBER
|
|
;;
|
|
nat|hostonly|route)
|
|
create_local_networks $NET_DEV $NET_TYPE $NET_NUMBER $NET_DEV_MAC $NET_DEV_IP $NET_DHCP_SRV
|
|
;;
|
|
nohost)
|
|
create_nohost_networks $NET_DEV $NET_NUMBER
|
|
;;
|
|
empty)
|
|
create_empty_networks $NET_NUMBER
|
|
;;
|
|
esac
|
|
;;
|
|
esac
|
|
}
|
|
|
|
#***** Network Renameing Functions ****************************************
|
|
modify_network() {
|
|
echo
|
|
echo "Modifying networks is currently unsupported."
|
|
echo
|
|
}
|
|
|
|
#***** Network Showing Functions ******************************************
|
|
show_networks() {
|
|
ACTIVE_NETWORK_LIST=`ip addr show | grep "xen" | cut -d ":" -f 2 | cut -d " " -f 2`
|
|
|
|
echo
|
|
echo "--------------------------------------"
|
|
echo " Active Virtual Networks"
|
|
echo "--------------------------------------"
|
|
for NET in $ACTIVE_NETWORK_LIST
|
|
do
|
|
echo $NET
|
|
echo
|
|
done
|
|
}
|
|
|
|
#### Main Code Body #######################################################
|
|
|
|
get_mode $*
|
|
|
|
touch $NETWORK_SAVE_FILE
|
|
|
|
case $MODE in
|
|
add)
|
|
CMD_OPT="start"
|
|
create_network
|
|
;;
|
|
del)
|
|
CMD_OPT="stop"
|
|
create_network
|
|
;;
|
|
delall)
|
|
CMD_OPT="stop"
|
|
remove_all_networks
|
|
mod)
|
|
modify_network
|
|
exit 0
|
|
;;
|
|
show)
|
|
show_networks
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo "Only the following modes are supported: add|del|delall|rename|show"
|
|
;;
|
|
esac
|
|
|
|
exit 0
|