Automagic bridged networking with QEMU (tap)
Juergen Lock
nox at jelal.kn-bremen.de
Sun Aug 23 22:19:43 UTC 2009
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... :)
Thanx,
Juergen
More information about the freebsd-emulation
mailing list