Hello all,
This is a custom network script I have been working on, mainly
for a SuSE 9.3 box, but I am hoping other people may find it
useful.
It is based on the existing network script in /etc/xen/scripts/ .
The existing script, by default, uses eth0 and xen-br0 for the
device and bridge respectively.
The custom script just takes one parameter, say eth0. It move
eth0 to one side by renaming it to eth0slv (eth0 slave) . Then
it create a bridge with the name eth0. Thus eth0 is magicallly
changed from an oridinary network device to a bridge.
This idea is shamelessly stolen from the /usr/lib/YaST2/bin/start-uml .
(I used the names eth0 / eth0slv . This might have been a mistake.
The start-uml script used eth0 / hweth0 . )
Doing things this way means that your firewall and routing settings
work both before and after the script is run. The network devices
continue to get configured with the info in /etc/sysconfig/network/
as usual.
To use it, you need to edit /etc/xen/xend-config.sxp . Set the
variable network-script to point to this script. Set the
variable vif-bridge to be the name of an existing network device
(probably eth0).
The script is a still a bit rough. I haven't finished commenting it.
There is still debugging stuff left in place. Feedback, both good
and bad, is welcomed.
#!/bin/sh
#============================================================================
# Default Xen network start/stop script.
# Xend calls a network script when it starts.
# The script name to use is defined in /etc/xen/xend-config.sxp
# in the network-script field.
#
# This script replaces a network device with a bridge by renaming
# the network device and creating a new bridge with the old name
# of the renamed device. The renamed device is enslaved to the
# bridge.
#
# The general idea is that names of devices given in Firewall and
# routing rules can remain the same before/after the script is
# run.
#
# If all goes well, this should ensure that networking stays up.
# However, some configurations are upset by this, especially
# NFS roots. If the bridged setup does not meet your needs,
# configure a different script, for example using routing instead.
#
# Usage:
#
# network (start|stop|status) {VAR=VAL}*
#
# Vars:
#
# bridge The bridge to use. (defaults to xen-br0: this proably isn't
# what you want. Remember to edit variable vif-bridge in
# file /etc/xen/xend-config.sxp. )
# netdev (now unused)
# antispoof Whether to use iptables to prevent spoofing (default yes).
#
# start:
# Renames the network device ${bridge} as ${bridge}slv
# Creates a new bridge device named ${bridge} that takes
# the place of the renamed device.
# Enslaves the the renamed network device to the new bridge device.
# Deletes the routing information for the network device and
# adds new routing information for the new bridge device using ifup
#
# stop:
# Removes netdev from the bridge.
# Deletes the routes to bridge and adds them to netdev.
#
# status:
# Print ifconfig for ${bridge}and ${bridge}slv.
# Print routes.
#
#============================================================================
# Exit if anything goes wrong.
#set -e
#DEBUG=""
#DEBUG="echo"
BRCTL="$DEBUG brctl"
IFUP="$DEBUG ifup"
IFDOWN="$DEBUG ifdown"
IP="$DEBUG ip"
IPTABLES="$DEBUG iptables"
#PATH="/sbin:/usr/sbin:$PATH"
# debugging sleep to fix posible races?
SLEEP="true "
#SLEEP="sleep "
# First arg is the operation.
OP=$1
shift
# Pull variables in args in to environment.
for arg ; do export "${arg}" ; done
bridge=${bridge:-xen-br0}
netdev=${netdev:-eth0}
antispoof=${antispoof:-yes}
echo "# network $OP bridge=$bridge netdev=$netdev antispoof=$antispoof"
# takes 1 arg, the name of a network device
# exit status of 0 or 1
is_netdev() {
local netdev=$1
[ $# == 1 ] && ifconfig $netdev >/dev/null 2>&1 || false
}
# takes 1 arg, the name of a network device
# exit status of 0 or 1
is_bridge() {
local netdev=$1
[ $# == 1 ] && brctl showmacs $netdev >/dev/null 2>&1 || false
}
# Usage: create_bridge bridge
# Create bridge $bridge and set bridge parameters.
# Does not add slave devices.
# Does not assign an IP address.
create_bridge() {
local netdev=$1
if [ $# != 1 ] ; then
false
return
fi
# Don't create the bridge if it already exists.
echo create_bridge $netdev
if ! is_netdev ${netdev} && ! is_bridge ${netdev} ; then
$BRCTL addbr ${netdev}
$BRCTL stp ${netdev} off
$BRCTL setfd ${netdev} 0
fi
}
# Return the MAC address of the network device
# given as an argument.
get_mac_addr() {
local netdev
local ret
if [ $# != 1 ] ; then
false
return
fi
netdev=$1
ip link show $netdev \
| grep -e 'link/ether' \
| sed -e 's#^[ ]*link/ether[ ]\(\([0-9a-f]\+:\)\+[0-9a-f]\+\).*#\1#'
return
}
# Usage: antispoofing dev bridge
# Set the default forwarding policy for $dev to drop.
# Allow forwarding to the bridge.
antispoofing() {
local dev=$1
local bridge=$2
$IPTABLES -P FORWARD DROP
# XXX . OUCH! This looks horribly permissive.
# I am not sure that firewall rules belong here.
$IPTABLES -A FORWARD -m physdev --physdev-in ${dev} -j ACCEPT
}
#Usage: show_status dev bridge
#Print ifconfig and routes.
show_status() {
local bridge=$1
echo '============================================================'
ifconfig ${bridge}
ifconfig ${bridge}slv
echo ' '
ip route list
echo ' '
route -n
echo '============================================================'
}
# start \ ${bridge}
# \ is_br is_dev missing
# ${bridge}slv \
# +-------+-------+-------+
# is_br | (1) | (3) | (1) |
# +-------+-------+-------+
# is_dev | (2) | (1) | (4) |
# +-------+-------+-------+
# missing | (1) | (5) | (1) |
# +-------+-------+-------+
# (1) Error: bail out leaving things as is.
# (2) Do nothing: bridge already started
# (3) create bridge called ${bridge}slv (if it doesn't already exist)
# ifdown ${bridge}
# rename ${bridge} -> ${bridge}tmp
# rename ${bridge}slv -> ${bridge}
# rename ${bridge}tmp -> ${bridge}slv
# enslave ${bridge}slv to ${bridge} (and make sure slave it is up.)
# ifup ${bridge}
# (4)
op_start () {
local real_mac_addr
if [ "${bridge}" == "null" ] ; then
return
fi
if is_bridge ${bridge}slv ; then
# row 1 in table above
if is_bridge ${bridge} || ! is_netdev ${bridge} ; then
# (1)
echo 'case #1'
# bail out with error
false
return
else
#(3)
echo '# case #3'
real_mac_addr="eth-id-$(get_mac_addr ${bridge})"
$IFDOWN $real_mac_addr $bridge
$IP link set ${bridge}slv down
$IP link set ${bridge}slv name ${bridge}tmp
$SLEEP 1
$IP link set ${bridge} name ${bridge}slv
$SLEEP 1
$IP link set ${bridge}tmp name ${bridge}
$SLEEP 1
$BRCTL addif ${bridge} ${bridge}slv
$SLEEP 1
# Use the mac addr of the enslaved device to find
# configuration for the bridge.
$IFUP $real_mac_addr ${bridge}
$IP link set ${bridge}slv up
return
fi
elif is_netdev ${bridge}slv ; then
# row 2 in table above
if is_bridge ${bridge} ; then
# (2)
echo '# case #2'
# nothing to do, return success
true
return
elif is_netdev ${bridge} ; then
# (1)
# bailout with error
false
return
else
# (4)
echo '# case #4'
real_mac_addr="eth-id-$(get_mac_addr ${bridge}slv)"
# create a bridge named ${bridge} and enslave
# ${bridge}slv to it.
# Make sure both interfaces are up.
create_bridge ${bridge}
$BRCTL addif ${bridge} ${bridge}slv
$IP link set ${bridge}slv up
$SLEEP 1
# Use the mac addr of the enslaved device to find
# configuration for the bridge.
$IFUP $real_mac_addr ${bridge}
return
fi
else
# row 3 in table above
if is_bridge ${bridge} ; then
# (1)
# bail out with error
false
return
elif is_netdev ${bridge} ; then
# (5)
echo '# case #5'
real_mac_addr="eth-id-$(get_mac_addr ${bridge})"
$IFDOWN $real_mac_addr $bridge
$IP link set ${bridge} name ${bridge}slv
$BRCTL addbr ${bridge}
$BRCTL addif ${bridge} ${bridge}slv
$SLEEP 1
# Use the mac addr of the enslaved device to find
# configuration for the bridge.
$IFUP $real_mac_addr ${bridge}
$IP link set ${bridge}slv up
return
else
# (1)
# bail out with error
false
return
fi
fi
# Create the bridge and give it the interface IP addresses.
# Move the interface routes onto the bridge.
#create_bridge ${bridge}
# Don't add $dev to $bridge if it's already on a bridge.
#if ! brctl show | grep -q ${netdev} ; then
# brctl addif ${bridge} ${netdev}
#fi
#if [ ${antispoof} == 'yes' ] ; then
# antispoofing ${bridge}slv ${bridge}
#fi
}
op_stop () {
if [ "${bridge}" == "null" ] ; then
return
fi
# Remove the interface from the bridge.
# Move the routes back to the interface.
if is_netdev ${bridge} && is_bridge ${bridge} ; then
$IFDOWN ${bridge}
$IP link set ${bridge}slv down
$BRCTL delif ${bridge} ${bridge}slv
$IP link set ${bridge} name ${bridge}tmp
$SLEEP 1
$IP link set ${bridge}slv name ${bridge}
$SLEEP 1
$IP link set ${bridge}tmp name ${bridge}slv
$SLEEP 1
$IFUP "eth-id-$(get_mac_addr ${bridge})" ${bridge}
return
fi
# It's not our place to be enabling forwarding...
}
case ${OP} in
start)
op_start
;;
stop)
op_stop
;;
status)
show_status ${bridge}
;;
*)
echo 'Unknown command: ' ${OP}
echo 'Valid commands are: start, stop, status'
exit 1
esac
_______________________________________________
Xen-users mailing list
Xen-users@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-users
|