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