I needed to fix the case where macvtap support is not to be compiled in. This part adds support for qemu making a macvtap tap device available via file descriptor passed to qemu command line. This also attempts to tear down the macvtap device when a VM terminates. This includes support for attachment and detachment to/from running VM. Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxx>
Index: libvirt-macvtap/src/qemu/qemu_conf.c =================================================================== --- libvirt-macvtap.orig/src/qemu/qemu_conf.c +++ libvirt-macvtap/src/qemu/qemu_conf.c @@ -52,6 +52,7 @@ #include "nodeinfo.h" #include "logging.h" #include "network.h" +#include "macvtap.h" #include "cpu/cpu.h" #define VIR_FROM_THIS VIR_FROM_QEMU @@ -1420,6 +1421,52 @@ int qemudExtractVersion(struct qemud_dri return 0; } +/** + * qemudPhysIfaceConnect: + * @conn: pointer to virConnect object + * @net: pointer to he VM's interface description with direct device type + * @linkdev: The name of the physical interface to link the macvtap to + * @brmode: The mode to put the macvtap device into + * + * Returns a filedescriptor on success or -1 in case of error. + */ +int +qemudPhysIfaceConnect(virConnectPtr conn, + virDomainNetDefPtr net, + char *linkdev, + int brmode) +{ + int rc; +#if defined(WITH_MACVTAP) + char *res_ifname = NULL; + int hasBusyDev = 0; + + delMacvtapByMACAddress(net->mac, &hasBusyDev); + + if (hasBusyDev) { + virReportSystemError(errno, "%s", + _("A macvtap with the same MAC address is in use")); + return -1; + } + + rc = openMacvtapTap(conn, net->ifname, net->mac, linkdev, brmode, + &res_ifname); + if (rc >= 0) { + VIR_FREE(net->ifname); + net->ifname = res_ifname; + } +#else + (void)net; + (void)linkdev; + (void)brmode; + (void)conn; + qemuReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("No support for macvtap device")); + rc = -1; +#endif + return rc; +} + int qemudNetworkIfaceConnect(virConnectPtr conn, @@ -2515,6 +2562,7 @@ qemuBuildHostNetStr(virDomainNetDefPtr n switch (net->type) { case VIR_DOMAIN_NET_TYPE_NETWORK: case VIR_DOMAIN_NET_TYPE_BRIDGE: + case VIR_DOMAIN_NET_TYPE_DIRECT: virBufferAddLit(&buf, "tap"); virBufferVSprintf(&buf, "%cfd=%s", type_sep, tapfd); type_sep = ','; @@ -3632,6 +3680,22 @@ int qemudBuildCommandLine(virConnectPtr if (snprintf(tapfd_name, sizeof(tapfd_name), "%d", tapfd) >= sizeof(tapfd_name)) goto no_memory; + } else if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) { + int tapfd = qemudPhysIfaceConnect(conn, net, + net->data.direct.linkdev, + net->data.direct.mode); + if (tapfd < 0) + goto error; + + if (VIR_REALLOC_N(*tapfds, (*ntapfds)+1) < 0) { + close(tapfd); + goto no_memory; + } + + (*tapfds)[(*ntapfds)++] = tapfd; + + if (snprintf(tapfd_name, sizeof(tapfd_name), "%d", tapfd) >= sizeof(tapfd_name)) + goto no_memory; } /* Possible combinations: Index: libvirt-macvtap/src/qemu/qemu_driver.c =================================================================== --- libvirt-macvtap.orig/src/qemu/qemu_driver.c +++ libvirt-macvtap/src/qemu/qemu_driver.c @@ -75,6 +75,7 @@ #include "libvirt_internal.h" #include "xml.h" #include "cpu/cpu.h" +#include "macvtap.h" #define VIR_FROM_THIS VIR_FROM_QEMU @@ -2795,6 +2796,8 @@ static void qemudShutdownVMDaemon(struct int retries = 0; qemuDomainObjPrivatePtr priv = vm->privateData; virErrorPtr orig_err; + virDomainDefPtr def; + int i; if (!virDomainObjIsActive(vm)) return; @@ -2806,8 +2809,7 @@ static void qemudShutdownVMDaemon(struct orig_err = virSaveLastError(); if (driver->macFilter) { - int i; - virDomainDefPtr def = vm->def; + def = vm->def; for (i = 0 ; i < def->nnets ; i++) { virDomainNetDefPtr net = def->nets[i]; if (net->ifname == NULL) @@ -2821,6 +2823,17 @@ static void qemudShutdownVMDaemon(struct } } +#if defined(WITH_MACVTAP) + def = vm->def; + for (i = 0; i < def->nnets; i++) { + virDomainNetDefPtr net = def->nets[i]; + if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) { + int dummy; + delMacvtapByMACAddress(net->mac, &dummy); + } + } +#endif + if (virKillProcess(vm->pid, 0) == 0 && virKillProcess(vm->pid, SIGTERM) < 0) virReportSystemError(errno, @@ -5589,6 +5602,19 @@ static int qemudDomainAttachNetDevice(vi if ((tapfd = qemudNetworkIfaceConnect(conn, driver, net, qemuCmdFlags)) < 0) return -1; + } else if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) { + if (priv->monConfig->type != VIR_DOMAIN_CHR_TYPE_UNIX) { + qemuReportError(VIR_ERR_NO_SUPPORT, + _("network device type '%s' cannot be attached: " + "qemu is not using a unix socket monitor"), + virDomainNetTypeToString(net->type)); + return -1; + } + + if ((tapfd = qemudPhysIfaceConnect(conn, net, + net->data.direct.linkdev, + net->data.direct.mode)) < 0) + return -1; } if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets+1) < 0) @@ -6207,6 +6233,13 @@ qemudDomainDetachNetDevice(struct qemud_ } qemuDomainObjExitMonitorWithDriver(driver, vm); +#if defined(WITH_MACVTAP) + if (detach->type == VIR_DOMAIN_NET_TYPE_DIRECT) { + int dummy; + delMacvtapByMACAddress(detach->mac, &dummy); + } +#endif + if ((driver->macFilter) && (detach->ifname != NULL)) { if ((errno = networkDisallowMacOnPort(driver, detach->ifname, Index: libvirt-macvtap/src/qemu/qemu_conf.h =================================================================== --- libvirt-macvtap.orig/src/qemu/qemu_conf.h +++ libvirt-macvtap/src/qemu/qemu_conf.h @@ -247,6 +247,11 @@ int qemudNetworkIfaceConnect unsigned long long qemuCmdFlags) ATTRIBUTE_NONNULL(1); +int qemudPhysIfaceConnect(virConnectPtr conn, + virDomainNetDefPtr net, + char *linkdev, + int brmode); + int qemudProbeMachineTypes (const char *binary, virCapsGuestMachinePtr **machines, int *nmachines);
-- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list