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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list