
On Fri, Mar 18, 2016 at 10:19:41PM +0000, Vasiliy Tolstov wrote:
If a user specify network type ethernet, then create it via libvirt and run script if it provided. After this commit user does not need to run external script to create tap device or add root permissions to qemu process.
Signed-off-by: Vasiliy Tolstov <v.tolstov@selfip.ru> --- src/qemu/qemu_command.c | 38 ++++++----- src/qemu/qemu_hotplug.c | 36 +++++++++-- src/qemu/qemu_interface.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_interface.h | 5 ++ src/qemu/qemu_process.c | 6 ++ 5 files changed, 221 insertions(+), 22 deletions(-)
diff --git a/src/qemu/qemu_interface.c b/src/qemu/qemu_interface.c index 08af13358113..bab0ff5b2006 100644 --- a/src/qemu/qemu_interface.c +++ b/src/qemu/qemu_interface.c +int +qemuInterfaceEthernetConnect(virDomainDefPtr def, + virQEMUDriverPtr driver, + virDomainNetDefPtr net, + int *tapfd, + size_t tapfdSize) +{ + virMacAddr tapmac; + size_t j; + int ret = -1; + unsigned int tap_create_flags = VIR_NETDEV_TAP_CREATE_IFUP; + bool template_ifname = false; + virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + const char *tunpath = "/dev/net/tun"; + + if (net->backend.tap) { + tunpath = net->backend.tap; + if (!(virQEMUDriverIsPrivileged(driver))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("cannot use custom tap device in session mode")); + goto cleanup; + } + } + + if (!net->ifname || + STRPREFIX(net->ifname, VIR_NET_GENERATED_PREFIX) || + strchr(net->ifname, '%')) { + VIR_FREE(net->ifname); + if (VIR_STRDUP(net->ifname, VIR_NET_GENERATED_PREFIX "%d") < 0) + goto cleanup; + /* avoid exposing vnet%d in getXMLDesc or error outputs */ + template_ifname = true; + } + + if (net->model && STREQ(net->model, "virtio")) + tap_create_flags |= VIR_NETDEV_TAP_CREATE_VNET_HDR; + + if (virNetDevTapCreate(&net->ifname, tunpath, tapfd, tapfdSize, + tap_create_flags) < 0) { + virDomainAuditNetDevice(def, net, tunpath, false); + goto cleanup; + } + + virDomainAuditNetDevice(def, net, tunpath, true); + virMacAddrSet(&tapmac, &net->mac); + tapmac.addr[0] = 0xFE; + + if (virNetDevSetMAC(net->ifname, &tapmac) < 0) + goto cleanup; + + for (j = 0; j < net->nips; j++) { + virDomainNetIpDefPtr ip = net->ips[j]; + unsigned int prefix = (ip->prefix > 0) ? ip->prefix : + VIR_SOCKET_ADDR_DEFAULT_PREFIX; + char *ipStr = virSocketAddrFormat(&ip->address); + + VIR_DEBUG("Adding IP address '%s/%u' to '%s'", + ipStr, ip->prefix, net->ifname); + + if (virNetDevSetIPAddress(net->ifname, &ip->address, &ip->peer, prefix) < 0) { + virReportError(VIR_ERR_SYSTEM_ERROR, + _("Failed to set IP address '%s' on %s"), + ipStr, net->ifname); + VIR_FREE(ipStr); + goto cleanup; + } + VIR_FREE(ipStr); + } + + if (net->linkstate == VIR_DOMAIN_NET_INTERFACE_LINK_STATE_UP || + net->linkstate == VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DEFAULT) { + if (virNetDevSetOnline(net->ifname, true) < 0) + goto cleanup; + + /* Set the routes */ + for (j = 0; j < net->nroutes; j++) { + virNetworkRouteDefPtr route = net->routes[j]; + + if (virNetDevAddRoute(net->ifname, + virNetworkRouteDefGetAddress(route), + virNetworkRouteDefGetPrefix(route), + virNetworkRouteDefGetGateway(route), + virNetworkRouteDefGetMetric(route)) < 0) { + goto cleanup; + } + } + }
This is still doing alot more work than QEMU would do if it crated the TAP device. In particular the adding of IP addresses & routes is not something QEMU would do - this is left for the specified network script todo. We can have a discussion about whether to support setting of routes and IP's on this device, vs inventing a new type of device for this purpose, but that should be in a separate patch. RAther than have you re-post again, I'll commit just this patch with this IP & route stuff removed now. Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|