compute network interface name instead of guessing it
[tests.git] / system / template-qemu / qemu-bridge-init
1 #!/bin/bash
2
3 # Thierry Parmentelat <thierry.parmentelat@inria.fr>
4 # Copyright (C) 2010 INRIA 
5 #
6 # Establishment of a runtime environment for a
7 # virtual  machine  under QEMU, This script allows the host box
8 # to share its network connection with qemu-based guests
9 #
10
11 COMMAND=$(basename $0)
12 cd $(dirname $0)
13
14 # turn on verbosity
15 set -x
16
17 # constant
18 INTERFACE_BRIDGE=br0
19
20 # Default Value for INTERFACE_LAN
21 # use /proc/net/dev instead of a hard-wired list
22 function gather_interfaces () {
23     python <<EOF
24 for line in file("/proc/net/dev"):
25     if ':' not in line: continue
26     ifname=line.replace(" ","").split(":")[0]
27     if ifname.find("lo")==0: continue
28     if ifname.find("virbr")==0: continue
29     if ifname.find("tap")==0: continue
30     print ifname
31 EOF
32 }
33     
34 # let's try to figure out the interface to use - try these in order
35 function discover_interface () {
36     for ifname in $(gather_interfaces); do
37         ip link show $ifname | grep -q UP && { INTERFACE_LAN=$ifname; return; }
38     done
39     # still not found ? that's bad
40     INTERFACE_LAN=unknown
41 }
42 discover_interface
43 echo $INTERFACE_LAN
44
45 # Fonction de mise en place du pont
46 function start () {
47
48     echo "========== $COMMAND: entering start - beg"
49     hostname
50     uname -a
51     ifconfig
52     netstat -rn
53     echo "========== $COMMAND: entering start - end"
54
55     # disable netfilter calls for bridge interface (they cause panick on 2.6.35 anyway)
56     #
57     # another option would be to accept the all forward packages for
58     # bridged interface like: -A FORWARD -m physdev --physdev-is-bridged -j ACCEPT
59     sysctl net.bridge.bridge-nf-call-iptables=0
60     sysctl net.bridge.bridge-nf-call-ip6tables=0
61     sysctl net.bridge.bridge-nf-call-arptables=0
62
63     # take extra arg for ifname, if provided
64     [ -n "$1" ] && { INTERFACE_LAN=$1; shift ; }
65
66     ### Checking
67     type -p brctl &> /dev/null || { echo "brctl not found, please install bridge-utils" ; exit 1 ; }
68
69     #if we have already configured the same host_box no need to do it again
70     /sbin/ifconfig $INTERFACE_BRIDGE &> /dev/null && {
71         echo "Bridge interface $INTERFACE_BRIDGE already set up - $COMMAND start exiting"
72         exit 0
73     }
74     /sbin/ifconfig $INTERFACE_LAN &>/dev/null || {
75         echo "Cannot use interface $INTERFACE_LAN - exiting"
76         exit 1
77     }
78
79     #Getting host IP/masklen
80     address=$(/sbin/ip addr show $INTERFACE_LAN | grep -v inet6 | grep inet | head --lines=1 | awk '{print $2;}')
81     [ -z "$address" ] && { echo "ERROR: Could not determine IP address for $INTERFACE_LAN" ; exit 1 ; }
82     
83     broadcast=$(/sbin/ip addr show $INTERFACE_LAN | grep -v inet6 | grep inet | head --lines=1 | awk '{print $4;}')
84     [ -z "$broadcast" ] && echo "WARNING: Could not determine broadcast address for $INTERFACE_LAN"
85
86     gateway=$(netstat -rn | grep '^0.0.0.0' | awk '{print $2;}')
87     [ -z "$gateway" ] && echo "WARNING: Could not determine gateway IP"
88
89     ### do it
90     #Restarting udev
91     echo "Starting udev ..."
92     /sbin/udevd restart
93     if modprobe kqemu &> /dev/null ; then
94         echo "(bridge-init) kqemu loaded"
95     else
96         echo "(bridge-init) WARNING : Could not modprobe kqemu"
97     fi
98     #Loading the tun/tap model
99     if modprobe tun ; then
100         echo "tun loaded"
101         # Giving read/write access
102         echo "Granting read/write acces to the tun device"
103         chmod 666 /dev/net/tun
104     else
105         echo "Could not modprobe tun - exiting"
106         exit 1
107     fi
108
109     # creating the bridge
110     echo "Creating bridge INTERFACE_BRIDGE=$INTERFACE_BRIDGE"
111     brctl addbr $INTERFACE_BRIDGE
112     #brctl stp $INTERFACE_BRIDGE yes
113     brctl addif $INTERFACE_BRIDGE $INTERFACE_LAN
114     echo "Activating promiscuous mode INTERFACE_LAN=$INTERFACE_LAN"
115     /sbin/ifconfig $INTERFACE_LAN 0.0.0.0 promisc up
116     sleep 2
117     echo "Setting bridge address=$address broadcast=$broadcast"
118     # static
119     /sbin/ifconfig $INTERFACE_BRIDGE $address broadcast $broadcast up
120     sleep 1
121         
122     #Reconfigure the routing table
123     echo "Configuring gateway=$gateway"
124     route add default gw $gateway
125
126     echo "========== $COMMAND: exiting start - beg"
127     ifconfig
128     netstat -rn
129     echo "========== $COMMAND: exiting start - end"
130 }
131
132 #Adding a new interface to the bridge: this is used by qemu-ifup 
133 function add () {
134
135     [[ -z "$@" ]] && { echo "Usage: $COMMAND add ifname" ; exit 1 ; }
136     INTERFACE_LAN=$1; shift
137
138     echo "========== $COMMAND: entering add - beg"
139     ifconfig
140     netstat -rn
141     echo "========== $COMMAND: entering add - end"
142
143     echo "Activating link for $INTERFACE_LAN..."
144     /sbin/ip link set $INTERFACE_LAN up
145     sleep 1
146     echo "Adding $INTERFACE_LAN to $INTERFACE_BRIDGE"
147     brctl addif $INTERFACE_BRIDGE $INTERFACE_LAN
148
149     # turn off filtering on this interface
150     ########## from the test environment
151     # expected vars are MACADDR, NODE_ISO, HOSTNAME, IP and TARGET_ARCH
152     CONFIG=qemu.conf
153     [ -f "$CONFIG" ] || { echo "Config file for qemu $CONFIG not found in $(pwd)" ; exit 1 ; }
154     . $CONFIG
155
156     echo "Tweaking iptables"
157     iptables-save > iptables.pre
158     # rewrite a new config - quick and dirty
159     ./iptables.py iptables.pre iptables.post $IP
160     iptables-restore < iptables.post
161
162     echo "========== $COMMAND: exiting add - beg"
163
164     ifconfig
165     netstat -rn
166
167     echo "Installed iptables"
168     iptables-save
169     
170     echo "========== $COMMAND: exiting add - end"
171 }
172
173 #Stop the bridge and restore the original setting
174 function stop () {
175     # take extra arg for ifname, if provided
176     [ -n "$1" ] && { INTERFACE_LAN=$1; shift ; }
177
178     ### Checking
179     type -p brctl &> /dev/null || { echo "brctl not found, please install bridge-utils" ; exit 1 ; }
180
181     /sbin/ifconfig $INTERFACE_BRIDGE &> /dev/null || {
182         echo "Bridge interface $INTERFACE_BRIDGE does not exist - $COMMAND stop exiting"
183         exit 0
184     }
185     brctl delif $INTERFACE_BRIDGE $INTERFACE_LAN
186     /sbin/ifconfig $INTERFACE_BRIDGE down
187     brctl delbr $INTERFACE_BRIDGE
188     /sbin/service network restart
189     /sbin/service iptables restart
190 }
191
192 function main () {
193
194     case "$1" in
195         start)
196             shift; start "$@" ;;
197         stop)
198             shift; stop "$@" ;;
199         add)
200             shift; add "$@" ;;
201         *)
202             echo $"Usage: env-qemu {start|add|stop} [interface]" ; exit 1 ;;
203     esac
204     exit 0
205 }
206
207 # redirect stderr as well
208 main "$@" 2>&1