[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH 2/2] Modify generic ethernet interface so it will work when sVirt is enabled with qemu



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)) {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]