3 # Thierry Parmentelat <thierry.parmentelat@inria.fr>
4 # Copyright (C) 2010 INRIA
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
11 COMMAND=$(basename $0)
20 #################### compute INTERFACE_LAN
21 # use /proc/net/dev instead of a hard-wired list
22 function gather_interfaces () {
24 with open("/proc/net/dev") as feed:
28 ifname = line.replace(" ","").split(":")[0]
29 if ifname.find("lo")==0:
31 if ifname.find("br")==0:
33 if ifname.find("virbr")==0:
35 if ifname.find("tap")==0:
41 function discover_interface () {
42 for ifname in $(gather_interfaces); do
43 ip link show $ifname | grep -qi 'state UP' && { echo $ifname; return; }
45 # still not found ? that's bad
48 INTERFACE_LAN=$(discover_interface)
49 echo Using physical interface $INTERFACE_LAN
52 # Fonction de mise en place du pont
55 echo "========== $COMMAND: entering start - beg"
60 echo "========== $COMMAND: entering start - end"
62 # disable netfilter calls for bridge interface (they cause panick on 2.6.35 anyway)
64 # another option would be to accept the all forward packages for
65 # bridged interface like: -A FORWARD -m physdev --physdev-is-bridged -j ACCEPT
66 sysctl net.bridge.bridge-nf-call-iptables=0
67 sysctl net.bridge.bridge-nf-call-ip6tables=0
68 sysctl net.bridge.bridge-nf-call-arptables=0
70 # take extra arg for ifname, if provided
71 [ -n "$1" ] && { INTERFACE_LAN=$1; shift ; }
74 type -p brctl &> /dev/null || { echo "brctl not found, please install bridge-utils" ; exit 1 ; }
76 #if we have already configured the same host_box no need to do it again
77 ip address show $INTERFACE_BRIDGE &> /dev/null && {
78 echo "Bridge interface $INTERFACE_BRIDGE already set up - $COMMAND start exiting"
81 ip address show $INTERFACE_LAN &> /dev/null || {
82 echo "Cannot use interface $INTERFACE_LAN - exiting"
86 #Getting host IP/masklen
87 address=$(/sbin/ip address show $INTERFACE_LAN | grep -v inet6 | grep inet | head --lines=1 | awk '{print $2;}')
88 [ -z "$address" ] && { echo "ERROR: Could not determine IP address for $INTERFACE_LAN" ; exit 1 ; }
90 broadcast=$(/sbin/ip address show $INTERFACE_LAN | grep -v inet6 | grep inet | head --lines=1 | awk '{print $4;}')
91 [ -z "$broadcast" ] && echo "WARNING: Could not determine broadcast address for $INTERFACE_LAN"
93 gateway=$(ip route show | grep default | awk '{print $3;}')
94 [ -z "$gateway" ] && echo "WARNING: Could not determine gateway IP"
98 #echo "Starting udev ..."
100 #if modprobe kqemu &> /dev/null ; then
101 # echo "(bridge-init) kqemu loaded"
103 # echo "(bridge-init) WARNING : Could not modprobe kqemu"
105 #Loading the tun/tap model
106 if modprobe tun ; then
108 # Giving read/write access
109 echo "Granting read/write acces to the tun device"
110 chmod 666 /dev/net/tun
112 echo "Could not modprobe tun - exiting"
116 # creating the bridge
117 echo "Creating bridge INTERFACE_BRIDGE=$INTERFACE_BRIDGE"
118 brctl addbr $INTERFACE_BRIDGE
119 #brctl stp $INTERFACE_BRIDGE yes
120 brctl addif $INTERFACE_BRIDGE $INTERFACE_LAN
121 echo "Activating promiscuous mode INTERFACE_LAN=$INTERFACE_LAN"
122 ip link set dev $INTERFACE_LAN promisc on
124 echo "Setting bridge address=$address broadcast=$broadcast"
126 ip address add $address broadcast $broadcast dev $INTERFACE_BRIDGE
127 # turn on bridge interface
128 ip link set dev $INTERFACE_BRIDGE up
129 ip address del $address dev $INTERFACE_LAN
132 #Reconfigure the routing table
133 echo "Adding default route via gateway=$gateway on dev $INTERFACE_LAN"
134 ip route add 0.0.0.0/0 via $gateway dev $INTERFACE_BRIDGE
136 echo "========== $COMMAND: exiting start - beg"
139 echo "========== $COMMAND: exiting start - end"
142 #Adding a new interface to the bridge: this is used by qemu-ifup
145 [[ -z "$@" ]] && { echo "Usage: $COMMAND add ifname" ; exit 1 ; }
146 INTERFACE_LAN=$1; shift
148 echo "========== $COMMAND: entering add - beg"
151 echo "========== $COMMAND: entering add - end"
153 echo "Activating link for $INTERFACE_LAN..."
154 /sbin/ip link set $INTERFACE_LAN up
156 echo "Adding $INTERFACE_LAN to $INTERFACE_BRIDGE"
157 brctl addif $INTERFACE_BRIDGE $INTERFACE_LAN
159 # turn off filtering on this interface
160 ########## from the test environment
161 # expected vars are MACADDR, NODE_ISO, HOSTNAME, IP and TARGET_ARCH
163 [ -f "$CONFIG" ] || { echo "Config file for qemu $CONFIG not found in $(pwd)" ; exit 1 ; }
166 echo "Tweaking iptables"
167 iptables-save > iptables.pre
168 # rewrite a new config - quick and dirty
169 ./iptables.py iptables.pre iptables.post $IP
170 iptables-restore < iptables.post
172 echo "========== $COMMAND: exiting add - beg"
177 echo "Installed iptables"
180 echo "========== $COMMAND: exiting add - end"
183 #Stop the bridge and restore the original setting
185 # take extra arg for ifname, if provided
186 [ -n "$1" ] && { INTERFACE_LAN=$1; shift ; }
189 type -p brctl &> /dev/null || { echo "brctl not found, please install bridge-utils" ; exit 1 ; }
191 ip address show $INTERFACE_BRIDGE &> /dev/null || {
192 echo "Bridge interface $INTERFACE_BRIDGE does not exist - $COMMAND stop exiting"
195 address=$(/sbin/ip address show $INTERFACE_BRIDGE | grep -v inet6 | grep inet | head --lines=1 | awk '{print $2;}')
196 brctl delif $INTERFACE_BRIDGE $INTERFACE_LAN
197 ip address del $address dev $INTERFACE_BRIDGE
198 brctl delbr $INTERFACE_BRIDGE
199 systemctl NetworkManager restart
212 echo $"Usage: env-qemu {start|add|stop} [interface]" ; exit 1 ;;
217 # redirect stderr as well