Update code to create generic ethernet interfaces using the new utility library tunctl making changes to create the TAP device in libvirt and pass it to qemu as a file descriptor. --- diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index ee4b52b..181f56c 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -396,6 +396,51 @@ qemuOpenVhostNet(virDomainDefPtr def, } +int qemuEthernetIfaceCreate(virDomainDefPtr def, + virDomainNetDefPtr net, + virBitmapPtr qemuCaps) +{ + int tapfd; + int err; + int vnet_hdr = 0; + unsigned char tapmac[VIR_MAC_BUFLEN]; + + if (qemuCapsGet(qemuCaps, QEMU_CAPS_VNET_HDR) && + net->model && STREQ(net->model, "virtio")) + vnet_hdr = 1; + + if (!net->ifname || + STRPREFIX(net->ifname, "vnet") || + strchr(net->ifname, '%')) { + VIR_FREE(net->ifname); + if (!(net->ifname = strdup("vnet%d"))) { + virReportOOMError(); + return -1; + } + } + + err = createTap(&net->ifname, vnet_hdr, &tapfd); + virDomainAuditNetDevice(def, net, "/dev/net/tun", tapfd >= 0); + if (tapfd < 0 || err) + return -1; + + memcpy(tapmac, net->mac, VIR_MAC_BUFLEN); + /* Discourage bridge from using TAP dev MAC */ + tapmac[0] = 0xFE; + err = tapSetInterfaceMac(net->ifname, tapmac); + + if (err) + return -1; + + err = tapSetInterfaceUp(net->ifname, 1); + + if (err) + return -1; + + return tapfd; +} + + static int qemuDomainDeviceAliasIndex(virDomainDeviceInfoPtr info, const char *prefix) { @@ -2055,14 +2100,17 @@ qemuBuildHostNetStr(virDomainNetDefPtr net, case VIR_DOMAIN_NET_TYPE_ETHERNET: virBufferAddLit(&buf, "tap"); - if (net->ifname) { - virBufferAsprintf(&buf, "%cifname=%s", type_sep, net->ifname); - type_sep = ','; - } if (net->data.ethernet.script) { + if (net->ifname) { + virBufferAsprintf(&buf, "%cifname=%s", type_sep, net->ifname); + type_sep = ','; + } virBufferAsprintf(&buf, "%cscript=%s", type_sep, net->data.ethernet.script); type_sep = ','; + } else if(net->ifname) { + virBufferAsprintf(&buf, "%cfd=%s", type_sep, tapfd); + type_sep = ','; } is_tap = true; break; @@ -4064,6 +4112,18 @@ qemuBuildCommandLine(virConnectPtr conn, if (snprintf(tapfd_name, sizeof(tapfd_name), "%d", tapfd) >= sizeof(tapfd_name)) goto no_memory; + } else if (actualType == VIR_DOMAIN_NET_TYPE_ETHERNET && + !net->data.ethernet.script) { + int tapfd = qemuEthernetIfaceCreate(def, net, qemuCaps); + if (tapfd < 0) + goto error; + + last_good_net = i; + virCommandTransferFD(cmd, tapfd); + + if (snprintf(tapfd_name, sizeof(tapfd_name), "%d", + tapfd) >= sizeof(tapfd_name)) + goto no_memory; } if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK || diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index 00e58a2..b21eeb6 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -142,6 +142,10 @@ int qemuOpenVhostNet(virDomainDefPtr def, virBitmapPtr qemuCaps, int *vhostfd); +int qemuEthernetIfaceCreate(virDomainDefPtr def, + virDomainNetDefPtr net, + virBitmapPtr qemuCaps); + int qemudCanonicalizeMachine(struct qemud_driver *driver, virDomainDefPtr def); diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index e8b92a4..cbea145 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -29,6 +29,7 @@ # include "ebtables.h" # include "internal.h" # include "bridge.h" +# include "tunctl.h" # include "capabilities.h" # include "network_conf.h" # include "domain_conf.h" diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 6cfe392..32c5edb 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -645,6 +645,12 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, iface_connected = true; if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, &vhostfd) < 0) goto cleanup; + } else if (net->type == VIR_DOMAIN_NET_TYPE_ETHERNET && + !net->data.ethernet.script) + { + if ((tapfd = qemuEthernetIfaceCreate(vm->def, net, priv->qemuCaps)) < 0) + goto cleanup; + iface_connected = true; } if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets+1) < 0) @@ -1881,6 +1887,10 @@ int qemuDomainDetachNetDevice(struct qemud_driver *driver, } #endif + if(detach->type == VIR_DOMAIN_NET_TYPE_ETHERNET && + !detach->data.ethernet.script) + delTap(detach->ifname); + if ((driver->macFilter) && (detach->ifname != NULL)) { if ((errno = networkDisallowMacOnPort(driver, detach->ifname, diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 3baaa19..11e4219 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3392,6 +3392,14 @@ void qemuProcessStop(struct qemud_driver *driver, networkReleaseActualDevice(net); } + def = vm->def; + for(i=0; i < def->nnets; i++) { + virDomainNetDefPtr net = def->nets[i]; + if (net->type == VIR_DOMAIN_NET_TYPE_ETHERNET && + !net->data.ethernet.script) + delTap(net->ifname); + } + retry: if ((ret = qemuRemoveCgroup(driver, vm, 0)) < 0) { if (ret == -EBUSY && (retries++ < 5)) { -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list