mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-02 01:45:17 +00:00
conf: support abstracted interface info in domain interface XML
the domain XML <interface> element is updated in the following ways: 1) <virtualportprofile> can be specified when source type='network' (previously it was only valid for source type='direct') 2) A new attribute "portgroup" has been added to the <source> element. When source type='network' (the only time portgroup is recognized), extra configuration information will be taken from the <portgroup> element of the given name in the network definition. 3) Each virDomainNetDef now also potentially has a virDomainActualNetDef which is a private object (never exported/imported via the public API, and not defined in the RNG) that is used to maintain information about the physical device that was actually used for a NetDef of type VIR_DOMAIN_NET_TYPE_NETWORK. The virDomainActualNetDef will only be parsed/formatted if the parse/format function is called with the VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET flag set (which is only needed when saving/loading a running domain's state info to the stateDir).
This commit is contained in:
parent
524655eea2
commit
07f4136993
1
cfg.mk
1
cfg.mk
@ -97,6 +97,7 @@ useless_free_options = \
|
|||||||
--name=virCommandFree \
|
--name=virCommandFree \
|
||||||
--name=virConfFreeList \
|
--name=virConfFreeList \
|
||||||
--name=virConfFreeValue \
|
--name=virConfFreeValue \
|
||||||
|
--name=virDomainActualNetDefFree \
|
||||||
--name=virDomainChrDefFree \
|
--name=virDomainChrDefFree \
|
||||||
--name=virDomainChrSourceDefFree \
|
--name=virDomainChrSourceDefFree \
|
||||||
--name=virDomainControllerDefFree \
|
--name=virDomainControllerDefFree \
|
||||||
|
@ -1391,24 +1391,55 @@
|
|||||||
<p>
|
<p>
|
||||||
<strong><em>
|
<strong><em>
|
||||||
This is the recommended config for general guest connectivity on
|
This is the recommended config for general guest connectivity on
|
||||||
hosts with dynamic / wireless networking configs
|
hosts with dynamic / wireless networking configs (or multi-host
|
||||||
|
environments where the host hardware details are described
|
||||||
|
separately in a <code><network></code>
|
||||||
|
definition <span class="since">Since 0.9.4</span>).
|
||||||
</em></strong>
|
</em></strong>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Provides a virtual network using a bridge device in the host.
|
|
||||||
Depending on the virtual network configuration, the network may be
|
Provides a connection whose details are described by the named
|
||||||
totally isolated, NAT'ing to an explicit network device, or NAT'ing to
|
network definition. Depending on the virtual network's "forward
|
||||||
the default route. DHCP and DNS are provided on the virtual network in
|
mode" configuration, the network may be totally isolated
|
||||||
all cases and the IP range can be determined by examining the virtual
|
(no <code><forward></code> element given), NAT'ing to an
|
||||||
network config with '<code>virsh net-dumpxml [networkname]</code>'.
|
explicit network device or to the default route
|
||||||
There is one virtual network called 'default' setup out
|
(<code><forward mode='nat'></code>), routed with no NAT
|
||||||
of the box which does NAT'ing to the default route and has an IP range of
|
(<code><forward mode='route'/></code>), or connected
|
||||||
<code>192.168.122.0/255.255.255.0</code>. Each guest will have an
|
directly to one of the host's network interfaces (via macvtap)
|
||||||
associated tun device created with a name of vnetN, which can also be
|
or bridge devices ((<code><forward
|
||||||
overridden with the <target> element (see
|
mode='bridge|private|vepa|passthrough'/></code> <span class="since">Since
|
||||||
|
0.9.4</span>)
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
For networks with a forward mode of bridge, private, vepa, and
|
||||||
|
passthrough, it is assumed that the host has any necessary DNS
|
||||||
|
and DHCP services already setup outside the scope of libvirt. In
|
||||||
|
the case of isolated, nat, and routed networks, DHCP and DNS are
|
||||||
|
provided on the virtual network by libvirt, and the IP range can
|
||||||
|
be determined by examining the virtual network config with
|
||||||
|
'<code>virsh net-dumpxml [networkname]</code>'. There is one
|
||||||
|
virtual network called 'default' setup out of the box which does
|
||||||
|
NAT'ing to the default route and has an IP range
|
||||||
|
of <code>192.168.122.0/255.255.255.0</code>. Each guest will
|
||||||
|
have an associated tun device created with a name of vnetN,
|
||||||
|
which can also be overridden with the <target> element
|
||||||
|
(see
|
||||||
<a href="#elementsNICSTargetOverride">overriding the target element</a>).
|
<a href="#elementsNICSTargetOverride">overriding the target element</a>).
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
When the source of an interface is a network,
|
||||||
|
a <code>portgroup</code> can be specified along with the name of
|
||||||
|
the network; one network may have multiple portgroups defined,
|
||||||
|
with each portgroup containing slightly different configuration
|
||||||
|
information for different classes of network
|
||||||
|
connections. <span class="since">Since 0.9.4</span>). Also,
|
||||||
|
similar to <code>direct</code> network connections (described
|
||||||
|
below), a connection of type <code>network</code> may specify
|
||||||
|
a <code>virtportprofile</code> element, with configuration data
|
||||||
|
to be forwarded to a vepa or 802.1Qbh compliant switch.
|
||||||
|
</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
...
|
...
|
||||||
@ -1418,9 +1449,13 @@
|
|||||||
</interface>
|
</interface>
|
||||||
...
|
...
|
||||||
<interface type='network'>
|
<interface type='network'>
|
||||||
<source network='default'/>
|
<source network='default' portgroup='engineering'/>
|
||||||
<target dev='vnet7'/>
|
<target dev='vnet7'/>
|
||||||
<mac address="00:11:22:33:44:55"/>
|
<mac address="00:11:22:33:44:55"/>
|
||||||
|
<virtualport type='802.1Qbg'>
|
||||||
|
<parameters managerid='11' typeid='1193047' typeidversion='2' instanceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/>
|
||||||
|
</virtualport>
|
||||||
|
|
||||||
</interface>
|
</interface>
|
||||||
</devices>
|
</devices>
|
||||||
...</pre>
|
...</pre>
|
||||||
|
@ -1036,8 +1036,16 @@
|
|||||||
<attribute name="network">
|
<attribute name="network">
|
||||||
<ref name="deviceName"/>
|
<ref name="deviceName"/>
|
||||||
</attribute>
|
</attribute>
|
||||||
|
<optional>
|
||||||
|
<attribute name="portgroup">
|
||||||
|
<ref name="deviceName"/>
|
||||||
|
</attribute>
|
||||||
|
</optional>
|
||||||
<empty/>
|
<empty/>
|
||||||
</element>
|
</element>
|
||||||
|
<optional>
|
||||||
|
<ref name="virtualPortProfile"/>
|
||||||
|
</optional>
|
||||||
<ref name="interface-options"/>
|
<ref name="interface-options"/>
|
||||||
</interleave>
|
</interleave>
|
||||||
</group>
|
</group>
|
||||||
|
@ -56,10 +56,11 @@
|
|||||||
* verify that it doesn't overflow an unsigned int when shifting */
|
* verify that it doesn't overflow an unsigned int when shifting */
|
||||||
verify(VIR_DOMAIN_VIRT_LAST <= 32);
|
verify(VIR_DOMAIN_VIRT_LAST <= 32);
|
||||||
|
|
||||||
/* Private flag used internally by virDomainSaveStatus and
|
/* Private flags used internally by virDomainSaveStatus and
|
||||||
* virDomainObjParseFile. */
|
* virDomainLoadStatus. */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
VIR_DOMAIN_XML_INTERNAL_STATUS = (1<<16), /* dump internal domain status information */
|
VIR_DOMAIN_XML_INTERNAL_STATUS = (1<<16), /* dump internal domain status information */
|
||||||
|
VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET = (1<<17), /* dump/parse <actual> element */
|
||||||
} virDomainXMLInternalFlags;
|
} virDomainXMLInternalFlags;
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virDomainTaint, VIR_DOMAIN_TAINT_LAST,
|
VIR_ENUM_IMPL(virDomainTaint, VIR_DOMAIN_TAINT_LAST,
|
||||||
@ -734,6 +735,27 @@ void virDomainFSDefFree(virDomainFSDefPtr def)
|
|||||||
VIR_FREE(def);
|
VIR_FREE(def);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
virDomainActualNetDefFree(virDomainActualNetDefPtr def)
|
||||||
|
{
|
||||||
|
if (!def)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (def->type) {
|
||||||
|
case VIR_DOMAIN_NET_TYPE_BRIDGE:
|
||||||
|
VIR_FREE(def->data.bridge.brname);
|
||||||
|
break;
|
||||||
|
case VIR_DOMAIN_NET_TYPE_DIRECT:
|
||||||
|
VIR_FREE(def->data.direct.linkdev);
|
||||||
|
VIR_FREE(def->data.direct.virtPortProfile);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
VIR_FREE(def);
|
||||||
|
}
|
||||||
|
|
||||||
void virDomainNetDefFree(virDomainNetDefPtr def)
|
void virDomainNetDefFree(virDomainNetDefPtr def)
|
||||||
{
|
{
|
||||||
if (!def)
|
if (!def)
|
||||||
@ -756,6 +778,9 @@ void virDomainNetDefFree(virDomainNetDefPtr def)
|
|||||||
|
|
||||||
case VIR_DOMAIN_NET_TYPE_NETWORK:
|
case VIR_DOMAIN_NET_TYPE_NETWORK:
|
||||||
VIR_FREE(def->data.network.name);
|
VIR_FREE(def->data.network.name);
|
||||||
|
VIR_FREE(def->data.network.portgroup);
|
||||||
|
VIR_FREE(def->data.network.virtPortProfile);
|
||||||
|
virDomainActualNetDefFree(def->data.network.actual);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_NET_TYPE_BRIDGE:
|
case VIR_DOMAIN_NET_TYPE_BRIDGE:
|
||||||
@ -2586,6 +2611,81 @@ cleanup:
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virDomainActualNetDefParseXML(xmlNodePtr node,
|
||||||
|
xmlXPathContextPtr ctxt,
|
||||||
|
virDomainActualNetDefPtr *def)
|
||||||
|
{
|
||||||
|
virDomainActualNetDefPtr actual = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
xmlNodePtr save_ctxt = ctxt->node;
|
||||||
|
char *type = NULL;
|
||||||
|
char *mode = NULL;
|
||||||
|
|
||||||
|
if (VIR_ALLOC(actual) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctxt->node = node;
|
||||||
|
|
||||||
|
type = virXMLPropString(node, "type");
|
||||||
|
if (!type) {
|
||||||
|
virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("missing type attribute in interface's <actual> element"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if ((actual->type = virDomainNetTypeFromString(type)) < 0) {
|
||||||
|
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("unknown type '%s' in interface's <actual> element"), type);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (actual->type != VIR_DOMAIN_NET_TYPE_BRIDGE &&
|
||||||
|
actual->type != VIR_DOMAIN_NET_TYPE_DIRECT) {
|
||||||
|
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("unsupported type '%s' in interface's <actual> element"),
|
||||||
|
type);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actual->type == VIR_DOMAIN_NET_TYPE_BRIDGE) {
|
||||||
|
actual->data.bridge.brname = virXPathString("string(./source[1]/@bridge)", ctxt);
|
||||||
|
} else if (actual->type == VIR_DOMAIN_NET_TYPE_DIRECT) {
|
||||||
|
xmlNodePtr virtPortNode;
|
||||||
|
|
||||||
|
actual->data.direct.linkdev = virXPathString("string(./source[1]/@dev)", ctxt);
|
||||||
|
|
||||||
|
mode = virXPathString("string(./source[1]/@mode)", ctxt);
|
||||||
|
if (mode) {
|
||||||
|
int m;
|
||||||
|
if ((m = virMacvtapModeTypeFromString(mode)) < 0) {
|
||||||
|
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Unkown mode '%s' in interface <actual> element"),
|
||||||
|
mode);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
actual->data.direct.mode = m;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtPortNode = virXPathNode("./virtualport", ctxt);
|
||||||
|
if (virtPortNode &&
|
||||||
|
virVirtualPortProfileParseXML(virtPortNode,
|
||||||
|
&actual->data.direct.virtPortProfile) < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*def = actual;
|
||||||
|
actual = NULL;
|
||||||
|
ret = 0;
|
||||||
|
error:
|
||||||
|
VIR_FREE(type);
|
||||||
|
VIR_FREE(mode);
|
||||||
|
virDomainActualNetDefFree(actual);
|
||||||
|
|
||||||
|
ctxt->node = save_ctxt;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse the XML definition for a network interface
|
/* Parse the XML definition for a network interface
|
||||||
* @param node XML nodeset to parse for net definition
|
* @param node XML nodeset to parse for net definition
|
||||||
@ -2603,6 +2703,7 @@ virDomainNetDefParseXML(virCapsPtr caps,
|
|||||||
char *macaddr = NULL;
|
char *macaddr = NULL;
|
||||||
char *type = NULL;
|
char *type = NULL;
|
||||||
char *network = NULL;
|
char *network = NULL;
|
||||||
|
char *portgroup = NULL;
|
||||||
char *bridge = NULL;
|
char *bridge = NULL;
|
||||||
char *dev = NULL;
|
char *dev = NULL;
|
||||||
char *ifname = NULL;
|
char *ifname = NULL;
|
||||||
@ -2619,6 +2720,7 @@ virDomainNetDefParseXML(virCapsPtr caps,
|
|||||||
char *mode = NULL;
|
char *mode = NULL;
|
||||||
virNWFilterHashTablePtr filterparams = NULL;
|
virNWFilterHashTablePtr filterparams = NULL;
|
||||||
virVirtualPortProfileParamsPtr virtPort = NULL;
|
virVirtualPortProfileParamsPtr virtPort = NULL;
|
||||||
|
virDomainActualNetDefPtr actual = NULL;
|
||||||
xmlNodePtr oldnode = ctxt->node;
|
xmlNodePtr oldnode = ctxt->node;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -2650,6 +2752,7 @@ virDomainNetDefParseXML(virCapsPtr caps,
|
|||||||
(def->type == VIR_DOMAIN_NET_TYPE_NETWORK) &&
|
(def->type == VIR_DOMAIN_NET_TYPE_NETWORK) &&
|
||||||
(xmlStrEqual(cur->name, BAD_CAST "source"))) {
|
(xmlStrEqual(cur->name, BAD_CAST "source"))) {
|
||||||
network = virXMLPropString(cur, "network");
|
network = virXMLPropString(cur, "network");
|
||||||
|
portgroup = virXMLPropString(cur, "portgroup");
|
||||||
} else if ((internal == NULL) &&
|
} else if ((internal == NULL) &&
|
||||||
(def->type == VIR_DOMAIN_NET_TYPE_INTERNAL) &&
|
(def->type == VIR_DOMAIN_NET_TYPE_INTERNAL) &&
|
||||||
(xmlStrEqual(cur->name, BAD_CAST "source"))) {
|
(xmlStrEqual(cur->name, BAD_CAST "source"))) {
|
||||||
@ -2665,7 +2768,8 @@ virDomainNetDefParseXML(virCapsPtr caps,
|
|||||||
dev = virXMLPropString(cur, "dev");
|
dev = virXMLPropString(cur, "dev");
|
||||||
mode = virXMLPropString(cur, "mode");
|
mode = virXMLPropString(cur, "mode");
|
||||||
} else if ((virtPort == NULL) &&
|
} else if ((virtPort == NULL) &&
|
||||||
(def->type == VIR_DOMAIN_NET_TYPE_DIRECT) &&
|
((def->type == VIR_DOMAIN_NET_TYPE_DIRECT) ||
|
||||||
|
(def->type == VIR_DOMAIN_NET_TYPE_NETWORK)) &&
|
||||||
xmlStrEqual(cur->name, BAD_CAST "virtualport")) {
|
xmlStrEqual(cur->name, BAD_CAST "virtualport")) {
|
||||||
if (virVirtualPortProfileParseXML(cur, &virtPort) < 0)
|
if (virVirtualPortProfileParseXML(cur, &virtPort) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
@ -2713,6 +2817,12 @@ virDomainNetDefParseXML(virCapsPtr caps,
|
|||||||
if (virDomainDeviceBootParseXML(cur, &def->bootIndex,
|
if (virDomainDeviceBootParseXML(cur, &def->bootIndex,
|
||||||
bootMap))
|
bootMap))
|
||||||
goto error;
|
goto error;
|
||||||
|
} else if ((actual == NULL) &&
|
||||||
|
(flags & VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET) &&
|
||||||
|
(def->type == VIR_DOMAIN_NET_TYPE_NETWORK) &&
|
||||||
|
xmlStrEqual(cur->name, BAD_CAST "actual")) {
|
||||||
|
if (virDomainActualNetDefParseXML(cur, ctxt, &actual) < 0)
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
@ -2761,6 +2871,12 @@ virDomainNetDefParseXML(virCapsPtr caps,
|
|||||||
}
|
}
|
||||||
def->data.network.name = network;
|
def->data.network.name = network;
|
||||||
network = NULL;
|
network = NULL;
|
||||||
|
def->data.network.portgroup = portgroup;
|
||||||
|
portgroup = NULL;
|
||||||
|
def->data.network.virtPortProfile = virtPort;
|
||||||
|
virtPort = NULL;
|
||||||
|
def->data.network.actual = actual;
|
||||||
|
actual = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_NET_TYPE_ETHERNET:
|
case VIR_DOMAIN_NET_TYPE_ETHERNET:
|
||||||
@ -2956,11 +3072,13 @@ cleanup:
|
|||||||
ctxt->node = oldnode;
|
ctxt->node = oldnode;
|
||||||
VIR_FREE(macaddr);
|
VIR_FREE(macaddr);
|
||||||
VIR_FREE(network);
|
VIR_FREE(network);
|
||||||
|
VIR_FREE(portgroup);
|
||||||
VIR_FREE(address);
|
VIR_FREE(address);
|
||||||
VIR_FREE(port);
|
VIR_FREE(port);
|
||||||
VIR_FREE(ifname);
|
VIR_FREE(ifname);
|
||||||
VIR_FREE(dev);
|
VIR_FREE(dev);
|
||||||
VIR_FREE(virtPort);
|
VIR_FREE(virtPort);
|
||||||
|
virDomainActualNetDefFree(actual);
|
||||||
VIR_FREE(script);
|
VIR_FREE(script);
|
||||||
VIR_FREE(bridge);
|
VIR_FREE(bridge);
|
||||||
VIR_FREE(model);
|
VIR_FREE(model);
|
||||||
@ -8536,6 +8654,67 @@ virDomainFSDefFormat(virBufferPtr buf,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
virDomainActualNetDefFormat(virBufferPtr buf,
|
||||||
|
virDomainActualNetDefPtr def)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
const char *type;
|
||||||
|
const char *mode;
|
||||||
|
|
||||||
|
if (!def)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
type = virDomainNetTypeToString(def->type);
|
||||||
|
if (!type) {
|
||||||
|
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("unexpected net type %d"), def->type);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (def->type != VIR_DOMAIN_NET_TYPE_BRIDGE &&
|
||||||
|
def->type != VIR_DOMAIN_NET_TYPE_DIRECT) {
|
||||||
|
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("unexpected net type %s"), type);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
virBufferAsprintf(buf, " <actual type='%s'>\n", type);
|
||||||
|
|
||||||
|
switch (def->type) {
|
||||||
|
case VIR_DOMAIN_NET_TYPE_BRIDGE:
|
||||||
|
if (def->data.bridge.brname) {
|
||||||
|
virBufferEscapeString(buf, " <source bridge='%s'/>\n",
|
||||||
|
def->data.bridge.brname);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VIR_DOMAIN_NET_TYPE_DIRECT:
|
||||||
|
virBufferAddLit(buf, " <source");
|
||||||
|
if (def->data.direct.linkdev)
|
||||||
|
virBufferEscapeString(buf, " dev='%s'",
|
||||||
|
def->data.direct.linkdev);
|
||||||
|
|
||||||
|
mode = virMacvtapModeTypeToString(def->data.direct.mode);
|
||||||
|
if (!mode) {
|
||||||
|
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("unexpected source mode %d"),
|
||||||
|
def->data.direct.mode);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
virBufferAsprintf(buf, " mode='%s'/>\n", mode);
|
||||||
|
virVirtualPortProfileFormat(buf, def->data.direct.virtPortProfile,
|
||||||
|
" ");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
virBufferAddLit(buf, " </actual>\n");
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
error:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virDomainNetDefFormat(virBufferPtr buf,
|
virDomainNetDefFormat(virBufferPtr buf,
|
||||||
virDomainNetDefPtr def,
|
virDomainNetDefPtr def,
|
||||||
@ -8559,8 +8738,18 @@ virDomainNetDefFormat(virBufferPtr buf,
|
|||||||
|
|
||||||
switch (def->type) {
|
switch (def->type) {
|
||||||
case VIR_DOMAIN_NET_TYPE_NETWORK:
|
case VIR_DOMAIN_NET_TYPE_NETWORK:
|
||||||
virBufferEscapeString(buf, " <source network='%s'/>\n",
|
virBufferEscapeString(buf, " <source network='%s'",
|
||||||
def->data.network.name);
|
def->data.network.name);
|
||||||
|
if (def->data.network.portgroup) {
|
||||||
|
virBufferEscapeString(buf, " portgroup='%s'",
|
||||||
|
def->data.network.portgroup);
|
||||||
|
}
|
||||||
|
virBufferAddLit(buf, "/>\n");
|
||||||
|
virVirtualPortProfileFormat(buf, def->data.network.virtPortProfile,
|
||||||
|
" ");
|
||||||
|
if ((flags & VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET) &&
|
||||||
|
(virDomainActualNetDefFormat(buf, def->data.network.actual) < 0))
|
||||||
|
return -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_NET_TYPE_ETHERNET:
|
case VIR_DOMAIN_NET_TYPE_ETHERNET:
|
||||||
@ -9445,9 +9634,11 @@ virDomainHostdevDefFormat(virBufferPtr buf,
|
|||||||
VIR_DOMAIN_XML_INACTIVE | \
|
VIR_DOMAIN_XML_INACTIVE | \
|
||||||
VIR_DOMAIN_XML_UPDATE_CPU)
|
VIR_DOMAIN_XML_UPDATE_CPU)
|
||||||
|
|
||||||
verify((VIR_DOMAIN_XML_INTERNAL_STATUS & DUMPXML_FLAGS) == 0);
|
verify(((VIR_DOMAIN_XML_INTERNAL_STATUS |
|
||||||
|
VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET)
|
||||||
|
& DUMPXML_FLAGS) == 0);
|
||||||
|
|
||||||
/* This internal version can accept VIR_DOMAIN_XML_INTERNAL_STATUS,
|
/* This internal version can accept VIR_DOMAIN_XML_INTERNAL_*,
|
||||||
* whereas the public version cannot. */
|
* whereas the public version cannot. */
|
||||||
static char *
|
static char *
|
||||||
virDomainDefFormatInternal(virDomainDefPtr def,
|
virDomainDefFormatInternal(virDomainDefPtr def,
|
||||||
@ -9459,7 +9650,10 @@ virDomainDefFormatInternal(virDomainDefPtr def,
|
|||||||
const char *type = NULL;
|
const char *type = NULL;
|
||||||
int n, allones = 1;
|
int n, allones = 1;
|
||||||
|
|
||||||
virCheckFlags(DUMPXML_FLAGS | VIR_DOMAIN_XML_INTERNAL_STATUS, NULL);
|
virCheckFlags(DUMPXML_FLAGS |
|
||||||
|
VIR_DOMAIN_XML_INTERNAL_STATUS |
|
||||||
|
VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET,
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (!(type = virDomainVirtTypeToString(def->virtType))) {
|
if (!(type = virDomainVirtTypeToString(def->virtType))) {
|
||||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
@ -10024,7 +10218,10 @@ int virDomainSaveStatus(virCapsPtr caps,
|
|||||||
const char *statusDir,
|
const char *statusDir,
|
||||||
virDomainObjPtr obj)
|
virDomainObjPtr obj)
|
||||||
{
|
{
|
||||||
unsigned int flags = VIR_DOMAIN_XML_SECURE|VIR_DOMAIN_XML_INTERNAL_STATUS;
|
unsigned int flags = (VIR_DOMAIN_XML_SECURE |
|
||||||
|
VIR_DOMAIN_XML_INTERNAL_STATUS |
|
||||||
|
VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET);
|
||||||
|
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
char *xml;
|
char *xml;
|
||||||
|
|
||||||
@ -10115,7 +10312,8 @@ static virDomainObjPtr virDomainLoadStatus(virCapsPtr caps,
|
|||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!(obj = virDomainObjParseFile(caps, statusFile, expectedVirtTypes,
|
if (!(obj = virDomainObjParseFile(caps, statusFile, expectedVirtTypes,
|
||||||
VIR_DOMAIN_XML_INTERNAL_STATUS)))
|
VIR_DOMAIN_XML_INTERNAL_STATUS |
|
||||||
|
VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET)))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
virUUIDFormat(obj->def->uuid, uuidstr);
|
virUUIDFormat(obj->def->uuid, uuidstr);
|
||||||
@ -11112,3 +11310,68 @@ virDomainStateReasonFromString(virDomainState state, const char *reason)
|
|||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Some access functions to gloss over the difference between NetDef
|
||||||
|
* (<interface>) and ActualNetDef (<actual>). If the NetDef has an
|
||||||
|
* ActualNetDef, return the requested value from the ActualNetDef,
|
||||||
|
* otherwise return the value from the NetDef.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
virDomainNetGetActualType(virDomainNetDefPtr iface)
|
||||||
|
{
|
||||||
|
if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK)
|
||||||
|
return iface->type;
|
||||||
|
if (!iface->data.network.actual)
|
||||||
|
return iface->type;
|
||||||
|
return iface->data.network.actual->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
virDomainNetGetActualBridgeName(virDomainNetDefPtr iface)
|
||||||
|
{
|
||||||
|
if (iface->type == VIR_DOMAIN_NET_TYPE_BRIDGE)
|
||||||
|
return iface->data.bridge.brname;
|
||||||
|
if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK)
|
||||||
|
return NULL;
|
||||||
|
if (!iface->data.network.actual)
|
||||||
|
return NULL;
|
||||||
|
return iface->data.network.actual->data.bridge.brname;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
virDomainNetGetActualDirectDev(virDomainNetDefPtr iface)
|
||||||
|
{
|
||||||
|
if (iface->type == VIR_DOMAIN_NET_TYPE_DIRECT)
|
||||||
|
return iface->data.direct.linkdev;
|
||||||
|
if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK)
|
||||||
|
return NULL;
|
||||||
|
if (!iface->data.network.actual)
|
||||||
|
return NULL;
|
||||||
|
return iface->data.network.actual->data.direct.linkdev;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
virDomainNetGetActualDirectMode(virDomainNetDefPtr iface)
|
||||||
|
{
|
||||||
|
if (iface->type == VIR_DOMAIN_NET_TYPE_DIRECT)
|
||||||
|
return iface->data.direct.mode;
|
||||||
|
if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK)
|
||||||
|
return 0;
|
||||||
|
if (!iface->data.network.actual)
|
||||||
|
return 0;
|
||||||
|
return iface->data.network.actual->data.direct.mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
virVirtualPortProfileParamsPtr
|
||||||
|
virDomainNetGetActualDirectVirtPortProfile(virDomainNetDefPtr iface)
|
||||||
|
{
|
||||||
|
if (iface->type == VIR_DOMAIN_NET_TYPE_DIRECT)
|
||||||
|
return iface->data.direct.virtPortProfile;
|
||||||
|
if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK)
|
||||||
|
return NULL;
|
||||||
|
if (!iface->data.network.actual)
|
||||||
|
return NULL;
|
||||||
|
return iface->data.network.actual->data.direct.virtPortProfile;
|
||||||
|
}
|
||||||
|
@ -343,6 +343,27 @@ enum virDomainNetVirtioTxModeType {
|
|||||||
VIR_DOMAIN_NET_VIRTIO_TX_MODE_LAST,
|
VIR_DOMAIN_NET_VIRTIO_TX_MODE_LAST,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Config that was actually used to bring up interface, after
|
||||||
|
* resolving network reference. This is private data, only used within
|
||||||
|
* libvirt, but still must maintain backward compatibility, because
|
||||||
|
* different versions of libvirt may read the same data file.
|
||||||
|
*/
|
||||||
|
typedef struct _virDomainActualNetDef virDomainActualNetDef;
|
||||||
|
typedef virDomainActualNetDef *virDomainActualNetDefPtr;
|
||||||
|
struct _virDomainActualNetDef {
|
||||||
|
int type; /* enum virDomainNetType */
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
char *brname;
|
||||||
|
} bridge;
|
||||||
|
struct {
|
||||||
|
char *linkdev;
|
||||||
|
int mode; /* enum virMacvtapMode from util/macvtap.h */
|
||||||
|
virVirtualPortProfileParamsPtr virtPortProfile;
|
||||||
|
} direct;
|
||||||
|
} data;
|
||||||
|
};
|
||||||
|
|
||||||
/* Stores the virtual network interface configuration */
|
/* Stores the virtual network interface configuration */
|
||||||
typedef struct _virDomainNetDef virDomainNetDef;
|
typedef struct _virDomainNetDef virDomainNetDef;
|
||||||
typedef virDomainNetDef *virDomainNetDefPtr;
|
typedef virDomainNetDef *virDomainNetDefPtr;
|
||||||
@ -369,6 +390,17 @@ struct _virDomainNetDef {
|
|||||||
} socket; /* any of NET_CLIENT or NET_SERVER or NET_MCAST */
|
} socket; /* any of NET_CLIENT or NET_SERVER or NET_MCAST */
|
||||||
struct {
|
struct {
|
||||||
char *name;
|
char *name;
|
||||||
|
char *portgroup;
|
||||||
|
virVirtualPortProfileParamsPtr virtPortProfile;
|
||||||
|
/* actual has info about the currently used physical
|
||||||
|
* device (if the network is of type
|
||||||
|
* bridge/private/vepa/passthrough). This is saved in the
|
||||||
|
* domain state, but never written to persistent config,
|
||||||
|
* since it needs to be re-allocated whenever the domain
|
||||||
|
* is restarted. It is also never shown to the user, and
|
||||||
|
* the user cannot specify it in XML documents.
|
||||||
|
*/
|
||||||
|
virDomainActualNetDefPtr actual;
|
||||||
} network;
|
} network;
|
||||||
struct {
|
struct {
|
||||||
char *brname;
|
char *brname;
|
||||||
@ -1340,6 +1372,7 @@ void virDomainDiskDefFree(virDomainDiskDefPtr def);
|
|||||||
void virDomainDiskHostDefFree(virDomainDiskHostDefPtr def);
|
void virDomainDiskHostDefFree(virDomainDiskHostDefPtr def);
|
||||||
void virDomainControllerDefFree(virDomainControllerDefPtr def);
|
void virDomainControllerDefFree(virDomainControllerDefPtr def);
|
||||||
void virDomainFSDefFree(virDomainFSDefPtr def);
|
void virDomainFSDefFree(virDomainFSDefPtr def);
|
||||||
|
void virDomainActualNetDefFree(virDomainActualNetDefPtr def);
|
||||||
void virDomainNetDefFree(virDomainNetDefPtr def);
|
void virDomainNetDefFree(virDomainNetDefPtr def);
|
||||||
void virDomainSmartcardDefFree(virDomainSmartcardDefPtr def);
|
void virDomainSmartcardDefFree(virDomainSmartcardDefPtr def);
|
||||||
void virDomainChrDefFree(virDomainChrDefPtr def);
|
void virDomainChrDefFree(virDomainChrDefPtr def);
|
||||||
@ -1450,6 +1483,13 @@ int virDomainNetIndexByMac(virDomainDefPtr def, const unsigned char *mac);
|
|||||||
int virDomainNetInsert(virDomainDefPtr def, virDomainNetDefPtr net);
|
int virDomainNetInsert(virDomainDefPtr def, virDomainNetDefPtr net);
|
||||||
int virDomainNetRemoveByMac(virDomainDefPtr def, const unsigned char *mac);
|
int virDomainNetRemoveByMac(virDomainDefPtr def, const unsigned char *mac);
|
||||||
|
|
||||||
|
int virDomainNetGetActualType(virDomainNetDefPtr iface);
|
||||||
|
char *virDomainNetGetActualBridgeName(virDomainNetDefPtr iface);
|
||||||
|
char *virDomainNetGetActualDirectDev(virDomainNetDefPtr iface);
|
||||||
|
int virDomainNetGetActualDirectMode(virDomainNetDefPtr iface);
|
||||||
|
virVirtualPortProfileParamsPtr
|
||||||
|
virDomainNetGetActualDirectVirtPortProfile(virDomainNetDefPtr iface);
|
||||||
|
|
||||||
int virDomainControllerInsert(virDomainDefPtr def,
|
int virDomainControllerInsert(virDomainDefPtr def,
|
||||||
virDomainControllerDefPtr controller);
|
virDomainControllerDefPtr controller);
|
||||||
void virDomainControllerInsertPreAlloced(virDomainDefPtr def,
|
void virDomainControllerInsertPreAlloced(virDomainDefPtr def,
|
||||||
|
@ -228,6 +228,7 @@ virDomainAuditVcpu;
|
|||||||
# domain_conf.h
|
# domain_conf.h
|
||||||
virDiskNameToBusDeviceIndex;
|
virDiskNameToBusDeviceIndex;
|
||||||
virDiskNameToIndex;
|
virDiskNameToIndex;
|
||||||
|
virDomainActualNetDefFree;
|
||||||
virDomainAssignDef;
|
virDomainAssignDef;
|
||||||
virDomainChrConsoleTargetTypeFromString;
|
virDomainChrConsoleTargetTypeFromString;
|
||||||
virDomainChrConsoleTargetTypeToString;
|
virDomainChrConsoleTargetTypeToString;
|
||||||
@ -334,6 +335,11 @@ virDomainLoadAllConfigs;
|
|||||||
virDomainMemballoonModelTypeFromString;
|
virDomainMemballoonModelTypeFromString;
|
||||||
virDomainMemballoonModelTypeToString;
|
virDomainMemballoonModelTypeToString;
|
||||||
virDomainNetDefFree;
|
virDomainNetDefFree;
|
||||||
|
virDomainNetGetActualBridgeName;
|
||||||
|
virDomainNetGetActualDirectDev;
|
||||||
|
virDomainNetGetActualDirectMode;
|
||||||
|
virDomainNetGetActualType;
|
||||||
|
virDomainNetGetActualDirectVirtPortProfile;
|
||||||
virDomainNetIndexByMac;
|
virDomainNetIndexByMac;
|
||||||
virDomainNetInsert;
|
virDomainNetInsert;
|
||||||
virDomainNetRemoveByMac;
|
virDomainNetRemoveByMac;
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
<domain type='qemu'>
|
||||||
|
<name>QEMUGuest1</name>
|
||||||
|
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
||||||
|
<memory>219136</memory>
|
||||||
|
<currentMemory>219136</currentMemory>
|
||||||
|
<vcpu>1</vcpu>
|
||||||
|
<os>
|
||||||
|
<type arch='i686' machine='pc'>hvm</type>
|
||||||
|
<boot dev='hd'/>
|
||||||
|
</os>
|
||||||
|
<clock offset='utc'/>
|
||||||
|
<on_poweroff>destroy</on_poweroff>
|
||||||
|
<on_reboot>restart</on_reboot>
|
||||||
|
<on_crash>destroy</on_crash>
|
||||||
|
<devices>
|
||||||
|
<emulator>/usr/bin/qemu</emulator>
|
||||||
|
<disk type='block' device='disk'>
|
||||||
|
<source dev='/dev/HostVG/QEMUGuest1'/>
|
||||||
|
<target dev='hda' bus='ide'/>
|
||||||
|
<address type='drive' controller='0' bus='0' unit='0'/>
|
||||||
|
</disk>
|
||||||
|
<controller type='ide' index='0'/>
|
||||||
|
<interface type='network'>
|
||||||
|
<mac address='00:11:22:33:44:55'/>
|
||||||
|
<source network='rednet' portgroup='bob'/>
|
||||||
|
<virtualport type='802.1Qbg'>
|
||||||
|
<parameters managerid='11' typeid='1193047' typeidversion='2' instanceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/>
|
||||||
|
</virtualport>
|
||||||
|
<model type='virtio'/>
|
||||||
|
</interface>
|
||||||
|
<memballoon model='virtio'/>
|
||||||
|
</devices>
|
||||||
|
</domain>
|
@ -158,6 +158,7 @@ mymain(void)
|
|||||||
DO_TEST("net-virtio-device");
|
DO_TEST("net-virtio-device");
|
||||||
DO_TEST("net-eth");
|
DO_TEST("net-eth");
|
||||||
DO_TEST("net-eth-ifname");
|
DO_TEST("net-eth-ifname");
|
||||||
|
DO_TEST("net-virtio-network-portgroup");
|
||||||
DO_TEST("sound");
|
DO_TEST("sound");
|
||||||
|
|
||||||
DO_TEST("serial-vc");
|
DO_TEST("serial-vc");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user