source: drbl-virt/conf/initrd_bin/network-bridge @ 186

Last change on this file since 186 was 170, checked in by rock, 14 years ago

Add: DRBL client -> Xen configuration file

  • Property svn:executable set to *
File size: 7.2 KB
Line 
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#============================================================================
50
51
52dir=/sbin
53. "$dir/xen-script-common.sh"
54. "$dir/xen-network-common.sh"
55
56findCommand "$@"
57evalVariables "$@"
58
59modprobe netloop > /dev/null 2>&1 || true
60
61is_network_root () {
62    local rootfs=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/") { print $3; }}' /etc/mtab)
63    local rootopts=$(awk '{ if ($1 !~ /^[ \t]*#/ && $2 == "/") { print $4; }}' /etc/mtab)
64
65    [[ "$rootfs" =~ "^nfs" ]] || [[ "$rootopts" =~ "_netdev" ]] && return 0 || return 1
66}
67
68find_alt_device () {
69    local interf=$1
70    local prefix=${interf%[[:digit:]]}
71    local ifs=$(ip link show | grep " $prefix" |\
72                gawk '{ printf ("%s",substr($2,1,length($2)-1)) }' |\
73                sed s/$interf//)
74    echo "$ifs"
75}
76
77netdev=${netdev:-$(ip route list 0.0.0.0/0  | \
78                   sed 's/.*dev \([a-z]\+[0-9]\+\).*$/\1/')}
79if is_network_root ; then
80    altdevs=$(find_alt_device $netdev)
81    for netdev in $altdevs; do break; done
82    if [ -z "$netdev" ]; then
83        [ -x /usr/bin/logger ] && /usr/bin/logger "network-bridge: bridging not supported on network root; not starting"
84        exit
85    fi
86fi
87netdev=${netdev:-eth0}
88bridge=${bridge:-${netdev}}
89antispoof=${antispoof:-no}
90
91pdev="p${netdev}"
92tdev=tmpbridge
93
94get_ip_info() {
95    addr_pfx=`ip addr show dev $1 | grep -E '^ *inet' | sed -e 's/ *inet //' -e 's/ .*//'`
96    gateway=`ip route show dev $1 | fgrep default | sed 's/default via //'`
97}
98   
99do_ifup() {
100    if ! ifup $1 ; then
101        if [ -n "$addr_pfx" ] ; then
102            # use the info from get_ip_info()
103            ip addr flush $1
104            ip addr add ${addr_pfx} dev $1
105            ip link set dev $1 up
106            [ -n "$gateway" ] && ip route add default via ${gateway}
107        fi
108    fi
109}
110
111# Usage: transfer_addrs src dst
112# Copy all IP addresses (including aliases) from device $src to device $dst.
113transfer_addrs () {
114    local src=$1
115    local dst=$2
116    # Don't bother if $dst already has IP addresses.
117    if ip addr show dev ${dst} | grep -E -q '^ *inet ' ; then
118        return
119    fi
120    # Address lines start with 'inet' and have the device in them.
121    # Replace 'inet' with 'ip addr add' and change the device name $src
122    # to 'dev $src'.
123    ip addr show dev ${src} | grep -E '^ *inet ' | sed -e "
124s/inet/ip addr add/
125s@\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+/[0-9]\+\)@\1@
126s/${src}/dev ${dst} label ${dst}/
127s/secondary//
128" | sh -e
129    # Remove automatic routes on destination device
130    ip route list | sed -ne "
131/dev ${dst}\( \|$\)/ {
132  s/^/ip route del /
133  p
134}" | sh -e
135}
136
137# Usage: transfer_routes src dst
138# Get all IP routes to device $src, delete them, and
139# add the same routes to device $dst.
140# The original routes have to be deleted, otherwise adding them
141# for $dst fails (duplicate routes).
142transfer_routes () {
143    local src=$1
144    local dst=$2
145    # List all routes and grep the ones with $src in.
146    # Stick 'ip route del' on the front to delete.
147    # Change $src to $dst and use 'ip route add' to add.
148    ip route list | sed -ne "
149/dev ${src}\( \|$\)/ {
150  h
151  s/^/ip route del /
152  P
153  g
154  s/${src}/${dst}/
155  s/^/ip route add /
156  P
157  d
158}" | sh -e
159}
160
161
162##
163# link_exists interface
164#
165# Returns 0 if the interface named exists (whether up or down), 1 otherwise.
166#
167link_exists()
168{
169    if ip link show "$1" >/dev/null 2>/dev/null
170    then
171        return 0
172    else
173        return 1
174    fi
175}
176
177# Set the default forwarding policy for $dev to drop.
178# Allow forwarding to the bridge.
179antispoofing () {
180    iptables -P FORWARD DROP
181    iptables -F FORWARD
182    iptables -A FORWARD -m physdev --physdev-in ${pdev} -j ACCEPT
183}
184
185# Usage: show_status dev bridge
186# Print ifconfig and routes.
187show_status () {
188    local dev=$1
189    local bridge=$2
190   
191    echo '============================================================'
192    ip addr show ${dev}
193    ip addr show ${bridge}
194    echo ' '
195    brctl show ${bridge}
196    echo ' '
197    ip route list
198    echo ' '
199    route -n
200    echo '============================================================'
201}
202
203op_start () {
204    if [ "${bridge}" = "null" ] ; then
205  return
206    fi
207
208    if link_exists "$pdev"; then
209        # The device is already up.
210        return
211    fi
212
213    create_bridge ${tdev}
214
215    preiftransfer ${netdev}
216    transfer_addrs ${netdev} ${tdev}
217    if ! ifdown ${netdev}; then
218  # If ifdown fails, remember the IP details.
219  get_ip_info ${netdev}
220  ip link set ${netdev} down
221  ip addr flush ${netdev}
222    fi
223    ip link set ${netdev} name ${pdev}
224    ip link set ${tdev} name ${bridge}
225
226    setup_bridge_port ${pdev}
227
228    add_to_bridge2 ${bridge} ${pdev}
229    do_ifup ${bridge}
230
231    if [ ${antispoof} = 'yes' ] ; then
232  antispoofing
233    fi
234}
235
236op_stop () {
237    if [ "${bridge}" = "null" ]; then
238  return
239    fi
240    if ! link_exists "$bridge"; then
241  return
242    fi
243
244    transfer_addrs ${bridge} ${pdev}
245    if ! ifdown ${bridge}; then
246  get_ip_info ${bridge}
247    fi
248    ip link set ${pdev} down
249    ip addr flush ${bridge}
250
251    brctl delif ${bridge} ${pdev}
252    ip link set ${bridge} down
253
254    ip link set ${bridge} name ${tdev}
255    ip link set ${pdev} name ${netdev}
256    do_ifup ${netdev}
257
258    brctl delbr ${tdev}
259}
260
261# adds $dev to $bridge but waits for $dev to be in running state first
262add_to_bridge2() {
263    local bridge=$1
264    local dev=$2
265    local maxtries=10
266
267    echo -n "Waiting for ${dev} to negotiate link."
268    ip link set ${dev} up
269    for i in `seq ${maxtries}` ; do
270  if ifconfig ${dev} | grep -q RUNNING ; then
271      break
272  else
273      echo -n '.'
274      sleep 1
275  fi
276    done
277
278    if [ ${i} -eq ${maxtries} ] ; then echo -n '(link isnt in running state)' ; fi
279    echo
280
281    add_to_bridge ${bridge} ${dev}
282}
283
284case "$command" in
285    start)
286  op_start
287  ;;
288   
289    stop)
290  op_stop
291  ;;
292
293    status)
294  show_status ${netdev} ${bridge}
295  ;;
296
297    *)
298  echo "Unknown command: $command" >&2
299  echo 'Valid commands are: start, stop, status' >&2
300  exit 1
301esac
Note: See TracBrowser for help on using the repository browser.