[libvirt] [PATCH 09/27] conf: introduce virNetworkPortDefPtr struct and XML support
Michal Privoznik
mprivozn at redhat.com
Tue Jan 8 16:15:49 UTC 2019
On 12/24/18 3:58 PM, Daniel P. Berrangé wrote:
> Introduce a virNetworkPortDefPtr struct to represent the data associated
> with a virtual network port. Add APIs for parsing/formatting XML docs
> with the data.
>
> Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
> ---
> src/conf/Makefile.inc.am | 2 +
> src/conf/virnetworkportdef.c | 497 ++++++++++++++++++
> src/conf/virnetworkportdef.h | 112 ++++
> src/libvirt_private.syms | 10 +
> tests/Makefile.am | 7 +
> .../plug-bridge-mactbl.xml | 9 +
> .../virnetworkportxml2xmldata/plug-bridge.xml | 9 +
> .../virnetworkportxml2xmldata/plug-direct.xml | 12 +
> .../plug-hostdev-pci.xml | 12 +
> tests/virnetworkportxml2xmldata/plug-none.xml | 8 +
> tests/virnetworkportxml2xmltest.c | 104 ++++
> 11 files changed, 782 insertions(+)
> create mode 100644 src/conf/virnetworkportdef.c
> create mode 100644 src/conf/virnetworkportdef.h
> create mode 100644 tests/virnetworkportxml2xmldata/plug-bridge-mactbl.xml
> create mode 100644 tests/virnetworkportxml2xmldata/plug-bridge.xml
> create mode 100644 tests/virnetworkportxml2xmldata/plug-direct.xml
> create mode 100644 tests/virnetworkportxml2xmldata/plug-hostdev-pci.xml
> create mode 100644 tests/virnetworkportxml2xmldata/plug-none.xml
> create mode 100644 tests/virnetworkportxml2xmltest.c
>
> diff --git a/src/conf/Makefile.inc.am b/src/conf/Makefile.inc.am
> index 219ff350d7..eec861591f 100644
> --- a/src/conf/Makefile.inc.am
> +++ b/src/conf/Makefile.inc.am
> @@ -5,6 +5,8 @@ NETDEV_CONF_SOURCES = \
> conf/netdev_vport_profile_conf.c \
> conf/netdev_vlan_conf.h \
> conf/netdev_vlan_conf.c \
> + conf/virnetworkportdef.h \
> + conf/virnetworkportdef.c \
> $(NULL)
>
> DOMAIN_CONF_SOURCES = \
> diff --git a/src/conf/virnetworkportdef.c b/src/conf/virnetworkportdef.c
> new file mode 100644
> index 0000000000..12b5f086ab
> --- /dev/null
> +++ b/src/conf/virnetworkportdef.c
> @@ -0,0 +1,497 @@
> +/*
> + * virnetworkportdef.c: network port XML processing
> + *
> + * Copyright (C) 2018 Red Hat, Inc.
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library. If not, see
> + * <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <config.h>
> +
> +#include "viralloc.h"
> +#include "virerror.h"
> +#include "virstring.h"
> +#include "virfile.h"
> +#include "virnetworkportdef.h"
> +#include "network_conf.h"
> +
> +#define VIR_FROM_THIS VIR_FROM_NETWORK
> +
> +VIR_ENUM_IMPL(virNetworkPortPlug, VIR_NETWORK_PORT_PLUG_TYPE_LAST,
> + "none", "bridge", "direct", "hostdev-pci");
> +
> +void
> +virNetworkPortDefFree(virNetworkPortDefPtr def)
> +{
> + if (!def)
> + return;
> +
> + VIR_FREE(def->ownername);
> + VIR_FREE(def->group);
> +
> + virNetDevBandwidthFree(def->bandwidth);
> + virNetDevVlanClear(&def->vlan);
> + VIR_FREE(def->virtPortProfile);
> +
> + switch ((virNetworkPortPlugType)def->plugtype) {
> + case VIR_NETWORK_PORT_PLUG_TYPE_NONE:
> + break;
> +
> + case VIR_NETWORK_PORT_PLUG_TYPE_BRIDGE:
> + VIR_FREE(def->plug.bridge.brname);
> + break;
> +
> + case VIR_NETWORK_PORT_PLUG_TYPE_DIRECT:
> + VIR_FREE(def->plug.direct.linkdev);
> + break;
> +
> + case VIR_NETWORK_PORT_PLUG_TYPE_HOSTDEV_PCI:
> + break;
> +
> + case VIR_NETWORK_PORT_PLUG_TYPE_LAST:
> + default:
> + break;
> + }
> +
> + VIR_FREE(def);
> +}
> +
> +
> +
> +static virNetworkPortDefPtr
> +virNetworkPortDefParseXML(xmlXPathContextPtr ctxt)
> +{
> + virNetworkPortDefPtr def;
> + char *uuid = NULL;
> + xmlNodePtr virtPortNode;
> + xmlNodePtr vlanNode;
> + xmlNodePtr bandwidthNode;
> + xmlNodePtr addressNode;
> + char *trustGuestRxFilters = NULL;
> + char *mac = NULL;
> + char *macmgr = NULL;
> + char *mode = NULL;
> + char *plugtype = NULL;
> + char *managed = NULL;
> + char *driver = NULL;
> +
> + if (VIR_ALLOC(def) < 0)
> + return NULL;
> +
> + uuid = virXPathString("string(./uuid)", ctxt);
> + if (!uuid) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + "%s", _("network port has no uuid"));
> + goto error;
> + }
> + if (virUUIDParse(uuid, def->uuid) < 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("Unable to parse UUID '%s'"), uuid);
> + goto error;
> + }
> +
> + def->ownername = virXPathString("string(./owner/name)", ctxt);
> + if (!def->ownername) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + "%s", _("network port has no owner name"));
> + goto error;
> + }
> +
> + VIR_FREE(uuid);
> + uuid = virXPathString("string(./owner/uuid)", ctxt);
> + if (!uuid) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + "%s", _("network port has no owner UUID"));
> + goto error;
> + }
> +
> + if (virUUIDParse(uuid, def->owneruuid) < 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("Unable to parse UUID '%s'"), uuid);
> + goto error;
> + }
> +
> + def->group = virXPathString("string(./group)", ctxt);
> +
> + virtPortNode = virXPathNode("./virtualport", ctxt);
> + if (virtPortNode &&
> + (!(def->virtPortProfile = virNetDevVPortProfileParse(virtPortNode, 0)))) {
> + goto error;
> + }
> +
> + mac = virXPathString("string(./mac/@address)", ctxt);
> + if (!mac) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + "%s", _("network port has no mac"));
> + goto error;
> + }
> + if (virMacAddrParse(mac, &def->mac) < 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("Unable to parse MAC '%s'"), mac);
> + goto error;
> + }
> +
> + bandwidthNode = virXPathNode("./bandwidth", ctxt);
> + if (bandwidthNode &&
> + virNetDevBandwidthParse(&def->bandwidth, bandwidthNode, -1) < 0)
This must not be -1. The bandwidth corresponds to the interface not the
bridge. If this is -1 then 'floor' is disallowed, which is not what we
want. Maybe we need to change the @net_type argument of
virNetDevBandwidthParse() so that it is bool which allows/denies 'floor'.
> + goto error;
> +
> + vlanNode = virXPathNode("./vlan", ctxt);
> + if (vlanNode && virNetDevVlanParse(vlanNode, ctxt, &def->vlan) < 0)
> + goto error;
> +
> +
> + trustGuestRxFilters
> + = virXPathString("string(./rxfilters/@trustGuest)", ctxt);
> + if (trustGuestRxFilters) {
> + if ((def->trustGuestRxFilters
> + = virTristateBoolTypeFromString(trustGuestRxFilters)) <= 0) {
> + virReportError(VIR_ERR_XML_ERROR,
> + _("Invalid guest rx filters trust setting '%s' "),
> + trustGuestRxFilters);
> + goto error;
> + }
> + }
> +
> + plugtype = virXPathString("string(./plug/@type)", ctxt);
> +
> + if (plugtype &&
> + (def->plugtype = virNetworkPortPlugTypeFromString(plugtype)) < 0) {
> + virReportError(VIR_ERR_XML_ERROR,
> + _("Invalid network prt plug type '%s'"), plugtype);
> + }
> +
> +int
> +virNetworkPortDefFormatBuf(virBufferPtr buf,
> + const virNetworkPortDef *def)
> +{
> + char uuid[VIR_UUID_STRING_BUFLEN];
> + char macaddr[VIR_MAC_STRING_BUFLEN];
> +
> + virBufferAddLit(buf, "<networkport>\n");
> +
> + virBufferAdjustIndent(buf, 2);
> +
> + virUUIDFormat(def->uuid, uuid);
> + virBufferAsprintf(buf, "<uuid>%s</uuid>\n", uuid);
> +
> + virBufferAddLit(buf, "<owner>\n");
> + virBufferAdjustIndent(buf, 2);
> + virBufferEscapeString(buf, "<name>%s</name>\n", def->ownername);
> + virUUIDFormat(def->owneruuid, uuid);
> + virBufferAsprintf(buf, "<uuid>%s</uuid>\n", uuid);
> + virBufferAdjustIndent(buf, -2);
> + virBufferAddLit(buf, "</owner>\n");
> +
> + if (def->group)
> + virBufferEscapeString(buf, "<group>%s</group>\n", def->group);
> +
> + virMacAddrFormat(&def->mac, macaddr);
> + virBufferAsprintf(buf, "<mac address='%s'/>\n", macaddr);
> +
> + if (virNetDevVPortProfileFormat(def->virtPortProfile, buf) < 0)
> + return -1;
> + virNetDevBandwidthFormat(def->bandwidth, buf);
> + if (def->class_id)
> + virBufferAsprintf(buf, "<class id='%u'/>\n", def->class_id);
> + if (virNetDevVlanFormat(&def->vlan, buf) < 0)
> + return -1;
> + if (def->trustGuestRxFilters)
> + virBufferAsprintf(buf, "<rxfilters trustGuest='%s'/>",
Add "\n" here.
> + virTristateBoolTypeToString(def->trustGuestRxFilters));
> +
Michal
More information about the libvir-list
mailing list