[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