#!/bin/bash
+# Thierry Parmentelat <thierry.parmentelat@inria.fr>
+# Copyright (C) 2010 INRIA
+#
# Establishment of a runtime environment for a
# virtual machine under QEMU, This script allows the host box
# to share its network connection with qemu-based guests
#
-# Author: Amine chaoui
-#
COMMAND=$(basename $0)
+cd $(dirname $0)
+
+# turn on verbosity
+set -x
# constant
INTERFACE_BRIDGE=br0
-# Default Value
-INTERFACE_LAN=eth0
+#################### compute INTERFACE_LAN
+# use /proc/net/dev instead of a hard-wired list
+function gather_interfaces () {
+ python3 << EOF
+with open("/proc/net/dev") as feed:
+ for line in feed:
+ if ':' not in line:
+ continue
+ ifname = line.replace(" ","").split(":")[0]
+ if ifname.find("lo")==0:
+ continue
+ if ifname.find("br")==0:
+ continue
+ if ifname.find("virbr")==0:
+ continue
+ if ifname.find("tap")==0:
+ continue
+ print(ifname)
+EOF
+}
+
+function discover_interface () {
+ for ifname in $(gather_interfaces); do
+ ip link show $ifname | grep -qi 'state UP' && { echo $ifname; return; }
+ done
+ # still not found ? that's bad
+ echo unknown
+}
+INTERFACE_LAN=$(discover_interface)
+echo Using physical interface $INTERFACE_LAN
+
+####################
# Fonction de mise en place du pont
-start () {
+function start () {
+
+ echo "========== $COMMAND: entering start - beg"
+ hostname
+ uname -a
+ ip address show
+ ip route show
+ echo "========== $COMMAND: entering start - end"
+
+ # disable netfilter calls for bridge interface (they cause panick on 2.6.35 anyway)
+ #
+ # another option would be to accept the all forward packages for
+ # bridged interface like: -A FORWARD -m physdev --physdev-is-bridged -j ACCEPT
+ sysctl net.bridge.bridge-nf-call-iptables=0
+ sysctl net.bridge.bridge-nf-call-ip6tables=0
+ sysctl net.bridge.bridge-nf-call-arptables=0
# take extra arg for ifname, if provided
[ -n "$1" ] && { INTERFACE_LAN=$1; shift ; }
type -p brctl &> /dev/null || { echo "brctl not found, please install bridge-utils" ; exit 1 ; }
#if we have already configured the same host_box no need to do it again
- /sbin/ifconfig $INTERFACE_BRIDGE &> /dev/null && {
- echo "Interface bridge $INTERFACE_BRIDGE already exist."
+ ip address show $INTERFACE_BRIDGE &> /dev/null && {
+ echo "Bridge interface $INTERFACE_BRIDGE already set up - $COMMAND start exiting"
exit 0
}
- /sbin/ifconfig $INTERFACE_LAN &>/dev/null || {
+ ip address show $INTERFACE_LAN &> /dev/null || {
echo "Cannot use interface $INTERFACE_LAN - exiting"
exit 1
}
#Getting host IP/masklen
- address=$(/sbin/ip addr show $INTERFACE_LAN | grep -v inet6 | grep inet | awk '{print $2;}')
+ address=$(/sbin/ip address show $INTERFACE_LAN | grep -v inet6 | grep inet | head --lines=1 | awk '{print $2;}')
[ -z "$address" ] && { echo "ERROR: Could not determine IP address for $INTERFACE_LAN" ; exit 1 ; }
-
- broadcast=$(/sbin/ip addr show $INTERFACE_LAN | grep -v inet6 | grep inet | awk '{print $4;}')
+
+ broadcast=$(/sbin/ip address show $INTERFACE_LAN | grep -v inet6 | grep inet | head --lines=1 | awk '{print $4;}')
[ -z "$broadcast" ] && echo "WARNING: Could not determine broadcast address for $INTERFACE_LAN"
- gateway=$(netstat -rn | grep '^0.0.0.0' | awk '{print $2;}')
+ gateway=$(ip route show | grep default | awk '{print $3;}')
[ -z "$gateway" ] && echo "WARNING: Could not determine gateway IP"
### do it
#Restarting udev
- echo "Starting udev ..."
- /sbin/udevd restart
- if modprobe kqemu ; then
- echo "kqemu loadded"
- else
- echo "WARNING : Could not modprobe kqemu"
- fi
- #Loding the tun/tap model
+ #echo "Starting udev ..."
+ #/sbin/udevd restart
+ #if modprobe kqemu &> /dev/null ; then
+ # echo "(bridge-init) kqemu loaded"
+ #else
+ # echo "(bridge-init) WARNING : Could not modprobe kqemu"
+ #fi
+ #Loading the tun/tap model
if modprobe tun ; then
echo "tun loaded"
# Giving read/write access
fi
# creating the bridge
- echo "Creating bridge $INTERFACE_BRIDGE"
+ echo "Creating bridge INTERFACE_BRIDGE=$INTERFACE_BRIDGE"
brctl addbr $INTERFACE_BRIDGE
#brctl stp $INTERFACE_BRIDGE yes
brctl addif $INTERFACE_BRIDGE $INTERFACE_LAN
- echo "Activating promiscuous mode $INTERFACE_LAN..."
- /sbin/ifconfig $INTERFACE_LAN 0.0.0.0 promisc up
+ echo "Activating promiscuous mode INTERFACE_LAN=$INTERFACE_LAN"
+ ip link set dev $INTERFACE_LAN promisc on
sleep 2
- echo "Setting bridge $address $broadcast"
+ echo "Setting bridge address=$address broadcast=$broadcast"
# static
- /sbin/ifconfig $INTERFACE_BRIDGE $address broadcast $broadcast up
+ ip address add $address broadcast $broadcast dev $INTERFACE_BRIDGE
+ # turn on bridge interface
+ ip link set dev $INTERFACE_BRIDGE up
+ ip address del $address dev $INTERFACE_LAN
sleep 1
-
+
#Reconfigure the routing table
- echo "Configuring the IP Gateway @:" $gateway
- route add default gw $gateway
-
- # xxx this is *wrong*
- # wipe the host firewall otherwise the guest qemu can't access the LAN
- # echo "Wiping the firewall..."
- # iptables -F
-
+ echo "Adding default route via gateway=$gateway on dev $INTERFACE_LAN"
+ ip route add 0.0.0.0/0 via $gateway dev $INTERFACE_BRIDGE
+
+ echo "========== $COMMAND: exiting start - beg"
+ ip address show
+ ip route show
+ echo "========== $COMMAND: exiting start - end"
}
-#Adding a new interface to the bridge: this is used by qemu-ifup
-add () {
+#Adding a new interface to the bridge: this is used by qemu-ifup
+function add () {
[[ -z "$@" ]] && { echo "Usage: $COMMAND add ifname" ; exit 1 ; }
INTERFACE_LAN=$1; shift
+ echo "========== $COMMAND: entering add - beg"
+ ip address show
+ ip route show
+ echo "========== $COMMAND: entering add - end"
+
echo "Activating link for $INTERFACE_LAN..."
/sbin/ip link set $INTERFACE_LAN up
sleep 1
echo "Adding $INTERFACE_LAN to $INTERFACE_BRIDGE"
brctl addif $INTERFACE_BRIDGE $INTERFACE_LAN
+ # turn off filtering on this interface
+ ########## from the test environment
+ # expected vars are MACADDR, NODE_ISO, HOSTNAME, IP and TARGET_ARCH
+ CONFIG=qemu.conf
+ [ -f "$CONFIG" ] || { echo "Config file for qemu $CONFIG not found in $(pwd)" ; exit 1 ; }
+ . $CONFIG
+
+ echo "Tweaking iptables"
+ iptables-save > iptables.pre
+ # rewrite a new config - quick and dirty
+ ./iptables.py iptables.pre iptables.post $IP
+ iptables-restore < iptables.post
+
+ echo "========== $COMMAND: exiting add - beg"
+
+ ip address show
+ ip route show
+
+ echo "Installed iptables"
+ iptables-save
+
+ echo "========== $COMMAND: exiting add - end"
}
#Stop the bridge and restore the original setting
-stop () {
+function stop () {
# take extra arg for ifname, if provided
[ -n "$1" ] && { INTERFACE_LAN=$1; shift ; }
### Checking
type -p brctl &> /dev/null || { echo "brctl not found, please install bridge-utils" ; exit 1 ; }
- /sbin/ifconfig $INTERFACE_BRIDGE &> /dev/null || {
- echo "Interface bridge $INTERFACE_BRIDGE does not exist."
+ ip address show $INTERFACE_BRIDGE &> /dev/null || {
+ echo "Bridge interface $INTERFACE_BRIDGE does not exist - $COMMAND stop exiting"
exit 0
}
+ address=$(/sbin/ip address show $INTERFACE_BRIDGE | grep -v inet6 | grep inet | head --lines=1 | awk '{print $2;}')
brctl delif $INTERFACE_BRIDGE $INTERFACE_LAN
- /sbin/ifconfig $INTERFACE_BRIDGE down
+ ip address del $address dev $INTERFACE_BRIDGE
brctl delbr $INTERFACE_BRIDGE
- /sbin/service network restart
+ systemctl NetworkManager restart
+}
+
+function main () {
+
+ case "$1" in
+ start)
+ shift; start "$@" ;;
+ stop)
+ shift; stop "$@" ;;
+ add)
+ shift; add "$@" ;;
+ *)
+ echo $"Usage: env-qemu {start|add|stop} [interface]" ; exit 1 ;;
+ esac
+ exit 0
}
-#
-case "$1" in
- start)
- shift; start "$@" ;;
- stop)
- shift; stop "$@" ;;
- add)
- shift; add "$@" ;;
- *)
- echo $"Usage: env-qemu {start|add|stop} [interface]" ; exit 1 ;;
-esac
-
-exit 0
+# redirect stderr as well
+main "$@" 2>&1