[libvirt] [PATCH 1/2] network: support <driver name='vfio'/> in network definitions

Laine Stump laine at laine.org
Fri Apr 26 22:35:17 UTC 2013


I remembered to document this bit, but somehow forgot to implement it.

This adds <driver name='kvm|vfio'/> as a subelement to the <forward>
element of a network (this puts it parallel to the match between
mode='hostdev' attribute in a network and type='hostdev' in an
<interface>).

Since it's already documented, only the parser, formatter, backend
driver recognition (it just translates/moves the flag into the
<interface> at the appropriate time), and a test case were needed.

(I used a separate enum for the values both because the original is
defined in domain_conf.h, which is unavailable from network_conf.h,
and because in the future it's possible that we may want to support
other non-hostdev oriented driver names in the network parser; this
makes sure that one can be expanded without the other).
---
 src/conf/network_conf.c                | 39 +++++++++++++++++++++++++++++++++-
 src/conf/network_conf.h                | 17 ++++++++++++++-
 src/network/bridge_driver.c            | 23 ++++++++++++++++++++
 tests/networkxml2xmlin/hostdev-pf.xml  |  1 +
 tests/networkxml2xmlout/hostdev-pf.xml |  1 +
 5 files changed, 79 insertions(+), 2 deletions(-)

diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 1c88547..d910a27 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -60,6 +60,12 @@ VIR_ENUM_IMPL(virNetworkForwardHostdevDevice,
               VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_LAST,
               "none", "pci", "netdev")
 
+VIR_ENUM_IMPL(virNetworkForwardDriverName,
+              VIR_NETWORK_FORWARD_DRIVER_NAME_LAST,
+              "default",
+              "kvm",
+              "vfio")
+
 virNetworkObjPtr virNetworkFindByUUID(const virNetworkObjListPtr nets,
                                       const unsigned char *uuid)
 {
@@ -1443,6 +1449,7 @@ virNetworkForwardDefParseXML(const char *networkName,
     int nForwardIfs, nForwardAddrs, nForwardPfs, nForwardNats;
     char *forwardDev = NULL;
     char *forwardManaged = NULL;
+    char *forwardDriverName = NULL;
     char *type = NULL;
     xmlNodePtr save = ctxt->node;
 
@@ -1465,6 +1472,21 @@ virNetworkForwardDefParseXML(const char *networkName,
         def->managed = true;
     }
 
+    forwardDriverName = virXPathString("string(./driver/@name)", ctxt);
+    if (forwardDriverName) {
+        int driverName
+            = virNetworkForwardDriverNameTypeFromString(forwardDriverName);
+
+        if (driverName <= 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Unknown forward <driver name='%s'/> "
+                             "in network %s"),
+                           forwardDriverName, networkName);
+            goto cleanup;
+        }
+        def->driverName = driverName;
+    }
+
     /* bridge and hostdev modes can use a pool of physical interfaces */
     nForwardIfs = virXPathNodeSet("./interface", ctxt, &forwardIfNodes);
     if (nForwardIfs < 0) {
@@ -1646,6 +1668,7 @@ cleanup:
     VIR_FREE(type);
     VIR_FREE(forwardDev);
     VIR_FREE(forwardManaged);
+    VIR_FREE(forwardDriverName);
     VIR_FREE(forwardPfNodes);
     VIR_FREE(forwardIfNodes);
     VIR_FREE(forwardAddrNodes);
@@ -2230,10 +2253,24 @@ virNetworkDefFormatInternal(virBufferPtr buf,
                          || VIR_SOCKET_ADDR_VALID(&def->forward.addr.start)
                          || VIR_SOCKET_ADDR_VALID(&def->forward.addr.end)
                          || def->forward.port.start
-                         || def->forward.port.end);
+                         || def->forward.port.end
+                         || (def->forward.driverName
+                             != VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT));
         virBufferAsprintf(buf, "%s>\n", shortforward ? "/" : "");
         virBufferAdjustIndent(buf, 2);
 
