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).
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)
{
int nForwardIfs, nForwardAddrs, nForwardPfs, nForwardNats;
char *forwardDev = NULL;
char *forwardManaged = NULL;
+ char *forwardDriverName = NULL;
char *type = NULL;
xmlNodePtr save = ctxt->node;
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) {
VIR_FREE(type);
VIR_FREE(forwardDev);
VIR_FREE(forwardManaged);
+ VIR_FREE(forwardDriverName);
VIR_FREE(forwardPfNodes);
VIR_FREE(forwardIfNodes);
VIR_FREE(forwardAddrNodes);
|| 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;
/*
* 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
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 {
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.
} else if (netdef->forward.type == VIR_NETWORK_FORWARD_HOSTDEV) {
+ virDomainHostdevSubsysPciBackendType backend;
+
if (!iface->data.network.actual
&& (VIR_ALLOC(iface->data.network.actual) < 0)) {
virReportOOMError();
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
*/
<name>hostdev</name>
<uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
<forward mode='hostdev' managed='yes'>
+ <driver name='vfio'/>
<pf dev='eth2'/>
</forward>
</network>
<name>hostdev</name>
<uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
<forward mode='hostdev' managed='yes'>
+ <driver name='vfio'/>
<pf dev='eth2'/>
</forward>
</network>