The QEMU driver pre-allocates a TAP device and connects it to a bridge
when using virtual networking. The FD associated with the tap device is
then passed to QEMU.
When running Xen guests, Xenner needs to turn this FD back into a TUN
device name. It does this by querying the hardware address of each NIC
and looking for the one which matches that it expects - ie its TUN device.
This obviously requires that the TUN device be configured with a MAC
address though. libvirt does not currently do this. This patch fixes this
and thus makes Xenner work from the QEMU driver when using virtual
networking
With this patch applied, and the latest 'virt-install' from upstream
and the latest 'xenner' RPM from Fedora 9, it is now possible to
create Xen paravirt guests under KVM using virt-install. That said
there's a few more pending patch to cleanup various hacks.
bridge.c | 14 ++++++++++++++
bridge.h | 1 +
qemu_conf.c | 1 +
3 files changed, 16 insertions(+)
Dan.
Index: bridge.c
===================================================================
RCS file: /data/cvs/libvirt/src/bridge.c,v
retrieving revision 1.8
diff -u -p -r1.8 bridge.c
--- bridge.c 5 Feb 2008 19:27:37 -0000 1.8
+++ bridge.c 27 Feb 2008 21:32:44 -0000
@@ -42,6 +42,7 @@
#include <linux/sockios.h> /* SIOCBRADDBR etc. */
#include <linux/if_bridge.h> /* SYSFS_BRIDGE_ATTR */
#include <linux/if_tun.h> /* IFF_TUN, IFF_NO_PI */
+#include <net/if_arp.h> /* ARPHRD_ETHER */
#include "internal.h"
@@ -312,6 +313,7 @@ brDeleteInterface(brControl *ctl ATTRIBU
int
brAddTap(brControl *ctl,
const char *bridge,
+ unsigned char *macaddr,
char *ifname,
int maxlen,
int *tapfd)
@@ -355,6 +357,18 @@ brAddTap(brControl *ctl,
}
if (ioctl(fd, TUNSETIFF, &try) == 0) {
+ struct ifreq addr;
+ memset(&addr, 0, sizeof(addr));
+ memcpy(addr.ifr_hwaddr.sa_data, macaddr, 6);
+ addr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
+
+ /* Device actually starts in 'UP' state, but it
+ * needs to be down to set the MAC addr
+ */
+ if ((errno = brSetInterfaceUp(ctl, try.ifr_name, 0)))
+ goto error;
+ if (ioctl(fd, SIOCSIFHWADDR, &addr) != 0)
+ goto error;
if ((errno = brAddInterface(ctl, bridge, try.ifr_name)))
goto error;
if ((errno = brSetInterfaceUp(ctl, try.ifr_name, 1)))
Index: bridge.h
===================================================================
RCS file: /data/cvs/libvirt/src/bridge.h,v
retrieving revision 1.4
diff -u -p -r1.4 bridge.h
--- bridge.h 29 Jan 2008 18:15:54 -0000 1.4
+++ bridge.h 27 Feb 2008 21:32:44 -0000
@@ -62,6 +62,7 @@ int brDeleteInterface (brContr
int brAddTap (brControl *ctl,
const char *bridge,
+ unsigned char *mac,
char *ifname,
int maxlen,
int *tapfd);
Index: qemu_conf.c
===================================================================
RCS file: /data/cvs/libvirt/src/qemu_conf.c,v
retrieving revision 1.38
diff -u -p -r1.38 qemu_conf.c
--- qemu_conf.c 27 Feb 2008 04:35:08 -0000 1.38
+++ qemu_conf.c 27 Feb 2008 21:32:44 -0000
@@ -1530,6 +1530,7 @@ qemudNetworkIfaceConnect(virConnectPtr c
}
if ((err = brAddTap(driver->brctl, brname,
+ net->mac,
ifname, BR_IFNAME_MAXLEN, &tapfd))) {
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
"Failed to add tap interface '%s' to bridge
'%s' : %s",
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules:
http://search.cpan.org/~danberr/ -=|
|=- Projects:
http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|