xen-drbd

annotate network-bridge-for-xen-drbd @ 51:d3198c10cc10

minifix
author root@linux10
date Fri Oct 10 18:35:48 2008 +0000 (2008-10-10)
parents
children
rev   line source
root@51 1 #!/bin/bash
root@51 2 #============================================================================
root@51 3 # Default Xen network start/stop script.
root@51 4 # Xend calls a network script when it starts.
root@51 5 # The script name to use is defined in /etc/xen/xend-config.sxp
root@51 6 # in the network-script field.
root@51 7 #
root@51 8 # This script creates a bridge (default xenbr${vifnum}), adds a device
root@51 9 # (default eth${vifnum}) to it, copies the IP addresses from the device
root@51 10 # to the bridge and adjusts the routes accordingly.
root@51 11 #
root@51 12 # If all goes well, this should ensure that networking stays up.
root@51 13 # However, some configurations are upset by this, especially
root@51 14 # NFS roots. If the bridged setup does not meet your needs,
root@51 15 # configure a different script, for example using routing instead.
root@51 16 #
root@51 17 # Usage:
root@51 18 #
root@51 19 # network-bridge (start|stop|status) {VAR=VAL}*
root@51 20 #
root@51 21 # Vars:
root@51 22 #
root@51 23 # vifnum Virtual device number to use (default 0). Numbers >=8
root@51 24 # require the netback driver to have nloopbacks set to a
root@51 25 # higher value than its default of 8.
root@51 26 # bridge The bridge to use (default xenbr${vifnum}).
root@51 27 # netdev The interface to add to the bridge (default eth${vifnum}).
root@51 28 # antispoof Whether to use iptables to prevent spoofing (default no).
root@51 29 #
root@51 30 # Internal Vars:
root@51 31 # pdev="p${netdev}"
root@51 32 # vdev="veth${vifnum}"
root@51 33 # vif0="vif0.${vifnum}"
root@51 34 #
root@51 35 # start:
root@51 36 # Creates the bridge
root@51 37 # Copies the IP and MAC addresses from netdev to vdev
root@51 38 # Renames netdev to be pdev
root@51 39 # Renames vdev to be netdev
root@51 40 # Enslaves pdev, vdev to bridge
root@51 41 #
root@51 42 # stop:
root@51 43 # Removes netdev from the bridge
root@51 44 # Transfers addresses, routes from netdev to pdev
root@51 45 # Renames netdev to vdev
root@51 46 # Renames pdev to netdev
root@51 47 # Deletes bridge
root@51 48 #
root@51 49 # status:
root@51 50 # Print addresses, interfaces, routes
root@51 51 #
root@51 52 #============================================================================
root@51 53
root@51 54
root@51 55 dir=$(dirname "$0")
root@51 56 . "$dir/xen-script-common.sh"
root@51 57 . "$dir/xen-network-common.sh"
root@51 58
root@51 59 findCommand "$@"
root@51 60 evalVariables "$@"
root@51 61
root@51 62 modprobe netloop > /dev/null 2>&1 || true
root@51 63
root@51 64 vifnum=${vifnum:-$(ip route list | awk '/^default / { print $NF }' | sed 's/^[^0-9]*//')}
root@51 65 vifnum=${vifnum:-0}
root@51 66 bridge=${bridge:-xenbr${vifnum}}
root@51 67 netdev=${netdev:-eth${vifnum}}
root@51 68 antispoof=${antispoof:-no}
root@51 69
root@51 70 pdev="p${netdev}"
root@51 71 vdev="veth${vifnum}"
root@51 72 vif0="vif0.${vifnum}"
root@51 73
root@51 74 get_ip_info() {
root@51 75 addr_pfx=`ip addr show dev $1 | egrep '^ *inet' | sed -e 's/ *inet //' -e 's/ .*//'`
root@51 76 gateway=`ip route show dev $1 | fgrep default | sed 's/default via //'`
root@51 77 }
root@51 78
root@51 79 do_ifup() {
root@51 80 if ! ifup $1 ; then
root@51 81 if [ ${addr_pfx} ] ; then
root@51 82 # use the info from get_ip_info()
root@51 83 ip addr flush $1
root@51 84 ip addr add ${addr_pfx} dev $1
root@51 85 ip link set dev $1 up
root@51 86 [ ${gateway} ] && ip route add default via ${gateway}
root@51 87 fi
root@51 88 fi
root@51 89 }
root@51 90
root@51 91 # Usage: transfer_addrs src dst
root@51 92 # Copy all IP addresses (including aliases) from device $src to device $dst.
root@51 93 transfer_addrs () {
root@51 94 local src=$1
root@51 95 local dst=$2
root@51 96 # Don't bother if $dst already has IP addresses.
root@51 97 if ip addr show dev ${dst} | egrep -q '^ *inet ' ; then
root@51 98 return
root@51 99 fi
root@51 100 # Address lines start with 'inet' and have the device in them.
root@51 101 # Replace 'inet' with 'ip addr add' and change the device name $src
root@51 102 # to 'dev $src'.
root@51 103 ip addr show dev ${src} | egrep '^ *inet ' | sed -e "
root@51 104 s/inet/ip addr add/
root@51 105 s@\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+/[0-9]\+\)@\1@
root@51 106 s/${src}/dev ${dst}/
root@51 107 " | sh -e
root@51 108 # Remove automatic routes on destination device
root@51 109 ip route list | sed -ne "
root@51 110 /dev ${dst}\( \|$\)/ {
root@51 111 s/^/ip route del /
root@51 112 p
root@51 113 }" | sh -e
root@51 114 }
root@51 115
root@51 116 # Usage: transfer_routes src dst
root@51 117 # Get all IP routes to device $src, delete them, and
root@51 118 # add the same routes to device $dst.
root@51 119 # The original routes have to be deleted, otherwise adding them
root@51 120 # for $dst fails (duplicate routes).
root@51 121 transfer_routes () {
root@51 122 local src=$1
root@51 123 local dst=$2
root@51 124 # List all routes and grep the ones with $src in.
root@51 125 # Stick 'ip route del' on the front to delete.
root@51 126 # Change $src to $dst and use 'ip route add' to add.
root@51 127 ip route list | sed -ne "
root@51 128 /dev ${src}\( \|$\)/ {
root@51 129 h
root@51 130 s/^/ip route del /
root@51 131 P
root@51 132 g
root@51 133 s/${src}/${dst}/
root@51 134 s/^/ip route add /
root@51 135 P
root@51 136 d
root@51 137 }" | sh -e
root@51 138 }
root@51 139
root@51 140
root@51 141 ##
root@51 142 # link_exists interface
root@51 143 #
root@51 144 # Returns 0 if the interface named exists (whether up or down), 1 otherwise.
root@51 145 #
root@51 146 link_exists()
root@51 147 {
root@51 148 if ip link show "$1" >/dev/null 2>/dev/null
root@51 149 then
root@51 150 return 0
root@51 151 else
root@51 152 return 1
root@51 153 fi
root@51 154 }
root@51 155
root@51 156 # Set the default forwarding policy for $dev to drop.
root@51 157 # Allow forwarding to the bridge.
root@51 158 antispoofing () {
root@51 159 iptables -P FORWARD DROP
root@51 160 iptables -F FORWARD
root@51 161 iptables -A FORWARD -m physdev --physdev-in ${pdev} -j ACCEPT
root@51 162 iptables -A FORWARD -m physdev --physdev-in ${vif0} -j ACCEPT
root@51 163 }
root@51 164
root@51 165 # Usage: show_status dev bridge
root@51 166 # Print ifconfig and routes.
root@51 167 show_status () {
root@51 168 local dev=$1
root@51 169 local bridge=$2
root@51 170
root@51 171 echo '============================================================'
root@51 172 ip addr show ${dev}
root@51 173 ip addr show ${bridge}
root@51 174 echo ' '
root@51 175 brctl show ${bridge}
root@51 176 echo ' '
root@51 177 ip route list
root@51 178 echo ' '
root@51 179 route -n
root@51 180 echo '============================================================'
root@51 181 }
root@51 182
root@51 183 op_start () {
root@51 184 if [ "${bridge}" = "null" ] ; then
root@51 185 return
root@51 186 fi
root@51 187
root@51 188 if ! link_exists "$vdev"; then
root@51 189 if link_exists "$pdev"; then
root@51 190 # The device is already up.
root@51 191 return
root@51 192 else
root@51 193 echo "
root@51 194 Link $vdev is missing.
root@51 195 This may be because you have reached the limit of the number of interfaces
root@51 196 that the loopback driver supports. If the loopback driver is a module, you
root@51 197 may raise this limit by passing it as a parameter (nloopbacks=<N>); if the
root@51 198 driver is compiled statically into the kernel, then you may set the parameter
root@51 199 using loopback.nloopbacks=<N> on the domain 0 kernel command line.
root@51 200 " >&2
root@51 201 exit 1
root@51 202 fi
root@51 203 fi
root@51 204
root@51 205 create_bridge ${bridge}
root@51 206
root@51 207 if link_exists "$vdev"; then
root@51 208 mac=`ip link show ${netdev} | grep 'link\/ether' | sed -e 's/.*ether \(..:..:..:..:..:..\).*/\1/'`
root@51 209 preiftransfer ${netdev}
root@51 210 transfer_addrs ${netdev} ${vdev}
root@51 211 if ! ifdown ${netdev}; then
root@51 212 # If ifdown fails, remember the IP details.
root@51 213 get_ip_info ${netdev}
root@51 214 ip link set ${netdev} down
root@51 215 ip addr flush ${netdev}
root@51 216 fi
root@51 217 ip link set ${netdev} name ${pdev}
root@51 218 ip link set ${vdev} name ${netdev}
root@51 219
root@51 220 setup_bridge_port ${pdev}
root@51 221 setup_bridge_port ${vif0}
root@51 222 ip link set ${netdev} addr ${mac} arp on
root@51 223
root@51 224 ip link set ${bridge} up
root@51 225 add_to_bridge ${bridge} ${vif0}
root@51 226 add_to_bridge2 ${bridge} ${pdev}
root@51 227 do_ifup ${netdev}
root@51 228 else
root@51 229 # old style without ${vdev}
root@51 230 transfer_addrs ${netdev} ${bridge}
root@51 231 transfer_routes ${netdev} ${bridge}
root@51 232 fi
root@51 233
root@51 234 if [ ${antispoof} = 'yes' ] ; then
root@51 235 antispoofing
root@51 236 fi
root@51 237 }
root@51 238
root@51 239 op_stop () {
root@51 240 if [ "${bridge}" = "null" ]; then
root@51 241 return
root@51 242 fi
root@51 243 if ! link_exists "$bridge"; then
root@51 244 return
root@51 245 fi
root@51 246
root@51 247 if link_exists "$pdev"; then
root@51 248 ip link set dev ${vif0} down
root@51 249 mac=`ip link show ${netdev} | grep 'link\/ether' | sed -e 's/.*ether \(..:..:..:..:..:..\).*/\1/'`
root@51 250 transfer_addrs ${netdev} ${pdev}
root@51 251 if ! ifdown ${netdev}; then
root@51 252 get_ip_info ${netdev}
root@51 253 fi
root@51 254 ip link set ${netdev} down arp off
root@51 255 ip link set ${netdev} addr fe:ff:ff:ff:ff:ff
root@51 256 ip link set ${pdev} down
root@51 257 ip addr flush ${netdev}
root@51 258 ip link set ${pdev} addr ${mac} arp on
root@51 259
root@51 260 brctl delif ${bridge} ${pdev}
root@51 261 brctl delif ${bridge} ${vif0}
root@51 262 ip link set ${bridge} down
root@51 263
root@51 264 ip link set ${netdev} name ${vdev}
root@51 265 ip link set ${pdev} name ${netdev}
root@51 266 do_ifup ${netdev}
root@51 267 else
root@51 268 transfer_routes ${bridge} ${netdev}
root@51 269 ip link set ${bridge} down
root@51 270 fi
root@51 271 brctl delbr ${bridge}
root@51 272 }
root@51 273
root@51 274 # adds $dev to $bridge but waits for $dev to be in running state first
root@51 275 add_to_bridge2() {
root@51 276 local bridge=$1
root@51 277 local dev=$2
root@51 278 local maxtries=10
root@51 279
root@51 280 echo -n "Waiting for ${dev} to negotiate link."
root@51 281 ip link set ${dev} up
root@51 282 for i in `seq ${maxtries}` ; do
root@51 283 if ifconfig ${dev} | grep -q RUNNING ; then
root@51 284 break
root@51 285 else
root@51 286 echo -n '.'
root@51 287 sleep 1
root@51 288 fi
root@51 289 done
root@51 290
root@51 291 if [ ${i} -eq ${maxtries} ] ; then echo '(link isnt in running state)' ; fi
root@51 292
root@51 293 add_to_bridge ${bridge} ${dev}
root@51 294 }
root@51 295
root@51 296 case "$command" in
root@51 297 start)
root@51 298 op_start
root@51 299 ;;
root@51 300
root@51 301 stop)
root@51 302 op_stop
root@51 303 ;;
root@51 304
root@51 305 status)
root@51 306 show_status ${netdev} ${bridge}
root@51 307 ;;
root@51 308
root@51 309 *)
root@51 310 echo "Unknown command: $command" >&2
root@51 311 echo 'Valid commands are: start, stop, status' >&2
root@51 312 exit 1
root@51 313 esac