ia64/xen-unstable

annotate tools/hotplug/Linux/network-bridge @ 18770:4bfc67b09e9c

tools/hotplug: Separate OS-specific scripts.

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