mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 17:34:18 +03:00
conf: introduce virNetworkPortDefPtr struct and XML support
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@redhat.com>
This commit is contained in:
parent
c0c37de2d6
commit
4b4a981d60
@ -72,6 +72,7 @@
|
||||
<dd>Description of the XML schemas for
|
||||
<a href="formatdomain.html">domains</a>,
|
||||
<a href="formatnetwork.html">networks</a>,
|
||||
<a href="formatnetworkport.html">network ports</a>,
|
||||
<a href="formatnwfilter.html">network filtering</a>,
|
||||
<a href="formatstorage.html">storage</a>,
|
||||
<a href="formatstorageencryption.html">storage encryption</a>,
|
||||
|
212
docs/formatnetworkport.html.in
Normal file
212
docs/formatnetworkport.html.in
Normal file
@ -0,0 +1,212 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<body>
|
||||
<h1>Network XML format</h1>
|
||||
|
||||
<ul id="toc">
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
This page provides an introduction to the network port XML format.
|
||||
This stores information about the connection between an virtual
|
||||
interface on a virtual domain's, and the virtual network it is
|
||||
attached to.
|
||||
</p>
|
||||
|
||||
<h2><a id="elements">Element and attribute overview</a></h2>
|
||||
|
||||
<p>
|
||||
The root element required for all virtual network ports is
|
||||
named <code>networkport</code> and has no configurable attributes
|
||||
The network port XML format is available <span class="since">since
|
||||
5.5.0</span>
|
||||
</p>
|
||||
|
||||
<h3><a id="elementsMetadata">General metadata</a></h3>
|
||||
|
||||
<p>
|
||||
The first elements provide basic metadata about the virtual
|
||||
network port.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
<networkport
|
||||
<uuid>7ae63b5f-fe96-4af0-a7c3-da04ba1b3f54</uuid>
|
||||
<owner>
|
||||
<uuid>06578fc1-c686-46fa-bc2c-220893b466a6</uuid>
|
||||
<name>myguest<name>
|
||||
</owner>
|
||||
<group>webfront<group>
|
||||
<mac address='52:54:0:7b:35:93'/>
|
||||
...</pre>
|
||||
|
||||
<dl>
|
||||
<dt><code>uuid</code></dt>
|
||||
<dd>The content of the <code>uuid</code> element provides
|
||||
a globally unique identifier for the virtual network port.
|
||||
The format must be RFC 4122 compliant, eg <code>3e3fce45-4f53-4fa7-bb32-11f34168b82b</code>.
|
||||
If omitted when defining/creating a new network port, a random
|
||||
UUID is generated.</dd>
|
||||
<dd>The <code>owner</code> node records the domain object that
|
||||
is the owner of the network port. It contains two child nodes:
|
||||
<dl>
|
||||
<dt><code>uuid</code></dt>
|
||||
<dd>The content of the <code>uuid</code> element provides
|
||||
a globally unique identifier for the virtual domain.</dd>
|
||||
<dt><code>name</code></dt>
|
||||
<dd>The unique name of the virtual domain</dd>
|
||||
</dl>
|
||||
</dd>
|
||||
<dt><code>group</code></dt>
|
||||
<dd>The port group in the virtual network to which the
|
||||
port belongs. Can be omitted if no port groups are
|
||||
defined on the network.</dd>
|
||||
<dt><code>mac</code></dt>
|
||||
<dd>The <code>address</code> attribute provides the MAC
|
||||
address of the virtual port that will be see by the
|
||||
guest. The MAC address must not start with 0xFE as this
|
||||
byte is reserved for use on the host side of the port.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h3><a id="elementsCommon">Common elements</a></h3>
|
||||
|
||||
<p>
|
||||
The following elements are common to one of more of the plug
|
||||
types listed later
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
...
|
||||
<bandwidth>
|
||||
<inbound average='1000' peak='5000' floor='200' burst='1024'/>
|
||||
<outbound average='128' peak='256' burst='256'/>
|
||||
</bandwidth>
|
||||
<rxfilters trustGuest='yes'/>
|
||||
<virtualport type='802.1Qbg'>
|
||||
<parameters managerid='11' typeid='1193047' typeidversion='2'/>
|
||||
</virtualport>
|
||||
...</pre>
|
||||
|
||||
<dl>
|
||||
<dt><code>bandwidth</code></dt>
|
||||
<dd>This part of the network port XML provides setting quality of service.
|
||||
Incoming and outgoing traffic can be shaped independently.
|
||||
The <code>bandwidth</code> element and its child elements are described
|
||||
in the <a href="formatnetwork.html#elementQoS">QoS</a> section of
|
||||
the Network XML. In addition the <code>classID</code> attribute may
|
||||
exist provide the ID of the traffic shaping class that is active.
|
||||
</dd>
|
||||
<dt><code>rxfilters</code></dt>
|
||||
<dd>The <code>rxfilters</code> element property
|
||||
<code>trustGuest</code> provides the
|
||||
capability for the host to detect and trust reports from the
|
||||
guest regarding changes to the interface mac address and receive
|
||||
filters by setting the attribute to <code>yes</code>. The default
|
||||
setting for the attribute is <code>no</code> for security
|
||||
reasons and support depends on the guest network device model as
|
||||
well as the type of connection on the host - currently it is
|
||||
only supported for the virtio device model and for macvtap
|
||||
connections on the host.
|
||||
</dd>
|
||||
<dt><code>virtualport</code></dt>
|
||||
<dd>The <code>virtualport</code> element describes metadata that
|
||||
needs to be provided to the underlying network subsystem. It
|
||||
is described in the domain XML
|
||||
<a href="formatdomain.html#elementsNICS">interface documentation</a>.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
<h3><a id="elementsPlug">Plugs</a></h3>
|
||||
|
||||
<p>
|
||||
The <code>plug</code> element has varying content depending
|
||||
on the value of the <code>type</code> attribute.
|
||||
</p>
|
||||
|
||||
<h4><a id="elementsPlugNetwork">Network</a></h4>
|
||||
|
||||
<p>
|
||||
The <code>network</code> plug type refers to a managed virtual
|
||||
network plug that is based on a traditional software bridge
|
||||
device privately managed by libvirt.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
...
|
||||
<plug type='network' bridge='virbr0'>
|
||||
...</pre>
|
||||
|
||||
<p>
|
||||
The <code>bridge</code> attribute provides the name of the
|
||||
privately managed bridge device associated with the virtual
|
||||
network.
|
||||
</p>
|
||||
|
||||
<h4><a id="elementsPlugNetwork">Bridge</a></h4>
|
||||
|
||||
<p>
|
||||
The <code>bridge</code> plug type refers to an externally
|
||||
managed traditional software bridge.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
...
|
||||
<plug type='bridge' bridge='br2'>
|
||||
...</pre>
|
||||
|
||||
<p>
|
||||
The <code>bridge</code> attribute provides the name of the
|
||||
externally managed bridge device associated with the virtual
|
||||
network.
|
||||
</p>
|
||||
|
||||
<h4><a id="elementsPlugNetwork">Direct</a></h4>
|
||||
|
||||
<p>
|
||||
The <code>direct</code> plug type refers to a connection
|
||||
directly to a physical network interface.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
...
|
||||
<plug type='direct' dev='ens3' mode='vepa'/>
|
||||
...</pre>
|
||||
|
||||
<p>
|
||||
The <code>dev</code> attribute provides the name of the
|
||||
physical network interface to which the port will be
|
||||
connected. The <code>mode</code> attribute describes
|
||||
how the connection will be setup and takes the same
|
||||
values described in the
|
||||
<a href="formatdomain.html#elementsNICSDirect">domain XML</a>.
|
||||
</p>
|
||||
|
||||
<h4><a id="elementsPlugNetwork">Host PCI</a></h4>
|
||||
|
||||
<p>
|
||||
The <code>hostdev-pci</code> plug type refers to the
|
||||
passthrough of a physical PCI device rather than emulation.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
...
|
||||
<plug type='hostdev-pci' managed='yes'>
|
||||
<driver name='vfio'/>
|
||||
<address domain='0x0001' bus='0x02' slot='0x03' function='0x4'/>
|
||||
</plug>
|
||||
...</pre>
|
||||
|
||||
<p>
|
||||
The <code>managed</code> attribute indicates who is responsible for
|
||||
managing the PCI device in the host. When set to the value <code>yes</code>
|
||||
libvirt is responsible for automatically detaching the device from host
|
||||
drivers and resetting it if needed. If the value is <code>no</code>,
|
||||
some other party must ensure the device is not attached to any
|
||||
host drivers.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -134,6 +134,11 @@
|
||||
|
||||
<define name="bandwidth">
|
||||
<element name="bandwidth">
|
||||
<optional>
|
||||
<attribute name="classID">
|
||||
<ref name="positiveInteger"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<interleave>
|
||||
<optional>
|
||||
<element name="inbound">
|
||||
|
154
docs/schemas/networkport.rng
Normal file
154
docs/schemas/networkport.rng
Normal file
@ -0,0 +1,154 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- A Relax NG schema for the libvirt network port XML format -->
|
||||
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
|
||||
datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
|
||||
<include href='basictypes.rng'/>
|
||||
<include href='networkcommon.rng'/>
|
||||
|
||||
<start>
|
||||
<ref name="networkport"/>
|
||||
</start>
|
||||
|
||||
<define name="networkport">
|
||||
<element name="networkport">
|
||||
<interleave>
|
||||
<element name="uuid">
|
||||
<ref name="UUID"/>
|
||||
</element>
|
||||
<ref name="owner"/>
|
||||
<ref name="mac"/>
|
||||
<optional>
|
||||
<ref name="group"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="rxfilters"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="virtualPortProfile"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="bandwidth"/>
|
||||
</optional>
|
||||
<optional>
|
||||
<ref name="plug"/>
|
||||
</optional>
|
||||
</interleave>
|
||||
</element>
|
||||
</define>
|
||||
|
||||
<define name="owner">
|
||||
<element name="owner">
|
||||
<element name="name">
|
||||
<text/>
|
||||
</element>
|
||||
<element name="uuid">
|
||||
<ref name="UUID"/>
|
||||
</element>
|
||||
</element>
|
||||
</define>
|
||||
|
||||
<define name="mac">
|
||||
<element name="mac">
|
||||
<attribute name="address">
|
||||
<ref name="uniMacAddr"/>
|
||||
</attribute>
|
||||
<empty/>
|
||||
</element>
|
||||
</define>
|
||||
|
||||
<define name="group">
|
||||
<element name="group">
|
||||
<ref name="deviceName"/>
|
||||
</element>
|
||||
</define>
|
||||
|
||||
<define name="rxfilters">
|
||||
<element name="rxfilters">
|
||||
<attribute name="trustGuest">
|
||||
<ref name="virYesNo"/>
|
||||
</attribute>
|
||||
</element>
|
||||
</define>
|
||||
|
||||
<define name="plug">
|
||||
<element name="plug">
|
||||
<choice>
|
||||
<ref name="plugnetwork"/>
|
||||
<ref name="plugbridge"/>
|
||||
<ref name="plugdirect"/>
|
||||
<ref name="plughostdevpci"/>
|
||||
</choice>
|
||||
</element>
|
||||
</define>
|
||||
|
||||
<define name="plugnetwork">
|
||||
<attribute name="type">
|
||||
<value>network</value>
|
||||
</attribute>
|
||||
<attribute name="bridge">
|
||||
<ref name="deviceName"/>
|
||||
</attribute>
|
||||
<optional>
|
||||
<attribute name="macTableManager">
|
||||
<ref name="macTableManager"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
</define>
|
||||
|
||||
<define name="plugbridge">
|
||||
<attribute name="type">
|
||||
<value>bridge</value>
|
||||
</attribute>
|
||||
<attribute name="bridge">
|
||||
<ref name="deviceName"/>
|
||||
</attribute>
|
||||
<optional>
|
||||
<attribute name="macTableManager">
|
||||
<ref name="macTableManager"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
</define>
|
||||
|
||||
<define name="plugdirect">
|
||||
<attribute name="type">
|
||||
<value>direct</value>
|
||||
</attribute>
|
||||
<attribute name="dev">
|
||||
<ref name="deviceName"/>
|
||||
</attribute>
|
||||
<attribute name="mode">
|
||||
<choice>
|
||||
<value>bridge</value>
|
||||
<value>passthrough</value>
|
||||
<value>private</value>
|
||||
<value>vepa</value>
|
||||
</choice>
|
||||
</attribute>
|
||||
</define>
|
||||
|
||||
<define name="plughostdevpci">
|
||||
<attribute name="type">
|
||||
<value>hostdev-pci</value>
|
||||
</attribute>
|
||||
<optional>
|
||||
<attribute name="managed">
|
||||
<ref name="virYesNo"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<element name="driver">
|
||||
<attribute name="name">
|
||||
<choice>
|
||||
<value>kvm</value>
|
||||
<value>vfio</value>
|
||||
</choice>
|
||||
</attribute>
|
||||
<empty/>
|
||||
</element>
|
||||
</optional>
|
||||
<element name='address'>
|
||||
<ref name="pciaddress"/>
|
||||
</element>
|
||||
</define>
|
||||
|
||||
</grammar>
|
@ -1788,6 +1788,7 @@ exit 0
|
||||
%{_datadir}/libvirt/schemas/interface.rng
|
||||
%{_datadir}/libvirt/schemas/network.rng
|
||||
%{_datadir}/libvirt/schemas/networkcommon.rng
|
||||
%{_datadir}/libvirt/schemas/networkport.rng
|
||||
%{_datadir}/libvirt/schemas/nodedev.rng
|
||||
%{_datadir}/libvirt/schemas/nwfilter.rng
|
||||
%{_datadir}/libvirt/schemas/nwfilter_params.rng
|
||||
|
@ -7,6 +7,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 = \
|
||||
|
508
src/conf/virnetworkportdef.c
Normal file
508
src/conf/virnetworkportdef.c
Normal file
@ -0,0 +1,508 @@
|
||||
/*
|
||||
* 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", "network", "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_NETWORK:
|
||||
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;
|
||||
char *class_id = 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);
|
||||
/*
|
||||
* 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, &def->class_id,
|
||||
bandwidthNode, true) < 0)
|
||||
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);
|
||||
}
|
||||
|
||||
switch (def->plugtype) {
|
||||
case VIR_NETWORK_PORT_PLUG_TYPE_NONE:
|
||||
break;
|
||||
|
||||
case VIR_NETWORK_PORT_PLUG_TYPE_NETWORK:
|
||||
case VIR_NETWORK_PORT_PLUG_TYPE_BRIDGE:
|
||||
if (!(def->plug.bridge.brname = virXPathString("string(./plug/@bridge)", ctxt))) {
|
||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||
_("Missing network port bridge name"));
|
||||
goto error;
|
||||
}
|
||||
macmgr = virXPathString("string(./plug/@macTableManager)", ctxt);
|
||||
if (macmgr &&
|
||||
(def->plug.bridge.macTableManager =
|
||||
virNetworkBridgeMACTableManagerTypeFromString(macmgr)) <= 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 = virXPathString("string(./plug/@dev)", ctxt))) {
|
||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||
_("Missing network port link device name"));
|
||||
goto error;
|
||||
}
|
||||
mode = virXPathString("string(./plug/@mode)", ctxt);
|
||||
if (mode &&
|
||||
(def->plug.direct.mode =
|
||||
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 = virXPathString("string(./plug/@managed)", ctxt);
|
||||
if (managed &&
|
||||
(def->plug.hostdevpci.managed =
|
||||
virTristateBoolTypeFromString(managed)) < 0) {
|
||||
virReportError(VIR_ERR_XML_ERROR,
|
||||
_("Invalid managed setting '%s' in network port"), mode);
|
||||
goto error;
|
||||
}
|
||||
driver = virXPathString("string(./plug/driver/@name)", ctxt);
|
||||
if (driver &&
|
||||
(def->plug.hostdevpci.driver =
|
||||
virNetworkForwardDriverNameTypeFromString(driver)) <= 0) {
|
||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||
_("Missing network port driver name"));
|
||||
goto error;
|
||||
}
|
||||
if (!(addressNode = 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 = NULL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
virNetworkPortDefPtr
|
||||
virNetworkPortDefParseNode(xmlDocPtr xml,
|
||||
xmlNodePtr root)
|
||||
{
|
||||
xmlXPathContextPtr ctxt = NULL;
|
||||
virNetworkPortDefPtr def = NULL;
|
||||
|
||||
if (STRNEQ((const char *)root->name, "networkport")) {
|
||||
virReportError(VIR_ERR_XML_ERROR,
|
||||
"%s",
|
||||
_("unknown root element for network port"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ctxt = xmlXPathNewContext(xml);
|
||||
if (ctxt == NULL) {
|
||||
virReportOOMError();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ctxt->node = root;
|
||||
def = virNetworkPortDefParseXML(ctxt);
|
||||
|
||||
cleanup:
|
||||
xmlXPathFreeContext(ctxt);
|
||||
return def;
|
||||
}
|
||||
|
||||
|
||||
static virNetworkPortDefPtr
|
||||
virNetworkPortDefParse(const char *xmlStr,
|
||||
const char *filename)
|
||||
{
|
||||
virNetworkPortDefPtr def = NULL;
|
||||
xmlDocPtr xml;
|
||||
|
||||
if ((xml = virXMLParse(filename, xmlStr, _("(networkport_definition)")))) {
|
||||
def = 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 = 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, "<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");
|
||||
|
||||
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;
|
||||
if (def->bandwidth)
|
||||
virNetDevBandwidthFormat(def->bandwidth, def->class_id, buf);
|
||||
if (virNetDevVlanFormat(&def->vlan, buf) < 0)
|
||||
return -1;
|
||||
if (def->trustGuestRxFilters)
|
||||
virBufferAsprintf(buf, "<rxfilters trustGuest='%s'/>\n",
|
||||
virTristateBoolTypeToString(def->trustGuestRxFilters));
|
||||
|
||||
if (def->plugtype != VIR_NETWORK_PORT_PLUG_TYPE_NONE) {
|
||||
virBufferAsprintf(buf, "<plug type='%s'",
|
||||
virNetworkPortPlugTypeToString(def->plugtype));
|
||||
|
||||
switch (def->plugtype) {
|
||||
case VIR_NETWORK_PORT_PLUG_TYPE_NONE:
|
||||
break;
|
||||
|
||||
case VIR_NETWORK_PORT_PLUG_TYPE_NETWORK:
|
||||
case VIR_NETWORK_PORT_PLUG_TYPE_BRIDGE:
|
||||
virBufferEscapeString(buf, " bridge='%s'", def->plug.bridge.brname);
|
||||
if (def->plug.bridge.macTableManager)
|
||||
virBufferAsprintf(buf, " macTableManager='%s'",
|
||||
virNetworkBridgeMACTableManagerTypeToString(
|
||||
def->plug.bridge.macTableManager));
|
||||
virBufferAddLit(buf, "/>\n");
|
||||
break;
|
||||
|
||||
case VIR_NETWORK_PORT_PLUG_TYPE_DIRECT:
|
||||
virBufferEscapeString(buf, " dev='%s'", def->plug.direct.linkdev);
|
||||
virBufferAsprintf(buf, " mode='%s'",
|
||||
virNetDevMacVLanModeTypeToString(
|
||||
def->plug.direct.mode));
|
||||
virBufferAddLit(buf, "/>\n");
|
||||
break;
|
||||
|
||||
case VIR_NETWORK_PORT_PLUG_TYPE_HOSTDEV_PCI:
|
||||
virBufferAsprintf(buf, " managed='%s'>\n",
|
||||
def->plug.hostdevpci.managed ? "yes" : "no");
|
||||
virBufferAdjustIndent(buf, 2);
|
||||
if (def->plug.hostdevpci.driver)
|
||||
virBufferEscapeString(buf, "<driver name='%s'/>\n",
|
||||
virNetworkForwardDriverNameTypeToString(
|
||||
def->plug.hostdevpci.driver));
|
||||
|
||||
virPCIDeviceAddressFormat(buf, def->plug.hostdevpci.addr, false);
|
||||
virBufferAdjustIndent(buf, -2);
|
||||
virBufferAddLit(buf, "</plug>\n");
|
||||
break;
|
||||
|
||||
case VIR_NETWORK_PORT_PLUG_TYPE_LAST:
|
||||
default:
|
||||
virReportEnumRangeError(virNetworkPortPlugType, def->plugtype);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
virBufferAdjustIndent(buf, -2);
|
||||
virBufferAddLit(buf, "</networkport>\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
virNetworkPortDefConfigFile(const char *dir,
|
||||
const char *name)
|
||||
{
|
||||
char *ret = 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 = NULL;
|
||||
int ret = -1;
|
||||
|
||||
virUUIDFormat(def->uuid, uuidstr);
|
||||
|
||||
if (virFileMakePath(dir) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (!(path = virNetworkPortDefConfigFile(dir, uuidstr)))
|
||||
goto cleanup;
|
||||
|
||||
if (!(xml = virNetworkPortDefFormat(def)))
|
||||
goto cleanup;
|
||||
|
||||
if (virXMLSaveFile(path, uuidstr, "net-port-create", xml) < 0)
|
||||
goto cleanup;
|
||||
|
||||
ret = 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 = -1;
|
||||
|
||||
virUUIDFormat(def->uuid, uuidstr);
|
||||
|
||||
if (!(path = virNetworkPortDefConfigFile(dir, uuidstr)))
|
||||
goto cleanup;
|
||||
|
||||
if (unlink(path) < 0 && errno != ENOENT) {
|
||||
virReportSystemError(errno,
|
||||
_("Unable to delete %s"), path);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
VIR_FREE(path);
|
||||
return ret;
|
||||
}
|
109
src/conf/virnetworkportdef.h
Normal file
109
src/conf/virnetworkportdef.h
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* 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
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#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_NETWORK,
|
||||
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 virNetworkBridgeMACTableManagerType */
|
||||
} bridge; /* For TYPE_NETWORK & TYPE_BRIDGE */
|
||||
struct {
|
||||
char *linkdev;
|
||||
int mode; /* enum virNetDevMacVLanMode from util/virnetdevmacvlan.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);
|
@ -1075,6 +1075,16 @@ virNetworkObjUpdate;
|
||||
virNetworkObjUpdateAssignDef;
|
||||
|
||||
|
||||
# conf/virnetworkportdef.h
|
||||
virNetworkPortDefFormat;
|
||||
virNetworkPortDefFormatBuf;
|
||||
virNetworkPortDefFree;
|
||||
virNetworkPortDefParseFile;
|
||||
virNetworkPortDefParseNode;
|
||||
virNetworkPortDefParseString;
|
||||
virNetworkPortDefSaveStatus;
|
||||
|
||||
|
||||
# conf/virnodedeviceobj.h
|
||||
virNodeDeviceObjEndAPI;
|
||||
virNodeDeviceObjGetDef;
|
||||
|
@ -149,6 +149,7 @@ EXTRA_DIST = \
|
||||
virmockstathelpers.c \
|
||||
virnetdaemondata \
|
||||
virnetdevtestdata \
|
||||
virnetworkportxml2xmldata \
|
||||
virnwfilterbindingxml2xmldata \
|
||||
virpcitestdata \
|
||||
virscsidata \
|
||||
@ -335,6 +336,7 @@ endif WITH_YAJL
|
||||
test_programs += \
|
||||
networkxml2xmltest \
|
||||
networkxml2xmlupdatetest \
|
||||
virnetworkportxml2xmltest \
|
||||
$(NULL)
|
||||
|
||||
if WITH_NETWORK
|
||||
@ -833,6 +835,11 @@ networkxml2xmlupdatetest_SOURCES = \
|
||||
testutils.c testutils.h
|
||||
networkxml2xmlupdatetest_LDADD = $(LDADDS)
|
||||
|
||||
virnetworkportxml2xmltest_SOURCES = \
|
||||
virnetworkportxml2xmltest.c \
|
||||
testutils.c testutils.h
|
||||
virnetworkportxml2xmltest_LDADD = $(LDADDS)
|
||||
|
||||
if WITH_NETWORK
|
||||
networkxml2conftest_SOURCES = \
|
||||
networkxml2conftest.c \
|
||||
|
9
tests/virnetworkportxml2xmldata/plug-bridge-mactbl.xml
Normal file
9
tests/virnetworkportxml2xmldata/plug-bridge-mactbl.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<networkport>
|
||||
<uuid>5d744f21-ba4a-4d6e-bdb2-30a35ff3207d</uuid>
|
||||
<owner>
|
||||
<name>memtest</name>
|
||||
<uuid>d54df46f-1ab5-4a22-8618-4560ef5fac2c</uuid>
|
||||
</owner>
|
||||
<mac address='52:54:00:7b:35:93'/>
|
||||
<plug type='bridge' bridge='virbr0' macTableManager='libvirt'/>
|
||||
</networkport>
|
15
tests/virnetworkportxml2xmldata/plug-bridge.xml
Normal file
15
tests/virnetworkportxml2xmldata/plug-bridge.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<networkport>
|
||||
<uuid>5d744f21-ba4a-4d6e-bdb2-30a35ff3207d</uuid>
|
||||
<owner>
|
||||
<name>memtest</name>
|
||||
<uuid>d54df46f-1ab5-4a22-8618-4560ef5fac2c</uuid>
|
||||
</owner>
|
||||
<group>web1</group>
|
||||
<mac address='52:54:00:7b:35:93'/>
|
||||
<bandwidth classID='1729'>
|
||||
<inbound average='1000' peak='4000' floor='2000' burst='1024'/>
|
||||
<outbound average='128' peak='256' burst='32768'/>
|
||||
</bandwidth>
|
||||
<rxfilters trustGuest='yes'/>
|
||||
<plug type='bridge' bridge='virbr0'/>
|
||||
</networkport>
|
12
tests/virnetworkportxml2xmldata/plug-direct.xml
Normal file
12
tests/virnetworkportxml2xmldata/plug-direct.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<networkport>
|
||||
<uuid>5d744f21-ba4a-4d6e-bdb2-30a35ff3207d</uuid>
|
||||
<owner>
|
||||
<name>memtest</name>
|
||||
<uuid>d54df46f-1ab5-4a22-8618-4560ef5fac2c</uuid>
|
||||
</owner>
|
||||
<mac address='52:54:00:7b:35:93'/>
|
||||
<virtualport type='802.1Qbg'>
|
||||
<parameters managerid='11' typeid='1193047' typeidversion='2'/>
|
||||
</virtualport>
|
||||
<plug type='direct' dev='ens3' mode='vepa'/>
|
||||
</networkport>
|
12
tests/virnetworkportxml2xmldata/plug-hostdev-pci.xml
Normal file
12
tests/virnetworkportxml2xmldata/plug-hostdev-pci.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<networkport>
|
||||
<uuid>5d744f21-ba4a-4d6e-bdb2-30a35ff3207d</uuid>
|
||||
<owner>
|
||||
<name>memtest</name>
|
||||
<uuid>d54df46f-1ab5-4a22-8618-4560ef5fac2c</uuid>
|
||||
</owner>
|
||||
<mac address='52:54:00:7b:35:93'/>
|
||||
<plug type='hostdev-pci' managed='yes'>
|
||||
<driver name='vfio'/>
|
||||
<address domain='0x0001' bus='0x02' slot='0x03' function='0x4'/>
|
||||
</plug>
|
||||
</networkport>
|
15
tests/virnetworkportxml2xmldata/plug-network.xml
Normal file
15
tests/virnetworkportxml2xmldata/plug-network.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<networkport>
|
||||
<uuid>5d744f21-ba4a-4d6e-bdb2-30a35ff3207d</uuid>
|
||||
<owner>
|
||||
<name>memtest</name>
|
||||
<uuid>d54df46f-1ab5-4a22-8618-4560ef5fac2c</uuid>
|
||||
</owner>
|
||||
<group>web1</group>
|
||||
<mac address='52:54:00:7b:35:93'/>
|
||||
<bandwidth classID='1729'>
|
||||
<inbound average='1000' peak='4000' floor='2000' burst='1024'/>
|
||||
<outbound average='128' peak='256' burst='32768'/>
|
||||
</bandwidth>
|
||||
<rxfilters trustGuest='yes'/>
|
||||
<plug type='network' bridge='virbr0'/>
|
||||
</networkport>
|
8
tests/virnetworkportxml2xmldata/plug-none.xml
Normal file
8
tests/virnetworkportxml2xmldata/plug-none.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<networkport>
|
||||
<uuid>5d744f21-ba4a-4d6e-bdb2-30a35ff3207d</uuid>
|
||||
<owner>
|
||||
<name>memtest</name>
|
||||
<uuid>d54df46f-1ab5-4a22-8618-4560ef5fac2c</uuid>
|
||||
</owner>
|
||||
<mac address='52:54:00:7b:35:93'/>
|
||||
</networkport>
|
104
tests/virnetworkportxml2xmltest.c
Normal file
104
tests/virnetworkportxml2xmltest.c
Normal file
@ -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
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#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 = NULL;
|
||||
int ret = -1;
|
||||
virNetworkPortDefPtr dev = NULL;
|
||||
|
||||
if (!(dev = virNetworkPortDefParseFile(expected)))
|
||||
goto cleanup;
|
||||
|
||||
if (!(actual = virNetworkPortDefFormat(dev)))
|
||||
goto cleanup;
|
||||
|
||||
if (virTestCompareToFile(actual, expected) < 0)
|
||||
goto cleanup;
|
||||
|
||||
ret = 0;
|
||||
cleanup:
|
||||
VIR_FREE(actual);
|
||||
virNetworkPortDefFree(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct testInfo {
|
||||
const char *name;
|
||||
};
|
||||
|
||||
static int
|
||||
testCompareXMLToXMLHelper(const void *data)
|
||||
{
|
||||
const struct testInfo *info = data;
|
||||
int ret = -1;
|
||||
char *xml = NULL;
|
||||
|
||||
if (virAsprintf(&xml, "%s/virnetworkportxml2xmldata/%s.xml",
|
||||
abs_srcdir, info->name) < 0)
|
||||
goto cleanup;
|
||||
|
||||
ret = testCompareXMLToXMLFiles(xml);
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(xml);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
mymain(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
#define DO_TEST(name) \
|
||||
do { \
|
||||
const struct testInfo info = {name}; \
|
||||
if (virTestRun("virnetworkportdeftest " name, \
|
||||
testCompareXMLToXMLHelper, &info) < 0) \
|
||||
ret = -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 == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
|
||||
VIR_TEST_MAIN(mymain)
|
@ -227,6 +227,7 @@ mymain(void)
|
||||
DO_TEST_DIR("interface.rng", "interfaceschemadata");
|
||||
DO_TEST_DIR("network.rng", "../src/network", "networkxml2xmlin",
|
||||
"networkxml2xmlout", "networkxml2confdata");
|
||||
DO_TEST_DIR("networkport.rng", "virnetworkportxml2xmldata");
|
||||
DO_TEST_DIR("nodedev.rng", "nodedevschemadata");
|
||||
DO_TEST_DIR("nwfilter.rng", "nwfilterxml2xmlout", "../examples/xml/nwfilter");
|
||||
DO_TEST_DIR("nwfilterbinding.rng", "virnwfilterbindingxml2xmldata");
|
||||
|
Loading…
Reference in New Issue
Block a user