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(a)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 :|