From nobody Sun Feb 8 05:58:59 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1555521616; cv=none; d=zoho.com; s=zohoarc; b=ZRnQLOXqWss8jZY2aEtrCxgqQTdL53VzTk0nTxQPnnvqB5nbUZEb8IFWDJ2ekId0DQD5cpGeFvgfDerbYXahu8hErdIae9oUbLHKplXo2EbJEAclioDtUomUzJS5V3fWLmXvg8/xjfv0/Ry9zZv0FfRIITnMifTU2axn+xAnqtA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1555521616; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=xzbpFhuJ8h31MLVCdsQNBGTEA32rB/VX75A5LInCo74=; b=XlY+pWc2qSHWr7+rajZ55fpE1/gfmAQAifQnnClvCsqPivWYG5mxtlH9vuZZ/J5fOsbC/p3xWDmDbAVNddOBwbueye2lnkrb5xj7QvcuIwhBRx93GSuDKPGcmd7YtXc9lbbB1yf1stkhIsnccdADP+J3++5kEXvpLL9NA2Z44aw= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1555521616672487.5375514996691; Wed, 17 Apr 2019 10:20:16 -0700 (PDT) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id CB00959464; Wed, 17 Apr 2019 17:20:14 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id A809B5DA2E; Wed, 17 Apr 2019 17:20:14 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 6BD1B181B9EF; Wed, 17 Apr 2019 17:20:14 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x3HHJtFg030576 for ; Wed, 17 Apr 2019 13:19:55 -0400 Received: by smtp.corp.redhat.com (Postfix) id 52DFD5D71B; Wed, 17 Apr 2019 17:19:55 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-112-35.ams2.redhat.com [10.36.112.35]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6BDC65D6A6; Wed, 17 Apr 2019 17:19:53 +0000 (UTC) From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: libvir-list@redhat.com Date: Wed, 17 Apr 2019 18:19:08 +0100 Message-Id: <20190417171929.9399-9-berrange@redhat.com> In-Reply-To: <20190417171929.9399-1-berrange@redhat.com> References: <20190417171929.9399-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-loop: libvir-list@redhat.com Cc: Laine Stump Subject: [libvirt] [PATCH v4 08/29] conf: introduce virNetworkPortDefPtr struct and XML support X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Wed, 17 Apr 2019 17:20:15 +0000 (UTC) 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=C3=A9 --- src/conf/Makefile.inc.am | 2 + src/conf/virnetworkportdef.c | 515 ++++++++++++++++++ src/conf/virnetworkportdef.h | 112 ++++ src/libvirt_private.syms | 10 + tests/Makefile.am | 7 + .../plug-bridge-mactbl.xml | 9 + .../virnetworkportxml2xmldata/plug-bridge.xml | 12 + .../virnetworkportxml2xmldata/plug-direct.xml | 12 + .../plug-hostdev-pci.xml | 12 + tests/virnetworkportxml2xmldata/plug-none.xml | 8 + tests/virnetworkportxml2xmltest.c | 104 ++++ 11 files changed, 803 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 3e9fdd1aea..6b52ba674b 100644 --- a/src/conf/Makefile.inc.am +++ b/src/conf/Makefile.inc.am @@ -7,6 +7,8 @@ NETDEV_CONF_SOURCES =3D \ conf/netdev_vport_profile_conf.c \ conf/netdev_vlan_conf.h \ conf/netdev_vlan_conf.c \ + conf/virnetworkportdef.h \ + conf/virnetworkportdef.c \ $(NULL) =20 DOMAIN_CONF_SOURCES =3D \ diff --git a/src/conf/virnetworkportdef.c b/src/conf/virnetworkportdef.c new file mode 100644 index 0000000000..0c2bb988f3 --- /dev/null +++ b/src/conf/virnetworkportdef.c @@ -0,0 +1,515 @@ +/* + * 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 + * . + */ + +#include + +#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 =3D NULL; + xmlNodePtr virtPortNode; + xmlNodePtr vlanNode; + xmlNodePtr bandwidthNode; + xmlNodePtr addressNode; + char *trustGuestRxFilters =3D NULL; + char *mac =3D NULL; + char *macmgr =3D NULL; + char *mode =3D NULL; + char *plugtype =3D NULL; + char *managed =3D NULL; + char *driver =3D NULL; + char *class_id =3D NULL; + + if (VIR_ALLOC(def) < 0) + return NULL; + + uuid =3D 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 =3D 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 =3D 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 =3D virXPathString("string(./group)", ctxt); + + virtPortNode =3D virXPathNode("./virtualport", ctxt); + if (virtPortNode && + (!(def->virtPortProfile =3D virNetDevVPortProfileParse(virtPortNod= e, 0)))) { + goto error; + } + + mac =3D 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; + } + + class_id =3D virXPathString("string(./class/@id)", ctxt); + if (class_id && + virStrToLong_ui(class_id, NULL, 10, &def->class_id) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to parse class id '%s'"), + class_id); + goto error; + } + + bandwidthNode =3D virXPathNode("./bandwidth", ctxt); + /* + * We don't know if the port will allow the "floor" param or + * not at this stage, so we must just tell virNetDevBandwidthParse + * to allow it regardless. Any bad config must be reported at + * time of use instead. + */ + if (bandwidthNode && + virNetDevBandwidthParse(&def->bandwidth, bandwidthNode, true) < 0) + goto error; + + vlanNode =3D virXPathNode("./vlan", ctxt); + if (vlanNode && virNetDevVlanParse(vlanNode, ctxt, &def->vlan) < 0) + goto error; + + + trustGuestRxFilters + =3D virXPathString("string(./rxfilters/@trustGuest)", ctxt); + if (trustGuestRxFilters) { + if ((def->trustGuestRxFilters + =3D virTristateBoolTypeFromString(trustGuestRxFilters)) <=3D = 0) { + virReportError(VIR_ERR_XML_ERROR, + _("Invalid guest rx filters trust setting '%s' = "), + trustGuestRxFilters); + goto error; + } + } + + plugtype =3D virXPathString("string(./plug/@type)", ctxt); + + if (plugtype && + (def->plugtype =3D virNetworkPortPlugTypeFromString(plugtype)) < 0= ) { + virReportError(VIR_ERR_XML_ERROR, + _("Invalid network prt plug type '%s'"), plugtype); + } + + switch (def->plugtype) { + case VIR_NETWORK_PORT_PLUG_TYPE_NONE: + break; + + case VIR_NETWORK_PORT_PLUG_TYPE_BRIDGE: + if (!(def->plug.bridge.brname =3D virXPathString("string(./plug/@b= ridge)", ctxt))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing network port bridge name")); + goto error; + } + macmgr =3D virXPathString("string(./plug/@macTableManager)", ctxt); + if (macmgr && + (def->plug.bridge.macTableManager =3D + virNetworkBridgeMACTableManagerTypeFromString(macmgr)) <=3D 0= ) { + virReportError(VIR_ERR_XML_ERROR, + _("Invalid macTableManager setting '%s' " + "in network port"), macmgr); + goto error; + } + break; + + case VIR_NETWORK_PORT_PLUG_TYPE_DIRECT: + if (!(def->plug.direct.linkdev =3D virXPathString("string(./plug/@= dev)", ctxt))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing network port link device name")); + goto error; + } + mode =3D virXPathString("string(./plug/@mode)", ctxt); + if (mode && + (def->plug.direct.mode =3D + virNetDevMacVLanModeTypeFromString(mode)) < 0) { + virReportError(VIR_ERR_XML_ERROR, + _("Invalid mode setting '%s' in network port"),= mode); + goto error; + } + break; + + case VIR_NETWORK_PORT_PLUG_TYPE_HOSTDEV_PCI: + managed =3D virXPathString("string(./plug/@managed)", ctxt); + if (managed && + (def->plug.hostdevpci.managed =3D + virTristateBoolTypeFromString(managed)) < 0) { + virReportError(VIR_ERR_XML_ERROR, + _("Invalid managed setting '%s' in network port= "), mode); + goto error; + } + driver =3D virXPathString("string(./plug/driver/@name)", ctxt); + if (driver && + (def->plug.hostdevpci.driver =3D + virNetworkForwardDriverNameTypeFromString(driver)) <=3D 0) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing network port driver name")); + goto error; + } + if (!(addressNode =3D virXPathNode("./plug/address", ctxt))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing network port PCI address")); + goto error; + } + + if (virPCIDeviceAddressParseXML(addressNode, &def->plug.hostdevpci= .addr) < 0) + goto error; + break; + + case VIR_NETWORK_PORT_PLUG_TYPE_LAST: + default: + virReportEnumRangeError(virNetworkPortPlugType, def->plugtype); + goto error; + } + + cleanup: + VIR_FREE(class_id); + VIR_FREE(uuid); + VIR_FREE(plugtype); + VIR_FREE(mac); + VIR_FREE(mode); + VIR_FREE(macmgr); + VIR_FREE(driver); + VIR_FREE(managed); + return def; + + error: + virNetworkPortDefFree(def); + def =3D NULL; + goto cleanup; +} + + +virNetworkPortDefPtr +virNetworkPortDefParseNode(xmlDocPtr xml, + xmlNodePtr root) +{ + xmlXPathContextPtr ctxt =3D NULL; + virNetworkPortDefPtr def =3D NULL; + + if (STRNEQ((const char *)root->name, "networkport")) { + virReportError(VIR_ERR_XML_ERROR, + "%s", + _("unknown root element for network port")); + goto cleanup; + } + + ctxt =3D xmlXPathNewContext(xml); + if (ctxt =3D=3D NULL) { + virReportOOMError(); + goto cleanup; + } + + ctxt->node =3D root; + def =3D virNetworkPortDefParseXML(ctxt); + + cleanup: + xmlXPathFreeContext(ctxt); + return def; +} + + +static virNetworkPortDefPtr +virNetworkPortDefParse(const char *xmlStr, + const char *filename) +{ + virNetworkPortDefPtr def =3D NULL; + xmlDocPtr xml; + + if ((xml =3D virXMLParse(filename, xmlStr, _("(networkport_definition)= ")))) { + def =3D virNetworkPortDefParseNode(xml, xmlDocGetRootElement(xml)); + xmlFreeDoc(xml); + } + + return def; +} + + +virNetworkPortDefPtr +virNetworkPortDefParseString(const char *xmlStr) +{ + return virNetworkPortDefParse(xmlStr, NULL); +} + + +virNetworkPortDefPtr +virNetworkPortDefParseFile(const char *filename) +{ + return virNetworkPortDefParse(NULL, filename); +} + + +char * +virNetworkPortDefFormat(const virNetworkPortDef *def) +{ + virBuffer buf =3D VIR_BUFFER_INITIALIZER; + + if (virNetworkPortDefFormatBuf(&buf, def) < 0) { + virBufferFreeAndReset(&buf); + return NULL; + } + + if (virBufferCheckError(&buf) < 0) + return NULL; + + return virBufferContentAndReset(&buf); +} + + +int +virNetworkPortDefFormatBuf(virBufferPtr buf, + const virNetworkPortDef *def) +{ + char uuid[VIR_UUID_STRING_BUFLEN]; + char macaddr[VIR_MAC_STRING_BUFLEN]; + + virBufferAddLit(buf, "\n"); + + virBufferAdjustIndent(buf, 2); + + virUUIDFormat(def->uuid, uuid); + virBufferAsprintf(buf, "%s\n", uuid); + + virBufferAddLit(buf, "\n"); + virBufferAdjustIndent(buf, 2); + virBufferEscapeString(buf, "%s\n", def->ownername); + virUUIDFormat(def->owneruuid, uuid); + virBufferAsprintf(buf, "%s\n", uuid); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n"); + + if (def->group) + virBufferEscapeString(buf, "%s\n", def->group); + + virMacAddrFormat(&def->mac, macaddr); + virBufferAsprintf(buf, "\n", macaddr); + + if (virNetDevVPortProfileFormat(def->virtPortProfile, buf) < 0) + return -1; + virNetDevBandwidthFormat(def->bandwidth, buf); + if (def->class_id) + virBufferAsprintf(buf, "\n", def->class_id); + if (virNetDevVlanFormat(&def->vlan, buf) < 0) + return -1; + if (def->trustGuestRxFilters) + virBufferAsprintf(buf, "\n", + virTristateBoolTypeToString(def->trustGuestRxFil= ters)); + + if (def->plugtype !=3D VIR_NETWORK_PORT_PLUG_TYPE_NONE) { + virBufferAsprintf(buf, "plugtype)); + + switch (def->plugtype) { + case VIR_NETWORK_PORT_PLUG_TYPE_NONE: + break; + + case VIR_NETWORK_PORT_PLUG_TYPE_BRIDGE: + virBufferEscapeString(buf, " bridge=3D'%s'", def->plug.bridge.= brname); + if (def->plug.bridge.macTableManager) + virBufferAsprintf(buf, " macTableManager=3D'%s'", + virNetworkBridgeMACTableManagerTypeToStr= ing( + def->plug.bridge.macTableManager)); + virBufferAddLit(buf, "/>\n"); + break; + + case VIR_NETWORK_PORT_PLUG_TYPE_DIRECT: + virBufferEscapeString(buf, " dev=3D'%s'", def->plug.direct.lin= kdev); + virBufferAsprintf(buf, " mode=3D'%s'", + virNetDevMacVLanModeTypeToString( + def->plug.direct.mode)); + virBufferAddLit(buf, "/>\n"); + break; + + case VIR_NETWORK_PORT_PLUG_TYPE_HOSTDEV_PCI: + virBufferAsprintf(buf, " managed=3D'%s'>\n", + def->plug.hostdevpci.managed ? "yes" : "no"); + virBufferAdjustIndent(buf, 2); + if (def->plug.hostdevpci.driver) + virBufferEscapeString(buf, "\n", + virNetworkForwardDriverNameTypeToStr= ing( + def->plug.hostdevpci.driver)); + + virPCIDeviceAddressFormat(buf, def->plug.hostdevpci.addr, fals= e); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n"); + break; + + case VIR_NETWORK_PORT_PLUG_TYPE_LAST: + default: + virReportEnumRangeError(virNetworkPortPlugType, def->plugtype); + return -1; + } + } + + + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n"); + + return 0; +} + + +static char * +virNetworkPortDefConfigFile(const char *dir, + const char *name) +{ + char *ret =3D NULL; + + ignore_value(virAsprintf(&ret, "%s/%s.xml", dir, name)); + return ret; +} + + +int +virNetworkPortDefSaveStatus(virNetworkPortDef *def, + const char *dir) +{ + char uuidstr[VIR_UUID_STRING_BUFLEN]; + char *path; + char *xml =3D NULL; + int ret =3D -1; + + virUUIDFormat(def->uuid, uuidstr); + + if (virFileMakePath(dir) < 0) + goto cleanup; + + if (!(path =3D virNetworkPortDefConfigFile(dir, uuidstr))) + goto cleanup; + + if (!(xml =3D virNetworkPortDefFormat(def))) + goto cleanup; + + if (virXMLSaveFile(path, uuidstr, "net-port-create", xml) < 0) + goto cleanup; + + ret =3D 0; + cleanup: + VIR_FREE(xml); + VIR_FREE(path); + return ret; +} + + +int +virNetworkPortDefDeleteStatus(virNetworkPortDef *def, + const char *dir) +{ + char uuidstr[VIR_UUID_STRING_BUFLEN]; + char *path; + int ret =3D -1; + + virUUIDFormat(def->uuid, uuidstr); + + if (!(path =3D virNetworkPortDefConfigFile(dir, uuidstr))) + goto cleanup; + + if (unlink(path) < 0 && errno !=3D ENOENT) { + virReportSystemError(errno, + _("Unable to delete %s"), path); + goto cleanup; + } + + ret =3D 0; + cleanup: + VIR_FREE(path); + return ret; +} diff --git a/src/conf/virnetworkportdef.h b/src/conf/virnetworkportdef.h new file mode 100644 index 0000000000..3897013a86 --- /dev/null +++ b/src/conf/virnetworkportdef.h @@ -0,0 +1,112 @@ +/* + * virnetworkportdef.h: 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 + * . + * + */ + +#ifndef LIBVIRT_VIRNETWORKPORTDEF_H +# define LIBVIRT_VIRNETWORKPORTDEF_H + +# include "internal.h" +# include "viruuid.h" +# include "virnetdevvlan.h" +# include "virnetdevvportprofile.h" +# include "virnetdevbandwidth.h" +# include "virpci.h" +# include "virxml.h" +# include "netdev_vport_profile_conf.h" +# include "netdev_bandwidth_conf.h" +# include "netdev_vlan_conf.h" + +typedef struct _virNetworkPortDef virNetworkPortDef; +typedef virNetworkPortDef *virNetworkPortDefPtr; + +typedef enum { + VIR_NETWORK_PORT_PLUG_TYPE_NONE, + VIR_NETWORK_PORT_PLUG_TYPE_BRIDGE, + VIR_NETWORK_PORT_PLUG_TYPE_DIRECT, + VIR_NETWORK_PORT_PLUG_TYPE_HOSTDEV_PCI, + + VIR_NETWORK_PORT_PLUG_TYPE_LAST, +} virNetworkPortPlugType; + +VIR_ENUM_DECL(virNetworkPortPlug); + +struct _virNetworkPortDef { + unsigned char uuid[VIR_UUID_BUFLEN]; + char *ownername; + unsigned char owneruuid[VIR_UUID_BUFLEN]; + + char *group; + virMacAddr mac; + + virNetDevVPortProfilePtr virtPortProfile; + virNetDevBandwidthPtr bandwidth; + unsigned int class_id; /* class ID for bandwidth 'floor' */ + virNetDevVlan vlan; + int trustGuestRxFilters; /* enum virTristateBool */ + + int plugtype; /* virNetworkPortPlugType */ + union { + struct { + char *brname; + int macTableManager; /* enum virNetworkBridgeMACTableManagerTy= pe */ + } bridge; + struct { + char *linkdev; + int mode; /* enum virMacvtapMode from util/macvtap.h */ + } direct; + struct { + virPCIDeviceAddress addr; /* PCI Address of device */ + int driver; /* virNetworkForwardDriverNameType */ + int managed; + } hostdevpci; + } plug; +}; + + +void +virNetworkPortDefFree(virNetworkPortDefPtr port); + +virNetworkPortDefPtr +virNetworkPortDefParseNode(xmlDocPtr xml, + xmlNodePtr root); + +virNetworkPortDefPtr +virNetworkPortDefParseString(const char *xml); + +virNetworkPortDefPtr +virNetworkPortDefParseFile(const char *filename); + +char * +virNetworkPortDefFormat(const virNetworkPortDef *def); + +int +virNetworkPortDefFormatBuf(virBufferPtr buf, + const virNetworkPortDef *def); + +int +virNetworkPortDefSaveStatus(virNetworkPortDef *def, + const char *dir); + +int +virNetworkPortDefDeleteStatus(virNetworkPortDef *def, + const char *dir); + + +#endif /* LIBVIRT_VIRNETWORKPORTDEF_H */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index aa123978fa..8767f4429e 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1074,6 +1074,16 @@ virNetworkObjUpdate; virNetworkObjUpdateAssignDef; =20 =20 +# conf/virnetworkportdef.h +virNetworkPortDefFormat; +virNetworkPortDefFormatBuf; +virNetworkPortDefFree; +virNetworkPortDefParseFile; +virNetworkPortDefParseNode; +virNetworkPortDefParseString; +virNetworkPortDefSaveStatus; + + # conf/virnodedeviceobj.h virNodeDeviceObjEndAPI; virNodeDeviceObjGetDef; diff --git a/tests/Makefile.am b/tests/Makefile.am index 46d94d2236..6865ee946e 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -149,6 +149,7 @@ EXTRA_DIST =3D \ virmockstathelpers.c \ virnetdaemondata \ virnetdevtestdata \ + virnetworkportxml2xmldata \ virnwfilterbindingxml2xmldata \ virpcitestdata \ virscsidata \ @@ -335,6 +336,7 @@ endif WITH_YAJL test_programs +=3D \ networkxml2xmltest \ networkxml2xmlupdatetest \ + virnetworkportxml2xmltest \ $(NULL) =20 if WITH_NETWORK @@ -832,6 +834,11 @@ networkxml2xmlupdatetest_SOURCES =3D \ testutils.c testutils.h networkxml2xmlupdatetest_LDADD =3D $(LDADDS) =20 +virnetworkportxml2xmltest_SOURCES =3D \ + virnetworkportxml2xmltest.c \ + testutils.c testutils.h +virnetworkportxml2xmltest_LDADD =3D $(LDADDS) + if WITH_NETWORK networkxml2conftest_SOURCES =3D \ networkxml2conftest.c \ diff --git a/tests/virnetworkportxml2xmldata/plug-bridge-mactbl.xml b/tests= /virnetworkportxml2xmldata/plug-bridge-mactbl.xml new file mode 100644 index 0000000000..8036bc2e1c --- /dev/null +++ b/tests/virnetworkportxml2xmldata/plug-bridge-mactbl.xml @@ -0,0 +1,9 @@ + + 5d744f21-ba4a-4d6e-bdb2-30a35ff3207d + + memtest + d54df46f-1ab5-4a22-8618-4560ef5fac2c + + + + diff --git a/tests/virnetworkportxml2xmldata/plug-bridge.xml b/tests/virnet= workportxml2xmldata/plug-bridge.xml new file mode 100644 index 0000000000..6dd576e8a1 --- /dev/null +++ b/tests/virnetworkportxml2xmldata/plug-bridge.xml @@ -0,0 +1,12 @@ + + 5d744f21-ba4a-4d6e-bdb2-30a35ff3207d + + memtest + d54df46f-1ab5-4a22-8618-4560ef5fac2c + + web1 + + + + + diff --git a/tests/virnetworkportxml2xmldata/plug-direct.xml b/tests/virnet= workportxml2xmldata/plug-direct.xml new file mode 100644 index 0000000000..81554b4579 --- /dev/null +++ b/tests/virnetworkportxml2xmldata/plug-direct.xml @@ -0,0 +1,12 @@ + + 5d744f21-ba4a-4d6e-bdb2-30a35ff3207d + + memtest + d54df46f-1ab5-4a22-8618-4560ef5fac2c + + + + + + + diff --git a/tests/virnetworkportxml2xmldata/plug-hostdev-pci.xml b/tests/v= irnetworkportxml2xmldata/plug-hostdev-pci.xml new file mode 100644 index 0000000000..cc4419f3fd --- /dev/null +++ b/tests/virnetworkportxml2xmldata/plug-hostdev-pci.xml @@ -0,0 +1,12 @@ + + 5d744f21-ba4a-4d6e-bdb2-30a35ff3207d + + memtest + d54df46f-1ab5-4a22-8618-4560ef5fac2c + + + + +
+ + diff --git a/tests/virnetworkportxml2xmldata/plug-none.xml b/tests/virnetwo= rkportxml2xmldata/plug-none.xml new file mode 100644 index 0000000000..ed7199ec8c --- /dev/null +++ b/tests/virnetworkportxml2xmldata/plug-none.xml @@ -0,0 +1,8 @@ + + 5d744f21-ba4a-4d6e-bdb2-30a35ff3207d + + memtest + d54df46f-1ab5-4a22-8618-4560ef5fac2c + + + diff --git a/tests/virnetworkportxml2xmltest.c b/tests/virnetworkportxml2xm= ltest.c new file mode 100644 index 0000000000..bb0ae8a8d5 --- /dev/null +++ b/tests/virnetworkportxml2xmltest.c @@ -0,0 +1,104 @@ +/* + * virnetworkportxml2xmltest.c: network port XML processing test suite + * + * 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 + * . + */ + +#include + +#include + +#include +#include + +#include "internal.h" +#include "testutils.h" +#include "virnetworkportdef.h" +#include "virstring.h" + +#define VIR_FROM_THIS VIR_FROM_NONE + + +static int +testCompareXMLToXMLFiles(const char *expected) +{ + char *actual =3D NULL; + int ret =3D -1; + virNetworkPortDefPtr dev =3D NULL; + + if (!(dev =3D virNetworkPortDefParseFile(expected))) + goto cleanup; + + if (!(actual =3D virNetworkPortDefFormat(dev))) + goto cleanup; + + if (virTestCompareToFile(actual, expected) < 0) + goto cleanup; + + ret =3D 0; + cleanup: + VIR_FREE(actual); + virNetworkPortDefFree(dev); + return ret; +} + +struct testInfo { + const char *name; +}; + +static int +testCompareXMLToXMLHelper(const void *data) +{ + const struct testInfo *info =3D data; + int ret =3D -1; + char *xml =3D NULL; + + if (virAsprintf(&xml, "%s/virnetworkportxml2xmldata/%s.xml", + abs_srcdir, info->name) < 0) + goto cleanup; + + ret =3D testCompareXMLToXMLFiles(xml); + + cleanup: + VIR_FREE(xml); + + return ret; +} + +static int +mymain(void) +{ + int ret =3D 0; + +#define DO_TEST(name) \ + do { \ + const struct testInfo info =3D {name}; \ + if (virTestRun("virnetworkportdeftest " name, \ + testCompareXMLToXMLHelper, &info) < 0) \ + ret =3D -1; \ + } while (0) + + DO_TEST("plug-none"); + DO_TEST("plug-bridge"); + DO_TEST("plug-bridge-mactbl"); + DO_TEST("plug-direct"); + DO_TEST("plug-hostdev-pci"); + + return ret =3D=3D 0 ? EXIT_SUCCESS : EXIT_FAILURE; +} + +VIR_TEST_MAIN(mymain) --=20 2.20.1 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list