From b01b53de3f0694c1fe3038c89fd173dcdb188549 Mon Sep 17 00:00:00 2001 From: Shradha Shah Date: Wed, 14 Dec 2011 10:50:23 +0000 Subject: [PATCH] Adding the element pf to network xml. This element will help the user to just specify the SR-IOV physical function in order to access all the Virtual functions attached to it. --- docs/formatnetwork.html.in | 18 ++++- docs/schemas/network.rng | 23 +++++-- src/conf/network_conf.c | 76 ++++++++++++++++++---- src/conf/network_conf.h | 5 +- tests/networkxml2xmlin/passthrough-pf.xml | 10 +++ tests/networkxml2xmlout/passthrough-pf.xml | 9 +++ 6 files changed, 117 insertions(+), 24 deletions(-) create mode 100644 tests/networkxml2xmlin/passthrough-pf.xml create mode 100644 tests/networkxml2xmlout/passthrough-pf.xml diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in index 755d51098b..907c046765 100644 --- a/docs/formatnetwork.html.in +++ b/docs/formatnetwork.html.in @@ -226,7 +226,21 @@ </forward> ... - When a guest interface is being constructed, libvirt will pick + Additionally, since 0.9.10, libvirt + allows a shorthand for specifying all virtual interfaces + associated with a single physical function, by using + the <pf> subelement to call out the + corresponding physical interface associated with multiple + virtual interfaces: +
+...
+  <forward mode='passthrough'>
+    <pf dev='eth0'/>
+  </forward>
+...
+        
+ +

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 @@ -234,7 +248,7 @@ 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.

Quality of service
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng index 5d58fe4021..6e1002f1b5 100644 --- a/docs/schemas/network.rng +++ b/docs/schemas/network.rng @@ -85,13 +85,22 @@ - - - - - - - + + + + + + + + + + + + + + + + diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index 347954374c..c3c70052d4 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -1,7 +1,7 @@ /* * 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 @@ -162,6 +162,11 @@ void virNetworkDefFree(virNetworkDefPtr def) 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]); } @@ -929,10 +934,11 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) 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; @@ -1074,10 +1080,44 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) /* all of these modes can use a pool of physical interfaces */ nForwardIfs = virXPathNodeSet("./interface", ctxt, &forwardIfNodes); - if (nForwardIfs < 0) - goto error; + nForwardPfs = virXPathNodeSet("./pf", ctxt, &forwardPfNodes); - if ((nForwardIfs > 0) || forwardDev) { + 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; + } + + 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 */ @@ -1123,6 +1163,8 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) def->nForwardIfs++; } } + VIR_FREE(forwardDev); + VIR_FREE(forwardPfNodes); VIR_FREE(forwardIfNodes); switch (def->forwardType) { @@ -1178,6 +1220,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt) VIR_FREE(ipNodes); VIR_FREE(portGroupNodes); VIR_FREE(forwardIfNodes); + VIR_FREE(forwardPfNodes); VIR_FREE(forwardDev); ctxt->node = save; return NULL; @@ -1420,7 +1463,9 @@ char *virNetworkDefFormat(const virNetworkDefPtr def) virBufferAsprintf(&buf, " %s\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) { @@ -1430,20 +1475,23 @@ char *virNetworkDefFormat(const virNetworkDefPtr def) goto error; } virBufferAddLit(&buf, " \n", mode, - def->nForwardIfs ? "" : "/"); + (def->nForwardIfs || def->nForwardPfs) ? "" : "/"); + + /* For now, hard-coded to at most 1 forwardPfs */ + if (def->nForwardPfs) + virBufferEscapeString(&buf, " \n", + def->forwardPfs[0].dev); if (def->nForwardIfs) { for (ii = 0; ii < def->nForwardIfs; ii++) { - if (def->forwardIfs[ii].dev) { - virBufferEscapeString(&buf, " \n", - def->forwardIfs[ii].dev); - } + virBufferEscapeString(&buf, " \n", + def->forwardIfs[ii].dev); } - virBufferAddLit(&buf, " \n"); } + if (def->nForwardPfs || def->nForwardIfs) + virBufferAddLit(&buf, " \n"); } if (def->forwardType == VIR_NETWORK_FORWARD_NONE || diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index 8920e18104..0bcd3bf469 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 Red Hat, Inc. + * Copyright (C) 2006-2008, 2012 Red Hat, Inc. * Copyright (C) 2006-2008 Daniel P. Berrange * * This library is free software; you can redistribute it and/or @@ -162,6 +162,9 @@ struct _virNetworkDef { /* If there are multiple forward devices (i.e. a pool of * interfaces), they will be listed here. */ + size_t nForwardPfs; + virNetworkForwardIfDefPtr forwardPfs; + size_t nForwardIfs; virNetworkForwardIfDefPtr forwardIfs; diff --git a/tests/networkxml2xmlin/passthrough-pf.xml b/tests/networkxml2xmlin/passthrough-pf.xml new file mode 100644 index 0000000000..e63aae0507 --- /dev/null +++ b/tests/networkxml2xmlin/passthrough-pf.xml @@ -0,0 +1,10 @@ + + local + 81ff0d90-c91e-6742-64da-4a736edb9a9b + + + + + + + diff --git a/tests/networkxml2xmlout/passthrough-pf.xml b/tests/networkxml2xmlout/passthrough-pf.xml new file mode 100644 index 0000000000..1a7e71ea88 --- /dev/null +++ b/tests/networkxml2xmlout/passthrough-pf.xml @@ -0,0 +1,9 @@ + + local + 81ff0d90-c91e-6742-64da-4a736edb9a9b + + + + + +