ia64/xen-unstable

view tools/examples/network-bridge @ 16684:7b7700a30e52

Handle netdev secondary addresses and labels

Fix the network-bridge logic to correctly transfer secondary IP
address from $netdev to $bridge.

e.g. if you add an secondary address/label/alias with:

$> ip addr add 172.31.0.200/24 dev eth0 label eth0:00

then, "ip addr show dev eth0" gives e.g.:

inet 172.31.0.10/24 brd 172.31.0.255 scope global eth0
inet 172.31.0.200/24 scope global secondary eth0:00

and transfer_addrs() tries to execute:

ip addr add 172.31.0.10/24 brd 172.31.0.255 scope global dev tmpbridge
ip addr add 172.31.0.200/24 scope global secondary dev tmpbridge:00

which causes the sript to fail because:

1) The device tmpbridge:00 doesn't exist
2) The "secondary" flag isn't valid

This patch fixes the sed commands to instead give:

ip addr add 172.31.0.10/24 brd 172.31.0.255 scope global dev tmpbridge label tmpbridge
ip addr add 172.31.0.200/24 scope global dev tmpbridge label tmpbridge:00

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