SHA256
1
0
forked from pool/xen
xen/xend-network

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