On 09/20/2011 05:18 PM, Tyler Coumbes wrote:
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.
This patch doesn't refactor src/util/bridge.c either, which means that if applied, we would have two copies of very similar code in two different files - that's a maintenance nightmare. We'll definitely need a v2 patch series that refactors things with minimal duplication.
Or, can this patch directly use the existing br* interfaces, instead of introducing a new file in patch 1/2?
--- 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;
This leaks tapfd. Our style tends to use 'goto error' to ensure that all cleanup occurs at the end, rather than 'return' in the middle of a function.
+ + err = tapSetInterfaceUp(net->ifname, 1); + + if (err) + return -1; + + return tapfd; +} + + static int qemuDomainDeviceAliasIndex(virDomainDeviceInfoPtr info, const char *prefix) @@ -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);
Check for failure to transfer the fd, and abort the command in that case (hmm, that's a pre-existing problem with the other fd transfers in this function).
-- Eric Blake eblake@xxxxxxxxxx +1-801-349-2682 Libvirt virtualization library http://libvirt.org -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list