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