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 @@ -1423,6 +1424,43 @@ int qemudExtractVersion(virConnectPtr co int +qemudPhysIfaceConnect(virConnectPtr conn, + virDomainNetDefPtr net, + char *linkdev, + char *brmode) +{ + int rc; +#if defined(WITH_MACVTAP) + char *res_ifname = NULL; + int hasBusyDev = 0; + + delMacvtapByMACAddress(conn, net->mac, &hasBusyDev); + + if (hasBusyDev) { + virReportSystemError(NULL, 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; + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + "%s", _("No support for macvtap device")); + rc = -1; +#endif + return rc; +} + + +int qemudNetworkIfaceConnect(virConnectPtr conn, struct qemud_driver *driver, virDomainNetDefPtr net, @@ -2520,6 +2558,7 @@ qemuBuildHostNetStr(virConnectPtr conn, 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 = ','; @@ -3636,6 +3675,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 @@ -2825,6 +2826,8 @@ static void qemudShutdownVMDaemon(virCon int retries = 0; qemuDomainObjPrivatePtr priv = vm->privateData; virErrorPtr orig_err; + virDomainDefPtr def; + int i; if (!virDomainObjIsActive(vm)) return; @@ -2836,8 +2839,7 @@ static void qemudShutdownVMDaemon(virCon 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) @@ -2851,6 +2853,17 @@ static void qemudShutdownVMDaemon(virCon } } +#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(conn, net->mac, &dummy); + } + } +#endif + if (virKillProcess(vm->pid, 0) == 0 && virKillProcess(vm->pid, SIGTERM) < 0) virReportSystemError(conn, errno, @@ -5629,6 +5642,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) { + qemudReportError(conn, dom, NULL, VIR_ERR_NO_SUPPORT, + _("direct 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) @@ -6242,6 +6268,11 @@ qemudDomainDetachNetDevice(virConnectPtr } qemuDomainObjExitMonitorWithDriver(driver, vm); + if (detach->type == VIR_DOMAIN_NET_TYPE_DIRECT) { + int dummy; + delMacvtapByMACAddress(conn, detach->mac, &dummy); + } + if ((driver->macFilter) && (detach->ifname != NULL)) { if ((errno = networkDisallowMacOnPort(conn, driver, 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 virDomainNetDefPtr net, int qemuCmdFlags); +int qemudPhysIfaceConnect(virConnectPtr conn, + virDomainNetDefPtr net, + char *linkdev, + char *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