xen-drbd
view 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 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