#include "nodeinfo.h"
#include "logging.h"
#include "network.h"
+#include "macvtap.h"
#include "cpu/cpu.h"
#define VIR_FROM_THIS VIR_FROM_QEMU
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 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)conn;
+ (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,
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 = ',';
(*tapfds)[(*ntapfds)++] = tapfd;
+ 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;
}
#include "libvirt_internal.h"
#include "xml.h"
#include "cpu/cpu.h"
+#include "macvtap.h"
#define VIR_FROM_THIS VIR_FROM_QEMU
int retries = 0;
qemuDomainObjPrivatePtr priv = vm->privateData;
virErrorPtr orig_err;
+ virDomainDefPtr def;
+ int i;
if (!virDomainObjIsActive(vm))
return;
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)
}
}
+#if 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,
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)
}
qemuDomainObjExitMonitorWithDriver(driver, vm);
+#if 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,