Automagic bridged networking with QEMU (tap)
Bakul Shah
bakul at bitblocks.com
Sun Aug 23 23:49:49 UTC 2009
I use something simpler that is perhaps less flexible but I
find my machines don't have enough oomph to handle more than
3 or 4 qemu VMs!
/boot/loader.conf
if_tap_load="YES" # if_bridge will be autoloaded later
/etc/rc.conf
cloned_interfaces="bridge0" # create these interfaces on bootup
autobridge_interfaces="bridge0" # autoconfigure these bridges
autobridge_bridge0="tap* $eth" # $eth = eth interface you want bridged
# if your machine has static ip address $ipaddr, with prefix length $len
ifconfig_bridge0="inet $ipaddr/$len
# if your machine is given a dynamic ip address
#ifconfig_bridge0="DHCP"
/etc/devfs.conf
# create as many as you are likely to use
own tap0 $user:$group # set to user/group of person invoking qemu
own tap1 $user:$group
own tap2 $user:$group
own tap3 $user:$group
/etc/sysctl.conf
net.link.tap.user_open=1
net.link.tap.up_on_open=1
ln -s /usr/bin/true /etc/qemu-ifup
ln -s /usr/bin/true /etc/qemu-ifdown
Note that on a wifi only machine you are only allowed one mac
address for the wifi link so bridging with VMs won't work and
you need NAT but you can still bridge all your tap interfaces
together.
Also note that each qemu VM will need a unique mac address.
On Mon, 24 Aug 2009 00:15:52 +0200 Juergen Lock <nox at jelal.kn-bremen.de> wrote:
> In article <h6m7i2$pgt$1 at ger.gmane.org> you write:
> >Hallo list,
> Hi!
> >
> >I spent a good portion of yesterday trying to find out how to change
> >from using user mode to bridged networking with QEMU on FreeBSD 7.2.
> >As I found a few how-to's of differing quality and I couldn't manage to
> >make it work for some time, I decided to share the final results of my
> >journey with you as I believe it may save someone a few hours or hair.
> >
> >The proposed solution does not need any manual steps and is fully
> >transparent to users (like user mode networking is). It does not even
> >permanently bridge your real NIC, only when necessary, which is good
> >because of some performance penalties when bridging. And you can run as
> >many guests as you want and it's all set up automagically. :-)
> >
> >OK, enough words, here's what to do:
> >
> >/boot/loader.conf[.local]:
> > if_bridge_load="YES"
> > if_tap_load="YES"
> >
> >/etc/sysctl.conf:
> > net.link.tap.up_on_open=1
> > net.link.tap.user_open=1
> >
> >/etc/devfs.rules:
> > [localrules=10]
> > add path 'tap*' mode 0660
> >
> >/etc/rc.conf[.local]:
> > devfs_system_ruleset="localrules"
> > kqemu_enable="YES"
> >
> >/usr/local/etc/qemu-ifup -- custom script
> >/usr/local/etc/qemu-ifdown -- custom script
> >
> >--- /usr/local/etc/qemu-ifup
> >
> >#!/bin/sh
> >#
> ># /usr/local/etc/qemu-ifup : martinko [20-aug-2009]
> >#
> >
> >IFNAME=re0
> >
> >for BRIDGE in $(ifconfig -a | grep '^bridge' | cut -d: -f1)
> >do
> > if [ -n "$(ifconfig "$BRIDGE" | grep -w "member: $IFNAME")" ]
> > then
> > echo "${0##*/}: Adding $1 as a member of $BRIDGE"
> > sudo /sbin/ifconfig "$BRIDGE" addm "$1" up
> > exit
> > fi
> >done
> >
> >BRIDGE="$(sudo /sbin/ifconfig bridge create)"
> >sudo /sbin/ifconfig "$BRIDGE" addm "$IFNAME" addm "$1" up
> >echo "${0##*/}: Created $BRIDGE and added $1 as a member"
> >
> >--- /usr/local/etc/qemu-ifdown
> >
> >#!/bin/sh
> >#
> ># /usr/local/etc/qemu-ifdown : martinko [20-aug-2009]
> >#
> >
> >for BRIDGE in $(ifconfig -a | grep '^bridge' | cut -d: -f1)
> >do
> > if [ -n "$(ifconfig "$BRIDGE" | grep -w "member: $1")" ]
> > then
> > if [ "$(ifconfig "$BRIDGE" | grep -c -w "member:")" -le 2 ]
> > then
> > echo "${0##*/}: Destroying $BRIDGE"
> > sudo /sbin/ifconfig "$BRIDGE" destroy
> > fi
> > echo "${0##*/}: Destroying $1"
> > sudo /sbin/ifconfig "$1" destroy
> > fi
> >done
> >
> >---
> >
> >And that's all, folks! :)
> >
> >Enjoy and if you find a better solution please let me/us know.
> >
> >Cheers,
> >
> >Martin
> >
> >PS1: Of course change IFNAME in qemu-ifup according to your setup.
> >PS2: You man want/need to change the group in devfs.rules as well.
>
> I like the idea, but found it needs a patch to qemu or otherwise a
> KASSERT gets triggered in the tap driver (sys/net/if_tap.c:tap_destroy(),
> causing a `tapX flags is out of sync' panic if the driver is built with
> INVARIANTS) because the tap interface gets destroyed before its /dev/tap
> fd is closed:
>
> Index: qemu/net.c
> @@ -961,11 +961,12 @@
> {
> TAPState *s = vc->opaque;
>
> - if (s->down_script[0])
> - launch_script(s->down_script, s->down_script_arg, s->fd);
> -
> qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
> close(s->fd);
> +
> + if (s->down_script[0])
> + launch_script(s->down_script, s->down_script_arg, -1);
> +
> qemu_free(s);
> }
>
> I guess the driver could handle this condition more gracefully, but
> until then... Oh and I also found the ifdown script doesn't get called
> in all cases, like when you quit qemu via the monitor.
>
> Btw, can someone test this on 6.3? I'm wondering if we could ship
> these ifup/down scripts in the qemu port(s) by default, maybe with an
> rcvar added to enable them or something like that. (and the other
> config instructions in the pkg-message file.) If you don't mind... :)
More information about the freebsd-emulation
mailing list