+        if (def->forward.driverName
+            != VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT) {
+            const char *driverName
+                = virNetworkForwardDriverNameTypeToString(def->forward.driverName);
+            if (!driverName) {
+                virReportError(VIR_ERR_INTERNAL_ERROR,
+                               _("unexpected hostdev driver name type %d "),
+                               def->forward.driverName);
+                goto error;
+            }
+            virBufferAsprintf(buf, "<driver name='%s'/>\n", driverName);
+        }
         if (def->forward.type == VIR_NETWORK_FORWARD_NAT) {
             if (virNetworkForwardNatDefFormat(buf, &def->forward) < 0)
                 goto error;
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index 163478c..e187f05 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -1,7 +1,7 @@
 /*
  * network_conf.h: network XML handling
  *
- * Copyright (C) 2006-2008, 2012 Red Hat, Inc.
+ * Copyright (C) 2006-2013 Red Hat, Inc.
  * Copyright (C) 2006-2008 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -62,6 +62,20 @@ enum virNetworkForwardHostdevDeviceType {
     VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_LAST,
 };
 
+/* The backend driver used for devices from the pool. Currently used
+ * only for PCI devices (vfio vs. kvm), but could be used for other
+ * device types in the future.
+ */
+typedef enum {
+    VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT, /* kvm now, could change */
+    VIR_NETWORK_FORWARD_DRIVER_NAME_KVM,    /* force legacy kvm style */
+    VIR_NETWORK_FORWARD_DRIVER_NAME_VFIO,   /* force vfio */
+
+    VIR_NETWORK_FORWARD_DRIVER_NAME_LAST
+} virNetworkForwardDriverNameType;
+
+VIR_ENUM_DECL(virNetworkForwardDriverName)
+
 typedef struct _virNetworkDHCPHostDef virNetworkDHCPHostDef;
 typedef virNetworkDHCPHostDef *virNetworkDHCPHostDefPtr;
 struct _virNetworkDHCPHostDef {
@@ -159,6 +173,7 @@ typedef virNetworkForwardDef *virNetworkForwardDefPtr;
 struct _virNetworkForwardDef {
     int type;     /* One of virNetworkForwardType constants */
     bool managed;  /* managed attribute for hostdev mode */
+    int driverName; /* enum virNetworkForwardDriverNameType */
 
     /* If there are multiple forward devices (i.e. a pool of
      * interfaces), they will be listed here.
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 20d1cb0..0c0b356 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -3859,6 +3859,8 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
 
     } else if (netdef->forward.type == VIR_NETWORK_FORWARD_HOSTDEV) {
 
+        virDomainHostdevSubsysPciBackendType backend;
+
         if (!iface->data.network.actual
             && (VIR_ALLOC(iface->data.network.actual) < 0)) {
             virReportOOMError();
@@ -3893,6 +3895,27 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
         iface->data.network.actual->data.hostdev.def.source.subsys.type = dev->type;
         iface->data.network.actual->data.hostdev.def.source.subsys.u.pci.addr = dev->device.pci;
 
+        switch (netdef->forward.driverName)
+        {
+        case VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT:
+            backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_DEFAULT;
+            break;
+        case VIR_NETWORK_FORWARD_DRIVER_NAME_KVM:
+            backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_KVM;
+            break;
+        case VIR_NETWORK_FORWARD_DRIVER_NAME_VFIO:
+            backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_TYPE_VFIO;
+            break;
+        default:
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("unrecognized driver name value %d "
+                             " in network '%s'"),
+                           netdef->forward.driverName, netdef->name);
+            goto error;
+        }
+        iface->data.network.actual->data.hostdev.def.source.subsys.u.pci.backend
+            = backend;
+
         /* merge virtualports from interface, network, and portgroup to
          * arrive at actual virtualport to use
          */
diff --git a/tests/networkxml2xmlin/hostdev-pf.xml b/tests/networkxml2xmlin/hostdev-pf.xml
index 7bf857d..5b8f598 100644
--- a/tests/networkxml2xmlin/hostdev-pf.xml
+++ b/tests/networkxml2xmlin/hostdev-pf.xml
@@ -2,6 +2,7 @@
   <name>hostdev</name>
   <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
   <forward mode='hostdev' managed='yes'>
+    <driver name='vfio'/>
     <pf dev='eth2'/>
   </forward>
 </network>
diff --git a/tests/networkxml2xmlout/hostdev-pf.xml b/tests/networkxml2xmlout/hostdev-pf.xml
index 7bf857d..5b8f598 100644
--- a/tests/networkxml2xmlout/hostdev-pf.xml
+++ b/tests/networkxml2xmlout/hostdev-pf.xml
@@ -2,6 +2,7 @@
   <name>hostdev</name>
   <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
   <forward mode='hostdev' managed='yes'>
+    <driver name='vfio'/>
     <pf dev='eth2'/>
   </forward>
 </network>
-- 
1.7.11.7




More information about the libvir-list mailing list