1215 lines
37 KiB
Bash
1215 lines
37 KiB
Bash
#!/bin/sh
|
|
#============================================================================
|
|
# multinet-common
|
|
#
|
|
# 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:
|
|
#
|
|
# Function library for network-multinet and all other multinet related scripts
|
|
#
|
|
#============================================================================
|
|
|
|
BRIDGE_NAME="xenbr"
|
|
HOSTONLY_NAME="xenhost"
|
|
NAT_NAME="xennat"
|
|
ROUTE_NAME="xenroute"
|
|
NOHOST_NAME="xennohost"
|
|
EMPTY_NAME="xenempty"
|
|
|
|
DEFAULT_DEV="eth"
|
|
DEFAULT_PDEV="peth"
|
|
DEFAULT_VDEV="veth"
|
|
|
|
#### Script Functions #####################################################
|
|
|
|
#***** Generic Functions **************************************************
|
|
|
|
evalVariables() {
|
|
for arg in "$@"
|
|
do
|
|
if expr 'index' "$arg" '=' '>' '1' >/dev/null
|
|
then
|
|
eval "$arg"
|
|
fi
|
|
done
|
|
}
|
|
|
|
findCommand() {
|
|
for arg in "$@"
|
|
do
|
|
if ! expr 'index' "$arg" '=' >/dev/null
|
|
then
|
|
command="$arg"
|
|
return
|
|
fi
|
|
done
|
|
}
|
|
|
|
#***** Firewall/Routing Functions *****************************************
|
|
|
|
manage_routing() {
|
|
# Saves and restores the ip forward and Network Address Translation state
|
|
# that exist before the script runs
|
|
#
|
|
# This function reads the start,stop parameter from the $CMD_OPT
|
|
# variable and responds respectively.
|
|
|
|
case $1 in
|
|
start)
|
|
#------------------------------------------------------------------
|
|
# Determine the initial state of the ip_forward parameter
|
|
#------------------------------------------------------------------
|
|
case `cat /proc/sys/net/ipv4/ip_forward` in
|
|
0)
|
|
INIT_IP_FWD="off"
|
|
echo "0" > $NETWORK_SAVE_PATH/init_ip_fwd_state
|
|
;;
|
|
1)
|
|
INIT_IP_FWD="on"
|
|
echo "1" > $NETWORK_SAVE_PATH/init_ip_fwd_state
|
|
;;
|
|
esac
|
|
|
|
#------------------------------------------------------------------
|
|
# Determine if we need to enable ip_forward
|
|
#------------------------------------------------------------------
|
|
if echo $NETWORK_LIST | grep -qE "(nat|NAT|route|ROUTE)"
|
|
then
|
|
IP_FWD="on"
|
|
echo ""
|
|
echo "============================================================"
|
|
echo "Enabling IP Forwarding"
|
|
echo "============================================================"
|
|
echo 1 > /proc/sys/net/ipv4/ip_forward
|
|
else
|
|
IP_FWD="off"
|
|
echo ""
|
|
echo "============================================================"
|
|
echo "Disabling IP Forwarding"
|
|
echo "============================================================"
|
|
echo 0 > /proc/sys/net/ipv4/ip_forward
|
|
fi
|
|
|
|
#------------------------------------------------------------------
|
|
# Determine if we need to enable NAT
|
|
#------------------------------------------------------------------
|
|
if echo $NETWORK_LIST | grep -qE "(nat|NAT)"
|
|
then
|
|
echo ""
|
|
echo "============================================================"
|
|
echo "Enabling Network Adress Translation"
|
|
echo "============================================================"
|
|
iptables -t nat -A POSTROUTING -o $NAT_EXTERNAL_INTERFACE -j MASQUERADE
|
|
sysctl -q -w net.bridge.bridge-nf-call-iptables="0"
|
|
NAT_DONE="yes"
|
|
fi
|
|
;;
|
|
stop)
|
|
#------------------------------------------------------------------
|
|
# Set the ip_forward value back to its original state
|
|
#------------------------------------------------------------------
|
|
echo ""
|
|
echo "============================================================"
|
|
echo "Restoring IP Forwarding to its original state"
|
|
echo "============================================================"
|
|
case `cat $NETWORK_SAVE_PATH/init_ip_fwd_state` in
|
|
0)
|
|
echo "ip_forward = 0"
|
|
echo "0" > /proc/sys/net/ipv4/ip_forward
|
|
;;
|
|
1)
|
|
echo "ip_forward = 0"
|
|
echo "1" > /proc/sys/net/ipv4/ip_forward
|
|
;;
|
|
*)
|
|
echo "Original state unknown. Using default value."
|
|
echo "ip_forward = 0"
|
|
echo "0" > /proc/sys/net/ipv4/ip_forward
|
|
;;
|
|
esac
|
|
|
|
#------------------------------------------------------------------
|
|
# Clean up init_ip_fwd_state file
|
|
#------------------------------------------------------------------
|
|
rm $NETWORK_SAVE_PATH/init_ip_fwd_state
|
|
;;
|
|
esac
|
|
}
|
|
|
|
manage_susefirewall2() {
|
|
case $1 in
|
|
stop)
|
|
if [ -e /etc/init.d/SuSEfirewall2_setup ] && /etc/init.d/SuSEfirewall2_setup status | grep -iwq "running"
|
|
then
|
|
echo ""
|
|
echo "============================================================"
|
|
echo "Stopping SuSEfirewall2"
|
|
echo "============================================================"
|
|
/etc/init.d/SuSEfirewall2_setup stop > /dev/null
|
|
echo "0" > $NETWORK_SAVE_PATH/sf2
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
;;
|
|
start)
|
|
if [ -e $NETWORK_SAVE_PATH/sf2 ] && grep "0" $NETWORK_SAVE_PATH/sf2
|
|
then
|
|
echo ""
|
|
echo "============================================================"
|
|
echo "Starting SuSEfirewall2"
|
|
echo "============================================================"
|
|
/etc/init.d/SuSEfirewall2_setup start > /dev/null
|
|
rm -rf $NETWORK_SAVE_PATH/sf2
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
;;
|
|
esac
|
|
}
|
|
|
|
manage_iptables() {
|
|
# Saves and restores the iptables rules that exist before the script runs
|
|
#
|
|
# This function reads the start,stop parameter from the $CMD_OPT
|
|
# variable and responds respectively.
|
|
|
|
case $1 in
|
|
stop)
|
|
echo ""
|
|
echo "============================================================"
|
|
echo "Saving iptables rules"
|
|
echo "============================================================"
|
|
|
|
#----------------------------------------------------------------
|
|
# Saving iptables rules for $TABLE to a file
|
|
#----------------------------------------------------------------
|
|
for TABLE in `iptables-save |grep '*'|cut -d '*' -f 2`
|
|
do
|
|
echo "Saving table: $TABLE"
|
|
iptables-save -t $TABLE > $IPTABLES_SAVE_FILE@$TABLE
|
|
echo "Flushing table: $TABLE"
|
|
iptables -F -t $TABLE
|
|
echo "-----------------------"
|
|
done
|
|
|
|
#----------------------------------------------------------------
|
|
# Deleting any custom chain
|
|
#----------------------------------------------------------------
|
|
for CHAIN in `iptables-save |grep ^:|cut -d ":" -f 2|cut -d " " -f 1`
|
|
do
|
|
case $CHAIN in
|
|
INPUT|OUTPUT|FORWARD|PREROUTING|POSTROUTING)
|
|
#do nothing
|
|
;;
|
|
*)
|
|
echo "Deteting chain: $CHAIN"
|
|
iptables -X $CHAIN
|
|
;;
|
|
esac
|
|
done
|
|
;;
|
|
start)
|
|
echo ""
|
|
echo "============================================================"
|
|
echo "Restoring iptables rules"
|
|
echo "============================================================"
|
|
|
|
#----------------------------------------------------------------
|
|
# Restoring iptables rules for $TABLE
|
|
#----------------------------------------------------------------
|
|
for TABLE in `ls $IPTABLES_SAVE_FILE*|cut -d "@" -f 2`
|
|
do
|
|
echo "Restoring table: $TABLE"
|
|
iptables-restore < $IPTABLES_SAVE_FILE@$TABLE
|
|
rm $IPTABLES_SAVE_FILE@$TABLE
|
|
echo "-----------------------"
|
|
done
|
|
;;
|
|
esac
|
|
}
|
|
|
|
#***** Traditional Bridge Helper Functions ********************************
|
|
|
|
setup_bridge_port() {
|
|
local dev="$1"
|
|
|
|
# take interface down ...
|
|
ip link set ${dev} down
|
|
|
|
# ... and configure it
|
|
ip link set ${dev} arp off
|
|
ip link set ${dev} multicast off
|
|
ip link set ${dev} addr fe:ff:ff:ff:ff:ff
|
|
ip addr flush ${dev}
|
|
}
|
|
|
|
create_bridge () {
|
|
# Usage: create_bridge bridge
|
|
local bridge=$1
|
|
|
|
# Don't create the bridge if it already exists.
|
|
if [ ! -e "/sys/class/net/${bridge}/bridge" ]; then
|
|
brctl addbr ${bridge}
|
|
brctl stp ${bridge} off
|
|
brctl setfd ${bridge} 0
|
|
ip link set ${bridge} arp off
|
|
ip link set ${bridge} multicast off
|
|
fi
|
|
ip link set ${bridge} up
|
|
}
|
|
|
|
add_to_bridge () {
|
|
# Usage: add_to_bridge bridge dev
|
|
local bridge=$1
|
|
local dev=$2
|
|
|
|
# Don't add $dev to $bridge if it's already on a bridge.
|
|
if [ -e "/sys/class/net/${bridge}/brif/${dev}" ]; then
|
|
ip link set ${dev} up || true
|
|
return
|
|
fi
|
|
brctl addif ${bridge} ${dev}
|
|
ip link set ${dev} up
|
|
}
|
|
|
|
add_to_bridge2() {
|
|
local bridge=$1
|
|
local dev=$2
|
|
local maxtries=10
|
|
|
|
echo -n "Waiting for ${dev} to negotiate link."
|
|
ip link set ${dev} up
|
|
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}
|
|
}
|
|
|
|
transfer_addrs () {
|
|
# Usage: transfer_addrs src dst
|
|
# Copy all IP addresses (including aliases) from device $src to device $dst.
|
|
local src=$1
|
|
local dst=$2
|
|
# Don't bother if $dst already has IP addresses.
|
|
if ip addr show dev ${dst} | egrep -q '^ *inet ' ; then
|
|
return
|
|
fi
|
|
# Address lines start with 'inet' and have the device in them.
|
|
# Replace 'inet' with 'ip addr add' and change the device name $src
|
|
# to 'dev $src'.
|
|
ip addr show dev ${src} | egrep '^ *inet ' | sed -e "
|
|
s/inet/ip addr add/
|
|
s@\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+/[0-9]\+\)@\1@
|
|
s/${src}/dev ${dst}/
|
|
" | sh -e
|
|
# Remove automatic routes on destination device
|
|
ip route list | sed -ne "
|
|
/dev ${dst}\( \|$\)/ {
|
|
s/^/ip route del /
|
|
p
|
|
}" | sh -e
|
|
}
|
|
|
|
transfer_routes () {
|
|
# Usage: transfer_routes src dst
|
|
# Get all IP routes to device $src, delete them, and
|
|
# add the same routes to device $dst.
|
|
# The original routes have to be deleted, otherwise adding them
|
|
# for $dst fails (duplicate routes).
|
|
local src=$1
|
|
local dst=$2
|
|
# List all routes and grep the ones with $src in.
|
|
# Stick 'ip route del' on the front to delete.
|
|
# Change $src to $dst and use 'ip route add' to add.
|
|
ip route list | sed -ne "
|
|
/dev ${src}\( \|$\)/ {
|
|
h
|
|
s/^/ip route del /
|
|
P
|
|
g
|
|
s/${src}/${dst}/
|
|
s/^/ip route add /
|
|
P
|
|
d
|
|
}" | sh -e
|
|
}
|
|
|
|
link_exists() {
|
|
##
|
|
# link_exists interface
|
|
#
|
|
# Returns 0 if the interface named exists (whether up or down), 1 otherwise.
|
|
#
|
|
if ip link show "$1" >/dev/null 2>/dev/null
|
|
then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
antispoofing () {
|
|
# Set the default forwarding policy for $dev to drop.
|
|
# Allow forwarding to the bridge.
|
|
iptables -P FORWARD DROP
|
|
iptables -F FORWARD
|
|
iptables -A FORWARD -m physdev --physdev-in ${pdev} -j ACCEPT
|
|
iptables -A FORWARD -m physdev --physdev-in ${vif0} -j ACCEPT
|
|
}
|
|
|
|
find_active_vlans() {
|
|
local netdev=$1
|
|
local vlan
|
|
local vlans
|
|
vlans=""
|
|
for vifcfg in /etc/sysconfig/network/ifcfg-vlan* ; do
|
|
vlan=${vifcfg/*\/ifcfg-}
|
|
if [ "$vlan" = "vlan*" ]; then
|
|
continue
|
|
fi
|
|
. $vifcfg
|
|
etherdevice="$ETHERDEVICE"
|
|
if [ -x /sbin/getcfg-interface ]; then
|
|
etherdevice=$(/sbin/getcfg-interface "$ETHERDEVICE")
|
|
fi
|
|
if [ "$ETHERDEVICE" = "$netdev" ] || [ "$etherdevice" = "$netdev" ] ; then
|
|
link_exists "$vlan" && vlans="$vlans $vlan"
|
|
fi
|
|
done
|
|
echo "$vlans"
|
|
}
|
|
|
|
get_ifcfg_file() {
|
|
local HWD_CONFIG_0=
|
|
local netdev="$DEV"
|
|
eval `/sbin/getcfg -d /etc/sysconfig/network/ -f ifcfg- -- "$netdev" | grep "HWD_CONFIG_0="`
|
|
if [ -n "$HWD_CONFIG_0" ]; then
|
|
hwddev="$HWD_CONFIG_0"
|
|
fi
|
|
}
|
|
|
|
find_bridged_netdev () {
|
|
# Find the netdev that is associated with the bridge by matching MAC addresses.
|
|
local bridge=$1
|
|
|
|
bmac=`ip link show ${bridge} | grep 'link\/ether' | sed -e 's/.*ether \(..:..:..:..:..:..\).*/\1/'`
|
|
for i in `ls /sys/class/net/${bridge}/brif` ; do
|
|
mac=`ip link show ${i} | grep 'link\/ether' | sed -e 's/.*ether \(..:..:..:..:..:..\).*/\1/'`
|
|
if [ "${bmac}" = "$MAC" ] && [ ! "${bridge}" = "${i}" ] ; then
|
|
netdev=${i}
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
create_bonded_bridge() {
|
|
|
|
# passed in variabiles:
|
|
# start|stop $DEV $VDEV $PDEV $BRIDGE $VIF0
|
|
|
|
local netdev="$2"
|
|
local vdev="$3"
|
|
local pdev="$4"
|
|
local bridge="$5"
|
|
local vif0="$6"
|
|
|
|
vlans=$(find_active_vlans "${netdev}")
|
|
for vlan in $vlans ; do ifdown $vlan ; done
|
|
|
|
case $1 in
|
|
start)
|
|
local NETDEV_IP=`ip addr show dev ${netdev}|egrep '^ *inet '|sed "s/^ *inet //"|cut -d " " -f 1`
|
|
local BONDSLAVE_LIST=`ifstatus ${netdev} | egrep -i "slave interface" | cut -d ":" -f 2 | sed "s/ //"`
|
|
local MAC=`ip link show ${netdev} | grep 'link\/ether' | sed -e 's/.*ether \(..:..:..:..:..:..\).*/\1/'`
|
|
local BRIDGE_NUM=${netdev##${netdev%%[0-9]*}}
|
|
local GATEWAY=`ip route show | grep "^default" | cut -d " " -f 3`
|
|
PDEV=eth${BRIDGE_NUM}
|
|
new_netdev=eth${BRIDGE_NUM}
|
|
|
|
#echo "netdev = ${netdev}"
|
|
#echo "NETDEV_IP = $NETDEV_IP"
|
|
#echo "GATEWAY = $GATEWAY"
|
|
#echo "BONDSLAVE_LIST = $BONDSLAVE_LIST"
|
|
#echo "MAC = $MAC"
|
|
#echo "BRIDGE_NUM = $BRIDGE_NUM"
|
|
#echo "new_netdev = $new_netdev"
|
|
#echo "vdev = $vdev"
|
|
#echo "pdev = $pdev"
|
|
#echo "bridge = $bridge"
|
|
#echo "vif0 = $vif0"
|
|
#read
|
|
|
|
#ip link set ${bridge} arp on
|
|
|
|
##### We must reconfigure the bonded interface first #####
|
|
#echo "bring bonded interface ${netdev} down";read
|
|
ip link set ${netdev} down
|
|
ip link set ${netdev} arp off
|
|
ip link set ${netdev} multicast off
|
|
ip link set ${netdev} addr fe:ff:ff:ff:ff:ff
|
|
ip addr flush ${netdev}
|
|
|
|
#echo "rename the bondslave interfaces";read
|
|
for DEV in $BONDSLAVE_LIST
|
|
do
|
|
ip link set ${DEV} name p${DEV}
|
|
done
|
|
|
|
#echo "bring ${netdev} back up with new bondslave names";read
|
|
ifup ${netdev}
|
|
#ip link set ${netdev} arp on
|
|
#ip link set ${netdev} multicast on
|
|
|
|
##### Here is where we attach the bridge ports to the bridge #####
|
|
#echo "bring up the bridge ${bridge}";read
|
|
ip link set ${bridge} up
|
|
|
|
#echo "add ${netdev} to bridge as a bridge port";read
|
|
add_to_bridge2 ${bridge} ${netdev}
|
|
|
|
#echo "add ${vif0} to bridge as a ${bridge} port";read
|
|
add_to_bridge ${bridge} ${vif0}
|
|
|
|
#echo "clean up ${vif0} (arp off, change MAC, flush IP address, etc.)";read
|
|
setup_bridge_port ${vif0}
|
|
|
|
#echo "bring ${vif0} up";read
|
|
ip link set ${vif0} up
|
|
|
|
##### Next we must configure the new interface for Dom0 #####
|
|
#echo "make sure the ${vdev} interface is down";read
|
|
ip link set ${vdev} down
|
|
|
|
#echo "rename ${vdev} to ${pdev}";read
|
|
ip link set ${vdev} name ${pdev}
|
|
|
|
#echo "transfer ${netdev}'s MAC address to ${pdev} and turn arp on";read
|
|
ip link set ${pdev} addr $MAC arp on
|
|
|
|
#echo "bring new ${pdev} interface up";read
|
|
ip link set ${pdev} up
|
|
|
|
#echo "transfer ${netdev}'s IP address to ${pdev}";read
|
|
ip addr add dev ${pdev} $NETDEV_IP brd +
|
|
|
|
#echo "remove ${netdev}'s IP address";read
|
|
ip addr del dev ${netdev} $NETDEV_IP
|
|
|
|
#echo "transfer ${netdev}'s routes to ${pdev}";read
|
|
#if ! echo ${netdev} | grep -qi "bond"
|
|
#then
|
|
transfer_routes ${netdev} ${pdev}
|
|
#fi
|
|
|
|
#echo "add new default route via ${pdev}";read
|
|
ip route add default via $GATEWAY
|
|
;;
|
|
stop)
|
|
local BRIDGE_NUM=${netdev##${netdev%%[0-9]*}}
|
|
local pdev=eth${BRIDGE_NUM}
|
|
local new_netdev=eth${BRIDGE_NUM}
|
|
local GATEWAY=`ip route show | grep "^default" | cut -d " " -f 3`
|
|
local NETDEV_IP=`ip addr show dev ${pdev}|egrep '^ *inet '|sed "s/^ *inet //"|cut -d " " -f 1`
|
|
local BONDSLAVE_LIST=`ifstatus ${netdev} | egrep -i "slave interface" | cut -d ":" -f 2 | sed "s/ //"`
|
|
local MAC=`ip link show ${pdev} | grep 'link\/ether' | sed -e 's/.*ether \(..:..:..:..:..:..\).*/\1/'`
|
|
|
|
#echo "netdev = ${netdev}"
|
|
#echo "NETDEV_IP = $NETDEV_IP"
|
|
#echo "BONDSLAVE_LIST = $BONDSLAVE_LIST"
|
|
#echo "MAC = $MAC"
|
|
#echo "BRIDGE_NUM = $BRIDGE_NUM"
|
|
#echo "new_netdev = $new_netdev"
|
|
#echo "vdev = $vdev"
|
|
#echo "pdev = $pdev"
|
|
#echo "bridge = $bridge"
|
|
#echo "vif0 = $vif0"
|
|
#read
|
|
|
|
##### First we reset the virtual interface ${pdev} #####
|
|
#echo "bring ${pdev} down";read
|
|
ip link set ${pdev} down arp off
|
|
ip link set ${pdev} addr fe:ff:ff:ff:ff:ff
|
|
ip addr flush ${pdev}
|
|
|
|
##### Then we reset the bridge port ${vif0} #####
|
|
#echo "bring ${vif0} down";read
|
|
ip link set dev ${vif0} down
|
|
|
|
##### Then we reset the bonded interface ${netdev} #####
|
|
#echo "bring the bonded interface ${netdev} down";read
|
|
ip link set ${netdev} down
|
|
#ip link set ${netdev} down arp off
|
|
#ip link set ${netdev} addr fe:ff:ff:ff:ff:ff
|
|
ip addr flush ${netdev}
|
|
|
|
##### Then we remove the bridge port interfaces from the bridge #####
|
|
#echo "removing ${netdev} from ${bridge}";read
|
|
brctl delif ${bridge} ${netdev}
|
|
|
|
#echo "removing ${vif0} from ${bridge}";read
|
|
brctl delif ${bridge} ${vif0}
|
|
|
|
##### Then we rename the virtual interface back to its original name #####
|
|
#echo "rename ${pdev} to ${vdev}";read
|
|
ip link set ${pdev} name ${vdev}
|
|
|
|
##### Then we reset the renamed bond slave interface ${pdev}
|
|
for DEV in $BONDSLAVE_LIST
|
|
do
|
|
local OLD_DEV=`echo ${DEV}|sed "s/p//"`
|
|
#echo "bring the bond slave ${DEV} down";read
|
|
ip link set ${DEV} down
|
|
#echo "rename the bond slave ${DEV} to ${OLD_DEV}";read
|
|
ip link set ${DEV} name ${OLD_DEV}
|
|
done
|
|
|
|
##### And then we restart the bonded interface #####
|
|
#echo "bring bonded interface back up";read
|
|
ifup ${netdev}
|
|
|
|
##### Then we bring the bridge ${bridge} down #####
|
|
#echo "bring the bridge ${bridge} down";read
|
|
ip link set ${bridge} down
|
|
;;
|
|
esac
|
|
|
|
for vlan in $vlans ; do ifup $vlan ; done
|
|
}
|
|
|
|
create_normal_bridge() {
|
|
|
|
# passed in variabiles:
|
|
# start|stop $DEV $VDEV $PDEV $BRIDGE $VIF0
|
|
|
|
local netdev="$2"
|
|
local vdev="$3"
|
|
local pdev="$4"
|
|
local bridge="$5"
|
|
local vif0="$6"
|
|
|
|
case $1 in
|
|
start)
|
|
local mac=`ip link show ${netdev} | grep 'link\/ether' | sed -e 's/.*ether \(..:..:..:..:..:..\).*/\1/'`
|
|
|
|
# Ensure there is an IP to transfer
|
|
#echo "Ensure there is an IP to transfer. (ifup ${netdev})";read
|
|
ifup ${netdev}
|
|
|
|
# Transfer the IP address to the virtual interface
|
|
#echo "Transfer the IP address from ${netdev} to ${vdev}";read
|
|
transfer_addrs ${netdev} ${vdev}
|
|
|
|
# Find and bring down any active VLANs
|
|
#echo "Find and bring down any active VLANs";read
|
|
local vlans=$(find_active_vlans "${netdev}")
|
|
for vlan in $vlans ; do ifdown $vlan ; done
|
|
|
|
# Bring down interface
|
|
#echo "Bring down interface (ifdown ${netdev})";read
|
|
ifdown ${netdev}
|
|
|
|
# Rename physical and virtual interfaces
|
|
#echo "Rename ${netdev} to ${pdev} & ${vdev} to ${netdev}";read
|
|
ip link set ${netdev} name ${pdev}
|
|
ip link set ${vdev} name ${netdev}
|
|
|
|
# Configure $pdev and $vif0 as bridge ports
|
|
#echo "Configure ${pdev} and ${vif0} as bridge ports";read
|
|
setup_bridge_port ${pdev}
|
|
setup_bridge_port ${vif0}
|
|
|
|
# Assign the physical MAC to the new interface
|
|
#echo "Assign the physical MAC to ${netdev}";read
|
|
ip link set ${netdev} addr ${mac} arp on
|
|
|
|
# Bring bridge up and add interfaces to it
|
|
#echo "Bring ${bridge} up and add ${vif0} and ${pdev} to it";read
|
|
ip link set ${bridge} up
|
|
add_to_bridge ${bridge} ${vif0}
|
|
add_to_bridge2 ${bridge} ${pdev}
|
|
|
|
# Bring new interface up
|
|
#echo "Bring up ${netdev} and ${hwddev}";read
|
|
ip link set ${netdev} up
|
|
ifup ${hwddev}
|
|
|
|
# Bring VLANs back up
|
|
#echo "Bring VLANs back up";read
|
|
for vlan in $vlans ; do ifup $vlan ; done
|
|
;;
|
|
stop)
|
|
# Bring down ${vif0}
|
|
#echo "Bring down ${vif0}";read
|
|
ip link set dev ${vif0} down
|
|
|
|
local mac=`ip link show ${netdev} | grep 'link\/ether' | sed -e 's/.*ether \(..:..:..:..:..:..\).*/\1/'`
|
|
|
|
# Transfer IP address back to original interface
|
|
#echo "Transfer IP address from ${netdev} to ${pdev}";read
|
|
transfer_addrs ${netdev} ${pdev}
|
|
|
|
# Find and bring down any active VLANs
|
|
#echo "Find and bring down any active VLANs";read
|
|
vlans=$(find_active_vlans "${netdev}")
|
|
for vlan in $vlans ; do ifdown $vlan ; done
|
|
|
|
# Bring down virtual network interface
|
|
#echo "Bring down ${netdev}";read
|
|
ifdown ${netdev}
|
|
|
|
# Clean up virtual network interfaces (MAC, arp, etc.)
|
|
#echo "Clean up virtual network interfaces (MAC, arp, etc.)";read
|
|
ip link set ${netdev} down arp off
|
|
ip link set ${netdev} addr fe:ff:ff:ff:ff:ff
|
|
|
|
# Bring down physical network interface
|
|
#echo "Bring down ${pdev}";read
|
|
ip link set ${pdev} down
|
|
|
|
# Flush address(es) from virtual network interface
|
|
#echo "Flush address(es) from ${netdev}";read
|
|
ip addr flush ${netdev}
|
|
|
|
# Change MAC address on physical interface
|
|
#echo "Change MAC address on ${pdev}";read
|
|
ip link set ${pdev} addr ${mac} arp on
|
|
|
|
# Remove interfaces from bridge
|
|
#echo "Remove interfaces ${pdev} and ${vif0} from ${bridge}";read
|
|
brctl delif ${bridge} ${pdev}
|
|
brctl delif ${bridge} ${vif0}
|
|
|
|
# Bring down bridge
|
|
#echo "Bring down ${bridge}";read
|
|
ip link set ${bridge} down
|
|
|
|
# Rename physical and virtual network interfaces
|
|
#echo "Rename ${netdev} to ${vdev} & ${pdev} to ${netdev}";read
|
|
ip link set ${netdev} name ${vdev}
|
|
ip link set ${pdev} name ${netdev}
|
|
|
|
# Bring renamed physical interface up
|
|
#echo "Bring up ${netdev}";read
|
|
ifup ${netdev}
|
|
|
|
# Bring VLANs back up
|
|
#echo "Bring VLANs back up";read
|
|
for vlan in $vlans ; do ifup $vlan ; done
|
|
;;
|
|
esac
|
|
|
|
}
|
|
|
|
#***** NAT/HostOnly Helper Functions **************************************
|
|
|
|
setup_host_interface() {
|
|
# Configure the MAC and IP address of a virtual device.
|
|
#
|
|
# This function is called by other fuctions.
|
|
#
|
|
# usage: setup_host_interface <virtual net device> <MAC Addr> <IP Addr>
|
|
|
|
local DEV="$1"
|
|
local MAC="$2"
|
|
local IPADDR="$3"
|
|
|
|
case $CMD_OPT in
|
|
start)
|
|
# take the interface down
|
|
ip link set $DEV down
|
|
|
|
# ... and configure it
|
|
ip link set $DEV addr $MAC
|
|
ip addr flush $DEV
|
|
ip addr add $IPADDR brd + dev $DEV
|
|
|
|
# bring it back up
|
|
ip link set $DEV up
|
|
ip link set $DEV arp on
|
|
;;
|
|
stop)
|
|
# take the interface down
|
|
ip link set $DEV down
|
|
|
|
# unconfigure it
|
|
ip link set $DEV addr fe:ff:ff:ff:ff:ff
|
|
ip addr flush $DEV
|
|
;;
|
|
status)
|
|
ip addr show $DEV
|
|
;;
|
|
esac
|
|
}
|
|
|
|
#***** Network Type Creation Functions ************************************
|
|
|
|
create_bridged_networks() {
|
|
# Creates traditional bridges on physical devices in Dom0.
|
|
#
|
|
# Variables passed in in order: $NET_DEV $NET_NUMBER
|
|
|
|
local DEV=$1
|
|
local NUMBER=$2
|
|
local NAME=$BRIDGE_NAME$NUMBER
|
|
local BRIDGE="$NAME"
|
|
local VDEV="veth$VIF_COUNT"
|
|
local PDEV="p$DEV"
|
|
local VIF0="vif0.$VIF_COUNT"
|
|
local VIF_NUM=$VIF_COUNT
|
|
|
|
# Test if $BRIDGE is set
|
|
if [ "$BRIDGE" = "null" ]
|
|
then
|
|
return
|
|
fi
|
|
|
|
case $CMD_OPT in
|
|
start)
|
|
if /sbin/ip link show $DEV | grep -qw UP
|
|
then
|
|
echo ""
|
|
echo "============================================================"
|
|
echo "Configuring Virtual Network: $NAME"
|
|
echo " of type: $TYPE"
|
|
echo " on- Physical Interface: $DEV"
|
|
echo " Virtual Interface: vif$NUMBER"
|
|
echo "============================================================"
|
|
echo ""
|
|
#$SCRIPT_PATH/network_bridge $CMD_OPT netdev=$DEV bridge=$NAME vifnum=$VIF_NUM
|
|
#network_bridge $DEV $NAME $VIF_NUM
|
|
|
|
# Check if vethX exists and if pethX exists and is up. Fail if not
|
|
if ! link_exists "$VDEV"
|
|
then
|
|
if link_exists "$PDEV"
|
|
then
|
|
# The device is already up.
|
|
return
|
|
else
|
|
# output error message
|
|
echo "
|
|
Link $VDEV is missing.
|
|
This may be because you have reached the limit of the number of interfaces
|
|
that the loopback driver supports. If the loopback driver is a module, you
|
|
may raise this limit by passing it as a parameter (nloopbacks=<N>); if the
|
|
driver is compiled statically into the kernel, then you may set the parameter
|
|
using loopback.nloopbacks=<N> on the domain 0 kernel command line.
|
|
" >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# Create the bridge
|
|
create_bridge $BRIDGE
|
|
|
|
# Find the corresponding ifcfg-eth-xxx file and source it
|
|
get_ifcfg_file
|
|
. /etc/sysconfig/network/ifcfg-${hwddev}
|
|
|
|
# Check if physical interface is bonded or not and in vethX exists
|
|
# Create bridge appropriately
|
|
if [ ! "$BONDING_MASTER" = "yes" ] && link_exists "$VDEV"
|
|
then
|
|
# Create bridge with nornal network interface (i.e. ethX)
|
|
create_normal_bridge start $DEV $VDEV $PDEV $BRIDGE $VIF0
|
|
elif [ "$BONDING_MASTER" = "yes" ]
|
|
then
|
|
# Create bridge with bonded network interface
|
|
create_bonded_bridge start $DEV $VDEV $PDEV $BRIDGE $VIF0
|
|
else
|
|
# Create old style bridge without $VDEV
|
|
transfer_addrs ${netdev} $BRIDGE
|
|
transfer_routes ${netdev} $BRIDGE
|
|
fi
|
|
|
|
if [ "${antispoof}" = "yes" ]
|
|
then
|
|
antispoofing
|
|
fi
|
|
|
|
echo ""
|
|
else
|
|
echo " Physical Interface $DEV is not up. Skipping $NAME"
|
|
fi
|
|
;;
|
|
stop)
|
|
# Check if bridge exists. Fail if not
|
|
if ! link_exists "$BRIDGE"; then
|
|
return
|
|
fi
|
|
|
|
echo ""
|
|
echo "============================================================"
|
|
echo "Removing Virtual Network: $NAME"
|
|
echo " of type: $TYPE"
|
|
echo "from- Physical Interface: $DEV"
|
|
echo " Virtual Interface: vif$NUMBER"
|
|
echo "============================================================"
|
|
echo ""
|
|
|
|
# Find the corresponding ifcfg-eth-xxx file and source it
|
|
if brctl show | grep "$BRIDGE" | grep -q "bond[0-9]"
|
|
then
|
|
hwddev=`brctl show | grep "$BRIDGE" | sed '/s.*bond\(.*\)/bond\1/g'`
|
|
netdev=${hwddev}
|
|
else
|
|
get_ifcfg_file
|
|
fi
|
|
. /etc/sysconfig/network/ifcfg-${hwddev}
|
|
|
|
# Check if physical interface is bonded or not and in pethX exists
|
|
# Remove bridge appropriately
|
|
if [ ! "$BONDING_MASTER" = "yes" ] && link_exists "$PDEV"
|
|
then
|
|
# Remove bridge with normal network interface (i.e. ethX)
|
|
create_normal_bridge stop $DEV $VDEV $PDEV $BRIDGE $VIF0
|
|
elif [ "$BONDING_MASTER" = "yes" ]
|
|
then
|
|
# Remove brisge with bonded network interface
|
|
create_bonded_bridge stop $DEV $VDEV $PDEV $BRIDGE $VIF0
|
|
else
|
|
# Remove old style bridge without $VDEV
|
|
if [ ${netdev} = $BRIDGE ]
|
|
then
|
|
find_bridged_netdev $BRIDGE
|
|
fi
|
|
ip link set dev ${vif0} down
|
|
transfer_routes $BRIDGE ${netdev}
|
|
ip link set $BRIDGE down
|
|
fi
|
|
|
|
# Remove the bridge
|
|
brctl delbr $BRIDGE
|
|
|
|
;;
|
|
status)
|
|
|
|
;;
|
|
*)
|
|
echo "The function create_bridged_networks requires the CMD_OPT variable"
|
|
echo "to be set to one of the following: start|stop|status"
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
create_local_networks() {
|
|
# Creates bridges attached to virtual devices in Dom0 and enables nat or routing
|
|
# on the bridges if specified.
|
|
#
|
|
# This fuction reads the start,stop,status parameter from the $CMD_OPT variable
|
|
# and responds respectively.
|
|
#
|
|
# Variables passed in in order:
|
|
# $NET_DEV $NET_TYPE $NET_NUMBER $NET_DEV_MAC $NET_DEV_IP $NET_DHCP_SRV
|
|
|
|
|
|
# Set local function variables
|
|
local DEV=$1
|
|
local TYPE=$2
|
|
local NUMBER=$3
|
|
case $TYPE in
|
|
hostonly)
|
|
local NAME=$HOSTONLY_NAME$NUMBER
|
|
;;
|
|
nat)
|
|
local NAME=$NAT_NAME$NUMBER
|
|
;;
|
|
route)
|
|
local NAME=$ROUTE_NAME$NUMBER
|
|
;;
|
|
esac
|
|
local MAC=$4
|
|
local IPADDR=$5
|
|
local DHCP_SRV=$6
|
|
local VIF=vif0.$VIF_COUNT
|
|
|
|
local NAT_GW_IP=`echo $IPADDR|cut -d "," -f 3|cut -d "/" -f 1`
|
|
local NAT_INTIF=$DEV
|
|
local ROUTE_INTIF=$DEV
|
|
|
|
case $CMD_OPT in
|
|
start)
|
|
if ! brctl show | grep -qw $DEV && /sbin/ip address show $DEV > /dev/null
|
|
then
|
|
#------------------------------------------------------------------
|
|
# Create the bridge
|
|
#------------------------------------------------------------------
|
|
echo ""
|
|
echo "============================================================"
|
|
echo "Configuring Virtual Network: $NAME"
|
|
echo " of type: $TYPE"
|
|
echo ""
|
|
echo " on- Virtual Interface: $VIF"
|
|
echo " Virtual Device: $DEV"
|
|
|
|
create_bridge $NAME > /dev/null 2>&1
|
|
setup_bridge_port $VIF > /dev/null 2>&1
|
|
add_to_bridge $NAME $VIF > /dev/null 2>&1
|
|
setup_host_interface $DEV $MAC $IPADDR > /dev/null 2>&1
|
|
|
|
#------------------------------------------------------------------
|
|
# Set up the bridge as a hostonly / NAT / Routed network
|
|
#------------------------------------------------------------------
|
|
case $TYPE in
|
|
NAT|nat) # Set up the bridge as NATed network
|
|
echo " Gateway: $NAT_GW_IP"
|
|
echo " External Interface: $NAT_EXTERNAL_INTERFACE"
|
|
;;
|
|
ROUTE|route) # Set up the bridge as Routed network
|
|
echo " Gateway: $NAT_GW_IP"
|
|
echo " External Interface: $NAT_EXTERNAL_INTERFACE"
|
|
iptables -t nat -A PREROUTING -i $ROUTE_INTIF -j ACCEPT
|
|
#iptables -t filter -A FORWARD -i $NAT_INTIF -j ACCEPT
|
|
#iptables -t filter -A FORWARD -i $NAT_INTIF -j ACCEPT
|
|
;;
|
|
HOSTONLY|hostonly) # Set up the bridge as hostonly network
|
|
if [ "$IP_FWD" = "on" ]
|
|
then
|
|
iptables -t nat -A PREROUTING -i $NAT_INTIF -j DROP
|
|
fi
|
|
;;
|
|
esac
|
|
echo "============================================================"
|
|
else
|
|
#------------------------------------------------------------------
|
|
# Skip this bridge
|
|
#------------------------------------------------------------------
|
|
echo " Virtual Interface $DEV is already attached to a bridge or it does not exist."
|
|
echo " Skipping $NAME"
|
|
fi
|
|
;;
|
|
stop)
|
|
#------------------------------------------------------------------
|
|
# Remove the bridge
|
|
#------------------------------------------------------------------
|
|
echo ""
|
|
echo "============================================================"
|
|
echo "Removing Virtual Network: $NAME"
|
|
echo " of type: $TYPE"
|
|
echo ""
|
|
echo " from- Virtual Interface: $VIF"
|
|
echo " Virtual Device: $DEV"
|
|
|
|
#------------------------------------------------------------------
|
|
# First remove the hostonly / NAT / Routed configuration
|
|
#------------------------------------------------------------------
|
|
case $TYPE in
|
|
NAT|nat)
|
|
|
|
;;
|
|
ROUTE|route)
|
|
# Clean out the bridge specific routing iptables rule
|
|
iptables -t nat -D PREROUTING -i $ROUTE_INTIF -j ACCEPT
|
|
#iptables -t filter -D FORWARD -i $DEV -j ACCEPT
|
|
#iptables -t filter -D FORWARD -i $NAT_INTIF -j ACCEPT
|
|
;;
|
|
HOSTONLY|hostonly)
|
|
# Clean out the bridge specific nat iptables rule
|
|
iptables -t nat -D PREROUTING -i $NAT_INTIF -j DROP
|
|
;;
|
|
esac
|
|
|
|
echo "============================================================"
|
|
|
|
#------------------------------------------------------------------
|
|
# Then unconfigure the veth
|
|
#------------------------------------------------------------------
|
|
setup_host_interface $DEV $MAC $IPADDR > /dev/null 2>&1
|
|
|
|
#------------------------------------------------------------------
|
|
# remove vif from the bridge
|
|
#------------------------------------------------------------------
|
|
brctl delif $NAME $VIF
|
|
|
|
#------------------------------------------------------------------
|
|
# unconfigure the vif
|
|
#------------------------------------------------------------------
|
|
ip link set $VIF down
|
|
ip link set $VIF addr fe:ff:ff:ff:ff:ff
|
|
ip link set $VIF multicast on
|
|
ip link set $VIF arp on
|
|
ip addr flush $VIF
|
|
|
|
#------------------------------------------------------------------
|
|
# and finaly unconfigure the bridge
|
|
#------------------------------------------------------------------
|
|
ip link set $NAME down
|
|
brctl delbr $NAME
|
|
;;
|
|
status)
|
|
#------------------------------------------------------------------
|
|
# Show the status of the bridge
|
|
#------------------------------------------------------------------
|
|
echo ""
|
|
echo "============================================================"
|
|
echo "Status of Virtual Network: $NAME"
|
|
echo " of type: $TYPE"
|
|
echo " on- Virtual Interface: $VIF"
|
|
echo " Virtual Device: $DEV"
|
|
echo "============================================================"
|
|
brctl show | grep -w "^$NAME"
|
|
echo ""
|
|
ip addr show $DEV
|
|
echo "============================================================"
|
|
;;
|
|
*)
|
|
echo "The function create_local_networks requires the CMD_OPT variable"
|
|
echo "to be set to one of the following: start|stop|status"
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
create_nohost_networks() {
|
|
# Creates bridges attached to an external interface but no devices in Dom0.
|
|
#
|
|
# This function reads the start,stop,status parameter from the $CMD_OPT
|
|
# variable and responds respectively.
|
|
#
|
|
# Variables passed in in order: $NET_DEV $NET_NUMBER
|
|
|
|
echo ""
|
|
echo "============================================================"
|
|
local DEV=$1
|
|
local PDEV=p$DEV
|
|
local MAC=`ip link show $DEV | grep 'link\/ether' | sed -e 's/.*ether \(..:..:..:..:..:..\).*/\1/'`
|
|
local NUMBER=$2
|
|
local NAME=$NOHOST_NAME$NUMBER
|
|
|
|
case $CMD_OPT in
|
|
start)
|
|
if ! brctl show | grep -qw "^$NAME"
|
|
then
|
|
echo ""
|
|
echo "============================================================"
|
|
echo "Configuring Virtual Network: $NAME"
|
|
echo " of type: $TYPE"
|
|
echo " on- Virtual Device: $DEV"
|
|
|
|
# create the bridge
|
|
create_bridge $NAME
|
|
|
|
# back up the interface's info (MAC, etc)
|
|
echo $MAC > $NETWORK_SAVE_PATH/$DEV-info
|
|
|
|
# configure the interface as a bridge port
|
|
setup_bridge_port $DEV
|
|
|
|
# rename the physical interface
|
|
ip link set $DEV name $PDEV
|
|
|
|
# add the interface to the bridge
|
|
add_to_bridge $NAME $PDEV
|
|
fi
|
|
;;
|
|
stop)
|
|
if brctl show | grep -qw "^$NAME"
|
|
then
|
|
echo "============================================================"
|
|
echo "Removing Virtual Network: $NAME"
|
|
echo " of type: $TYPE"
|
|
echo ""
|
|
|
|
# bring the bridge down
|
|
ip link set $NAME down
|
|
|
|
# remove the interface from the bridge
|
|
brctl delif $NAME $PDEV
|
|
|
|
# remove the bridge
|
|
brctl delbr $NAME
|
|
|
|
# bring the interface down
|
|
ip link set down $PDEV
|
|
|
|
# reset the interface back to normal
|
|
ip link set $PDEV arp on
|
|
ip link set $PDEV multicast on
|
|
|
|
# reset the interface back to its original name and MAC
|
|
ip link set $PDEV name $DEV
|
|
ip link set $DEV addr `cat $NETWORK_SAVE_PATH/$DEV-info`
|
|
rm -f `cat $NETWORK_SAVE_PATH/$DEV-info`
|
|
|
|
# bring the interface back up
|
|
ifup $DEV
|
|
fi
|
|
;;
|
|
status)
|
|
brctl show $NAME | grep -w "^$NAME"
|
|
;;
|
|
*)
|
|
echo "The function create_nohost_networks requires the CMD_OPT variable"
|
|
echo "to be set to one of the following: start|stop|status"
|
|
exit 1
|
|
;;
|
|
esac
|
|
echo "============================================================"
|
|
}
|
|
|
|
create_empty_networks() {
|
|
# Creates bridges attached to no devices in Dom0.
|
|
#
|
|
# This function reads the start,stop,status parameter from the $CMD_OPT
|
|
# variable and responds respectively.
|
|
#
|
|
# Variables passed in in order: $NET_NUMBER
|
|
|
|
echo ""
|
|
echo "============================================================"
|
|
local NUMBER=$1
|
|
local NAME=$EMPTY_NAME$NUMBER
|
|
|
|
case $CMD_OPT in
|
|
start)
|
|
if ! brctl show | grep -qw "^$NAME"
|
|
then
|
|
echo "Configuring Virtual Network: $NAME"
|
|
echo " of type: $TYPE"
|
|
create_bridge $NAME
|
|
fi
|
|
;;
|
|
stop)
|
|
if brctl show | grep -qw "^$NAME"
|
|
then
|
|
echo "Removing Virtual Network: $NAME"
|
|
echo " of type: $TYPE"
|
|
ip link set $NAME down
|
|
brctl delbr $NAME
|
|
fi
|
|
;;
|
|
status)
|
|
brctl show $NAME | grep -w "^$NAME"
|
|
;;
|
|
*)
|
|
echo "The function create_empty_networks requires the CMD_OPT variable"
|
|
echo "to be set to one of the following: start|stop|status"
|
|
exit 1
|
|
;;
|
|
esac
|
|
echo "============================================================"
|
|
}
|
|
|
|
|
|
|