aboutsummaryrefslogtreecommitdiffstats
path: root/tools/examples/network-bridge
diff options
context:
space:
mode:
Diffstat (limited to 'tools/examples/network-bridge')
-rwxr-xr-xtools/examples/network-bridge260
1 files changed, 260 insertions, 0 deletions
diff --git a/tools/examples/network-bridge b/tools/examples/network-bridge
new file mode 100755
index 0000000000..d9fc2d855f
--- /dev/null
+++ b/tools/examples/network-bridge
@@ -0,0 +1,260 @@
+#!/bin/sh -x
+#============================================================================
+# 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 creates a bridge (default xen-br0), adds a device
+# (default eth0) to it, copies the IP addresses from the device
+# to the bridge and adjusts the routes accordingly.
+#
+# 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 (default xen-br0).
+# netdev The interface to add to the bridge (default eth0).
+# antispoof Whether to use iptables to prevent spoofing (default yes).
+#
+# start:
+# Creates the bridge and enslaves netdev to it.
+# Copies the IP addresses from netdev to the bridge.
+# Deletes the routes to netdev and adds them on bridge.
+#
+# stop:
+# Removes netdev from the bridge.
+# Deletes the routes to bridge and adds them to netdev.
+#
+# status:
+# Print ifconfig for netdev and bridge.
+# Print routes.
+#
+#============================================================================
+
+# Exit if anything goes wrong.
+set -e
+
+# 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" >&2
+
+# Usage: transfer_addrs src dst
+# Copy all IP addresses (including aliases) from device $src to device $dst.
+transfer_addrs () {
+ 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 destionation device
+ ip route list | sed -ne "
+/dev ${dst}\( \|$\)/ {
+ s/^/ip route del /
+ p
+}" | sh -e
+}
+
+# Usage: del_addrs src
+del_addrs () {
+ local src=$1
+ ip addr show dev ${src} | egrep '^ *inet ' | sed -e "
+s/inet/ip addr del/
+s@\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\)/[0-9]\+@\1@
+s/${src}/dev ${src}/
+" | sh -e
+}
+
+# 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).
+transfer_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
+}
+
+# Usage: create_bridge bridge
+create_bridge () {
+ local bridge=$1
+
+ # Don't create the bridge if it already exists.
+ if ! brctl show | grep -q ${bridge} ; then
+ brctl addbr ${bridge}
+ brctl stp ${bridge} off
+ brctl setfd ${bridge} 0
+ fi
+ ifconfig ${bridge} up
+}
+
+# Usage: add_to_bridge bridge dev
+add_to_bridge () {
+ local bridge=$1
+ local dev=$2
+ # Don't add $dev to $bridge if it's already on a bridge.
+ if ! brctl show | grep -q ${dev} ; then
+ brctl addif ${bridge} ${dev}
+ fi
+}
+
+# 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
+ iptables -A FORWARD -m physdev --physdev-in ${dev} -j ACCEPT
+}
+
+# Usage: show_status dev bridge
+# Print ifconfig and routes.
+show_status () {
+ local dev=$1
+ local bridge=$2
+
+ echo '============================================================'
+ ifconfig ${dev}
+ ifconfig ${bridge}
+ echo ' '
+ ip route list
+ echo ' '
+ route -n
+ echo '============================================================'
+}
+
+op_start () {
+ if [ "${bridge}" == "null" ] ; then
+ return
+ fi
+
+ create_bridge ${bridge}
+
+ if ifconfig 2>/dev/null | grep -q veth0 ; then
+ return
+ fi
+
+ if ifconfig veth0 2>/dev/null | grep -q veth0 ; then
+ mac=`ifconfig ${netdev} | grep HWadd | sed -e 's/.*\(..:..:..:..:..:..\).*/\1/'`
+ if ! ifdown ${netdev} ; then
+ # if ifup didn't work, see if we have an ip= on cmd line
+ if egrep 'ip=[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:' /proc/cmdline ;
+ then
+ kip=`sed -e 's!.*ip=\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\):.*!\1!' /proc/cmdline`
+ kmask=`sed -e 's!.*ip=[^:]*:[^:]*:[^:]*:\([^:]*\):.*!\1!' /proc/cmdline`
+ kgate=`sed -e 's!.*ip=[^:]*:[^:]*:\([^:]*\):.*!\1!' /proc/cmdline`
+ ifconfig ${netdev} 0.0.0.0 down
+ fi
+ fi
+ ip link set ${netdev} name p${netdev}
+ ip link set veth0 name eth0
+ ifconfig p${netdev} -arp down
+ ifconfig p${netdev} hw ether fe:ff:ff:ff:ff:ff
+ ifconfig ${netdev} hw ether ${mac}
+ add_to_bridge ${bridge} vif0.0
+ add_to_bridge ${bridge} p${netdev}
+ ip link set vif0.0 up
+ ip link set p${netdev} up
+ if ! ifup ${netdev} ; then
+ if [ ${kip} ] ; then
+ # use the addresses we grocked from /proc/cmdline
+ ifconfig ${netdev} ${kip}
+ [ ${kmask} ] && ifconfig ${netdev} netmask ${kmask}
+ ifconfig ${netdev} up
+ [ ${kgate} ] && ip route add default via ${kgate}
+ fi
+ fi
+ else
+ # old style without veth0
+ transfer_addrs ${netdev} ${bridge}
+ transfer_routes ${netdev} ${bridge}
+ fi
+
+ if [ ${antispoof} == 'yes' ] ; then
+ antispoofing ${netdev} ${bridge}
+ fi
+}
+
+op_stop () {
+ if [ "${bridge}" == "null" ] ; then
+ return
+ fi
+
+ brctl delif ${bridge} ${netdev}
+
+ if ifconfig veth0 2>/dev/null | grep -q veth0 ; then
+ brctl delif ${bridge} vif0.0
+ ifconfig vif0.0 down
+ mac=`ifconfig veth0 | grep HWadd | sed -e 's/.*\(..:..:..:..:..:..\).*/\1/'`
+ ifconfig ${netdev} down
+ ifconfig ${netdev} hw ether ${mac}
+ ifconfig ${netdev} arp up
+ transfer_addrs veth0 ${netdev}
+ transfer_routes veth0 ${netdev}
+ del_addrs veth0
+ ifconfig veth0 -arp down
+ ifconfig veth0 hw ether 00:00:00:00:00:00
+ else
+ transfer_routes ${bridge} ${netdev}
+ fi
+}
+
+case ${OP} in
+ start)
+ op_start
+ ;;
+
+ stop)
+ op_stop
+ ;;
+
+ status)
+ show_status ${netdev} ${bridge}
+ ;;
+
+ *)
+ echo 'Unknown command: ' ${OP} >&2
+ echo 'Valid commands are: start, stop, status' >&2
+ exit 1
+esac