</forward>
...
</pre>
- When a guest interface is being constructed, libvirt will pick
+ Additionally, <span class="since">since 0.9.10</span>, libvirt
+ allows a shorthand for specifying all virtual interfaces
+ associated with a single physical function, by using
+ the <code><pf></code> subelement to call out the
+ corresponding physical interface associated with multiple
+ virtual interfaces:
+ <pre>
+...
+ <forward mode='passthrough'>
+ <pf dev='eth0'/>
+ </forward>
+...
+ </pre>
+
+ <p>When a guest interface is being constructed, libvirt will pick
an interface from this list to use for the connection. In
modes where physical interfaces can be shared by multiple
guest interfaces, libvirt will choose the interface that
that do not allow sharing of the physical device (in
particular, 'passthrough' mode, and 'private' mode when using
802.1Qbh), libvirt will choose an unused physical interface
- or, if it can't find an unused interface, fail the operation.
+ or, if it can't find an unused interface, fail the operation.</p>
</dd>
</dl>
<h5><a name="elementQoS">Quality of service</a></h5>
/*
* network_conf.c: network XML handling
*
- * Copyright (C) 2006-2011 Red Hat, Inc.
+ * Copyright (C) 2006-2012 Red Hat, Inc.
* Copyright (C) 2006-2008 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
VIR_FREE(def->bridge);
VIR_FREE(def->domain);
+ for (ii = 0 ; ii < def->nForwardPfs && def->forwardPfs ; ii++) {
+ virNetworkForwardIfDefClear(&def->forwardPfs[ii]);
+ }
+ VIR_FREE(def->forwardPfs);
+
for (ii = 0 ; ii < def->nForwardIfs && def->forwardIfs ; ii++) {
virNetworkForwardIfDefClear(&def->forwardIfs[ii]);
}
xmlNodePtr *ipNodes = NULL;
xmlNodePtr *portGroupNodes = NULL;
xmlNodePtr *forwardIfNodes = NULL;
+ xmlNodePtr *forwardPfNodes = NULL;
xmlNodePtr dnsNode = NULL;
xmlNodePtr virtPortNode = NULL;
xmlNodePtr forwardNode = NULL;
- int nIps, nPortGroups, nForwardIfs;
+ int nIps, nPortGroups, nForwardIfs, nForwardPfs;
char *forwardDev = NULL;
xmlNodePtr save = ctxt->node;
xmlNodePtr bandwidthNode = NULL;
/* all of these modes can use a pool of physical interfaces */
nForwardIfs = virXPathNodeSet("./interface", ctxt, &forwardIfNodes);
- if (nForwardIfs < 0)
+ nForwardPfs = virXPathNodeSet("./pf", ctxt, &forwardPfNodes);
+
+ if (nForwardIfs < 0 || nForwardPfs < 0) {
+ virNetworkReportError(VIR_ERR_XML_ERROR,
+ _("No interface pool or SRIOV physical device given"));
goto error;
+ }
+
+ if (nForwardPfs == 1) {
+ if (VIR_ALLOC_N(def->forwardPfs, nForwardPfs) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+
+ if (forwardDev) {
+ virNetworkReportError(VIR_ERR_XML_ERROR,
+ _("A forward Dev should not be used when using a SRIOV PF"));
+ goto error;
+ }
- if ((nForwardIfs > 0) || forwardDev) {
+ forwardDev = virXMLPropString(*forwardPfNodes, "dev");
+ if (!forwardDev) {
+ virNetworkReportError(VIR_ERR_XML_ERROR,
+ _("Missing required dev attribute in network '%s' pf element"),
+ def->name);
+ goto error;
+ }
+
+ def->forwardPfs->usageCount = 0;
+ def->forwardPfs->dev = forwardDev;
+ forwardDev = NULL;
+ def->nForwardPfs++;
+ } else if (nForwardPfs > 1) {
+ virNetworkReportError(VIR_ERR_XML_ERROR,
+ _("Use of more than one physical interface is not allowed"));
+ goto error;
+ }
+ if (nForwardIfs > 0 || forwardDev) {
int ii;
/* allocate array to hold all the portgroups */
def->nForwardIfs++;
}
}
+ VIR_FREE(forwardDev);
+ VIR_FREE(forwardPfNodes);
VIR_FREE(forwardIfNodes);
switch (def->forwardType) {
VIR_FREE(ipNodes);
VIR_FREE(portGroupNodes);
VIR_FREE(forwardIfNodes);
+ VIR_FREE(forwardPfNodes);
VIR_FREE(forwardDev);
ctxt->node = save;
return NULL;
virBufferAsprintf(&buf, " <uuid>%s</uuid>\n", uuidstr);
if (def->forwardType != VIR_NETWORK_FORWARD_NONE) {
- const char *dev = virNetworkDefForwardIf(def, 0);
+ const char *dev = NULL;
+ if (!def->nForwardPfs)
+ dev = virNetworkDefForwardIf(def, 0);
const char *mode = virNetworkForwardTypeToString(def->forwardType);
if (!mode) {
goto error;
}
virBufferAddLit(&buf, " <forward");
- if (dev)
- virBufferEscapeString(&buf, " dev='%s'", dev);
+ virBufferEscapeString(&buf, " dev='%s'", dev);
virBufferAsprintf(&buf, " mode='%s'%s>\n", mode,
- def->nForwardIfs ? "" : "/");
+ (def->nForwardIfs || def->nForwardPfs) ? "" : "/");
+
+ /* For now, hard-coded to at most 1 forwardPfs */
+ if (def->nForwardPfs)
+ virBufferEscapeString(&buf, " <pf dev='%s'/>\n",
+ def->forwardPfs[0].dev);
if (def->nForwardIfs) {
for (ii = 0; ii < def->nForwardIfs; ii++) {
- if (def->forwardIfs[ii].dev) {
- virBufferEscapeString(&buf, " <interface dev='%s'/>\n",
- def->forwardIfs[ii].dev);
- }
+ virBufferEscapeString(&buf, " <interface dev='%s'/>\n",
+ def->forwardIfs[ii].dev);
}
- virBufferAddLit(&buf, " </forward>\n");
}
+ if (def->nForwardPfs || def->nForwardIfs)
+ virBufferAddLit(&buf, " </forward>\n");
}
if (def->forwardType == VIR_NETWORK_FORWARD_NONE ||