xen-drbd

diff network-bridge-for-xen-drbd @ 52:21f21fa8f106

minifix
author root@linux10
date Fri Oct 10 18:43:08 2008 +0000 (2008-10-10)
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/network-bridge-for-xen-drbd	Fri Oct 10 18:43:08 2008 +0000
     1.3 @@ -0,0 +1,313 @@
     1.4 +#!/bin/bash
     1.5 +#============================================================================
     1.6 +# Default Xen network start/stop script.
     1.7 +# Xend calls a network script when it starts.
     1.8 +# The script name to use is defined in /etc/xen/xend-config.sxp
     1.9 +# in the network-script field.
    1.10 +#
    1.11 +# This script creates a bridge (default xenbr${vifnum}), adds a device
    1.12 +# (default eth${vifnum}) to it, copies the IP addresses from the device
    1.13 +# to the bridge and adjusts the routes accordingly.
    1.14 +#
    1.15 +# If all goes well, this should ensure that networking stays up.
    1.16 +# However, some configurations are upset by this, especially
    1.17 +# NFS roots. If the bridged setup does not meet your needs,
    1.18 +# configure a different script, for example using routing instead.
    1.19 +#
    1.20 +# Usage:
    1.21 +#
    1.22 +# network-bridge (start|stop|status) {VAR=VAL}*
    1.23 +#
    1.24 +# Vars:
    1.25 +#
    1.26 +# vifnum     Virtual device number to use (default 0). Numbers >=8
    1.27 +#            require the netback driver to have nloopbacks set to a
    1.28 +#            higher value than its default of 8.
    1.29 +# bridge     The bridge to use (default xenbr${vifnum}).
    1.30 +# netdev     The interface to add to the bridge (default eth${vifnum}).
    1.31 +# antispoof  Whether to use iptables to prevent spoofing (default no).
    1.32 +#
    1.33 +# Internal Vars:
    1.34 +# pdev="p${netdev}"
    1.35 +# vdev="veth${vifnum}"
    1.36 +# vif0="vif0.${vifnum}"
    1.37 +#
    1.38 +# start:
    1.39 +# Creates the bridge
    1.40 +# Copies the IP and MAC addresses from netdev to vdev
    1.41 +# Renames netdev to be pdev 
    1.42 +# Renames vdev to be netdev 
    1.43 +# Enslaves pdev, vdev to bridge
    1.44 +#
    1.45 +# stop:
    1.46 +# Removes netdev from the bridge
    1.47 +# Transfers addresses, routes from netdev to pdev
    1.48 +# Renames netdev to vdev
    1.49 +# Renames pdev to netdev 
    1.50 +# Deletes bridge
    1.51 +#
    1.52 +# status:
    1.53 +# Print addresses, interfaces, routes
    1.54 +#
    1.55 +#============================================================================
    1.56 +
    1.57 +
    1.58 +dir=$(dirname "$0")
    1.59 +. "$dir/xen-script-common.sh"
    1.60 +. "$dir/xen-network-common.sh"
    1.61 +
    1.62 +findCommand "$@"
    1.63 +evalVariables "$@"
    1.64 +
    1.65 +modprobe netloop > /dev/null 2>&1 || true
    1.66 +
    1.67 +vifnum=${vifnum:-$(ip route list | awk '/^default / { print $NF }' | sed 's/^[^0-9]*//')}
    1.68 +vifnum=${vifnum:-0}
    1.69 +bridge=${bridge:-xenbr${vifnum}}
    1.70 +netdev=${netdev:-eth${vifnum}}
    1.71 +antispoof=${antispoof:-no}
    1.72 +
    1.73 +pdev="p${netdev}"
    1.74 +vdev="veth${vifnum}"
    1.75 +vif0="vif0.${vifnum}"
    1.76 +
    1.77 +get_ip_info() {
    1.78 +    addr_pfx=`ip addr show dev $1 | egrep '^ *inet' | sed -e 's/ *inet //' -e 's/ .*//'`
    1.79 +    gateway=`ip route show dev $1 | fgrep default | sed 's/default via //'`
    1.80 +}
    1.81 +    
    1.82 +do_ifup() {
    1.83 +    if ! ifup $1 ; then
    1.84 +        if [ ${addr_pfx} ] ; then
    1.85 +            # use the info from get_ip_info()
    1.86 +            ip addr flush $1
    1.87 +            ip addr add ${addr_pfx} dev $1
    1.88 +            ip link set dev $1 up
    1.89 +            [ ${gateway} ] && ip route add default via ${gateway}
    1.90 +        fi
    1.91 +    fi
    1.92 +}
    1.93 +
    1.94 +# Usage: transfer_addrs src dst
    1.95 +# Copy all IP addresses (including aliases) from device $src to device $dst.
    1.96 +transfer_addrs () {
    1.97 +    local src=$1
    1.98 +    local dst=$2
    1.99 +    # Don't bother if $dst already has IP addresses.
   1.100 +    if ip addr show dev ${dst} | egrep -q '^ *inet ' ; then
   1.101 +        return
   1.102 +    fi
   1.103 +    # Address lines start with 'inet' and have the device in them.
   1.104 +    # Replace 'inet' with 'ip addr add' and change the device name $src
   1.105 +    # to 'dev $src'.
   1.106 +    ip addr show dev ${src} | egrep '^ *inet ' | sed -e "
   1.107 +s/inet/ip addr add/
   1.108 +s@\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+/[0-9]\+\)@\1@
   1.109 +s/${src}/dev ${dst}/
   1.110 +" | sh -e
   1.111 +    # Remove automatic routes on destination device
   1.112 +    ip route list | sed -ne "
   1.113 +/dev ${dst}\( \|$\)/ {
   1.114 +  s/^/ip route del /
   1.115 +  p
   1.116 +}" | sh -e
   1.117 +}
   1.118 +
   1.119 +# Usage: transfer_routes src dst
   1.120 +# Get all IP routes to device $src, delete them, and
   1.121 +# add the same routes to device $dst.
   1.122 +# The original routes have to be deleted, otherwise adding them
   1.123 +# for $dst fails (duplicate routes).
   1.124 +transfer_routes () {
   1.125 +    local src=$1
   1.126 +    local dst=$2
   1.127 +    # List all routes and grep the ones with $src in.
   1.128 +    # Stick 'ip route del' on the front to delete.
   1.129 +    # Change $src to $dst and use 'ip route add' to add.
   1.130 +    ip route list | sed -ne "
   1.131 +/dev ${src}\( \|$\)/ {
   1.132 +  h
   1.133 +  s/^/ip route del /
   1.134 +  P
   1.135 +  g
   1.136 +  s/${src}/${dst}/
   1.137 +  s/^/ip route add /
   1.138 +  P
   1.139 +  d
   1.140 +}" | sh -e
   1.141 +}
   1.142 +
   1.143 +
   1.144 +##
   1.145 +# link_exists interface
   1.146 +#
   1.147 +# Returns 0 if the interface named exists (whether up or down), 1 otherwise.
   1.148 +#
   1.149 +link_exists()
   1.150 +{
   1.151 +    if ip link show "$1" >/dev/null 2>/dev/null
   1.152 +    then
   1.153 +        return 0
   1.154 +    else
   1.155 +        return 1
   1.156 +    fi
   1.157 +}
   1.158 +
   1.159 +# Set the default forwarding policy for $dev to drop.
   1.160 +# Allow forwarding to the bridge.
   1.161 +antispoofing () {
   1.162 +    iptables -P FORWARD DROP
   1.163 +    iptables -F FORWARD
   1.164 +    iptables -A FORWARD -m physdev --physdev-in ${pdev} -j ACCEPT
   1.165 +    iptables -A FORWARD -m physdev --physdev-in ${vif0} -j ACCEPT
   1.166 +}
   1.167 +
   1.168 +# Usage: show_status dev bridge
   1.169 +# Print ifconfig and routes.
   1.170 +show_status () {
   1.171 +    local dev=$1
   1.172 +    local bridge=$2
   1.173 +    
   1.174 +    echo '============================================================'
   1.175 +    ip addr show ${dev}
   1.176 +    ip addr show ${bridge}
   1.177 +    echo ' '
   1.178 +    brctl show ${bridge}
   1.179 +    echo ' '
   1.180 +    ip route list
   1.181 +    echo ' '
   1.182 +    route -n
   1.183 +    echo '============================================================'
   1.184 +}
   1.185 +
   1.186 +op_start () {
   1.187 +    if [ "${bridge}" = "null" ] ; then
   1.188 +	return
   1.189 +    fi
   1.190 +
   1.191 +    if ! link_exists "$vdev"; then
   1.192 +        if link_exists "$pdev"; then
   1.193 +            # The device is already up.
   1.194 +            return
   1.195 +        else
   1.196 +            echo "
   1.197 +Link $vdev is missing.
   1.198 +This may be because you have reached the limit of the number of interfaces
   1.199 +that the loopback driver supports.  If the loopback driver is a module, you
   1.200 +may raise this limit by passing it as a parameter (nloopbacks=<N>); if the
   1.201 +driver is compiled statically into the kernel, then you may set the parameter
   1.202 +using loopback.nloopbacks=<N> on the domain 0 kernel command line.
   1.203 +" >&2
   1.204 +            exit 1
   1.205 +        fi
   1.206 +    fi
   1.207 +
   1.208 +    create_bridge ${bridge}
   1.209 +
   1.210 +    if link_exists "$vdev"; then
   1.211 +	mac=`ip link show ${netdev} | grep 'link\/ether' | sed -e 's/.*ether \(..:..:..:..:..:..\).*/\1/'`
   1.212 +	preiftransfer ${netdev}
   1.213 +	transfer_addrs ${netdev} ${vdev}
   1.214 +	if ! ifdown ${netdev}; then
   1.215 +	    # If ifdown fails, remember the IP details.
   1.216 +	    get_ip_info ${netdev}
   1.217 +	    ip link set ${netdev} down
   1.218 +	    ip addr flush ${netdev}
   1.219 +	fi
   1.220 +	ip link set ${netdev} name ${pdev}
   1.221 +	ip link set ${vdev} name ${netdev}
   1.222 +
   1.223 +	setup_bridge_port ${pdev}
   1.224 +	setup_bridge_port ${vif0}
   1.225 +	ip link set ${netdev} addr ${mac} arp on
   1.226 +
   1.227 +	ip link set ${bridge} up
   1.228 +	add_to_bridge  ${bridge} ${vif0}
   1.229 +	add_to_bridge2 ${bridge} ${pdev}
   1.230 +	do_ifup ${netdev}
   1.231 +    else
   1.232 +	# old style without ${vdev}
   1.233 +	transfer_addrs  ${netdev} ${bridge}
   1.234 +	transfer_routes ${netdev} ${bridge}
   1.235 +    fi
   1.236 +
   1.237 +    if [ ${antispoof} = 'yes' ] ; then
   1.238 +	antispoofing
   1.239 +    fi
   1.240 +}
   1.241 +
   1.242 +op_stop () {
   1.243 +    if [ "${bridge}" = "null" ]; then
   1.244 +	return
   1.245 +    fi
   1.246 +    if ! link_exists "$bridge"; then
   1.247 +	return
   1.248 +    fi
   1.249 +
   1.250 +    if link_exists "$pdev"; then
   1.251 +	ip link set dev ${vif0} down
   1.252 +	mac=`ip link show ${netdev} | grep 'link\/ether' | sed -e 's/.*ether \(..:..:..:..:..:..\).*/\1/'`
   1.253 +	transfer_addrs ${netdev} ${pdev}
   1.254 +	if ! ifdown ${netdev}; then
   1.255 +	    get_ip_info ${netdev}
   1.256 +	fi
   1.257 +	ip link set ${netdev} down arp off
   1.258 +	ip link set ${netdev} addr fe:ff:ff:ff:ff:ff
   1.259 +	ip link set ${pdev} down
   1.260 +	ip addr flush ${netdev}
   1.261 +	ip link set ${pdev} addr ${mac} arp on
   1.262 +
   1.263 +	brctl delif ${bridge} ${pdev}
   1.264 +	brctl delif ${bridge} ${vif0}
   1.265 +	ip link set ${bridge} down
   1.266 +
   1.267 +	ip link set ${netdev} name ${vdev}
   1.268 +	ip link set ${pdev} name ${netdev}
   1.269 +	do_ifup ${netdev}
   1.270 +    else
   1.271 +	transfer_routes ${bridge} ${netdev}
   1.272 +	ip link set ${bridge} down
   1.273 +    fi
   1.274 +    brctl delbr ${bridge}
   1.275 +}
   1.276 +
   1.277 +# adds $dev to $bridge but waits for $dev to be in running state first
   1.278 +add_to_bridge2() {
   1.279 +    local bridge=$1
   1.280 +    local dev=$2
   1.281 +    local maxtries=10
   1.282 +
   1.283 +    echo -n "Waiting for ${dev} to negotiate link."
   1.284 +    ip link set ${dev} up
   1.285 +    for i in `seq ${maxtries}` ; do
   1.286 +	if ifconfig ${dev} | grep -q RUNNING ; then
   1.287 +	    break
   1.288 +	else
   1.289 +	    echo -n '.'
   1.290 +	    sleep 1
   1.291 +	fi
   1.292 +    done
   1.293 +
   1.294 +    if [ ${i} -eq ${maxtries} ] ; then echo '(link isnt in running state)' ; fi
   1.295 +
   1.296 +    add_to_bridge ${bridge} ${dev}
   1.297 +}
   1.298 +
   1.299 +case "$command" in
   1.300 +    start)
   1.301 +	op_start
   1.302 +	;;
   1.303 +    
   1.304 +    stop)
   1.305 +	op_stop
   1.306 +	;;
   1.307 +
   1.308 +    status)
   1.309 +	show_status ${netdev} ${bridge}
   1.310 +	;;
   1.311 +
   1.312 +    *)
   1.313 +	echo "Unknown command: $command" >&2
   1.314 +	echo 'Valid commands are: start, stop, status' >&2
   1.315 +	exit 1
   1.316 +esac