xen-drbd
diff network-bridge-for-xen-drbd @ 53:748e00890579
transition to xen 3.2.1
author | root@linux10 |
---|---|
date | Fri Oct 10 20:35:46 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 20:35:46 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