<pre>
...
<devices>
- <interface type='bridge'>
- <source bridge='xenbr0'/>
- <mac address='00:16:3e:5d:c7:9e'/>
- <script path='vif-bridge'/>
+ <interface type='direct' trustGuestRxFilters='yes'>
+ <source dev='eth0'/>
+ <mac address='52:54:00:5d:c7:9e'/>
<boot order='1'/>
<rom bar='off'/>
</interface>
<p>
There are several possibilities for specifying a network
interface visible to the guest. Each subsection below provides
- more details about common setup options. Additionally,
- each <code><interface></code> element has an
+ more details about common setup options.
+ </p>
+ <p>
+ <span class="since">Since 1.2.10</span>),
+ the <code>interface</code> element
+ property <code>trustGuestRxFilters</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 ddevice model and for macvtap
+ connections on the host.
+ </p>
+ <p>
+ Each <code><interface></code> element has an
optional <code><address></code> sub-element that can tie
the interface to a particular pci slot, with
attribute <code>type='pci'</code>
being the default mode. The individual modes cause the delivery of
packets to behave as follows:
</p>
+ <p>
+ If the model type is set to <code>virtio</code> and
+ interface's <code>trustGuestRxFilters</code> attribute is set
+ to <code>yes</code>, changes made to the interface mac address,
+ unicast/multicast receive filters, and vlan settings in the
+ guest will be monitored and propagated to the associated macvtap
+ device on the host (<span class="since">Since
+ 1.2.10</span>). If <code>trustGuestRxFilters</code> is not set,
+ or is not supported for the device model in use, an attempted
+ change to the mac address originating from the guest side will
+ result in a non-working network connection.
+ </p>
<dl>
<dt><code>vepa</code></dt>
...
<devices>
...
- <interface type='direct'>
+ <interface type='direct' trustGuestRxFilters='no'>
<source dev='eth0' mode='vepa'/>
</interface>
</devices>
</p>
<pre>
- <network ipv6='yes'>
+ <network ipv6='yes' trustGuestRxFilters='no'>
<name>default</name>
<uuid>3e3fce45-4f53-4fa7-bb32-11f34168b82b</uuid>
...</pre>
to have guest-to-guest communications. For further information,
see the example below for the example with no gateway addresses.
<span class="since">Since 1.0.1</span></dd>
+ <dt><code>trustGuestRxFilters='yes'</code></dt>
+ <dd>The optional parameter <code>trustGuestRxFilters</code> can
+ be used to set that attribute of the same name for each domain
+ interface connected to this network (<span class="since">since
+ 1.2.10</span>). See
+ the <a href="formatdomain.html#elementSNICS">Network
+ interfaces</a> section of the domain XML documentation for
+ more details. Note that an explicit setting of this attribute
+ in a portgroup or the individual domain interface will
+ override the setting in the network.</dd>
</dl>
<h3><a name="elementsConnect">Connectivity</a></h3>
<outbound average='1000' peak='5000' burst='5120'/>
</bandwidth>
</portgroup></b>
- <b><portgroup name='sales'>
+ <b><portgroup name='sales' trustGuestRxFilters='no'>
<virtualport type='802.1Qbh'>
<parameters profileid='salestest'/>
</virtualport>
network can have multiple portgroup elements (and one of those
can optionally be designated as the 'default' portgroup for the
network), and each portgroup has a name, as well as various
- subelements associated with it. The currently supported
+ attributes and subelements associated with it. The currently supported
subelements are <code><bandwidth></code>
(described <a href="formatnetwork.html#elementQoS">here</a>)
and <code><virtualport></code>
considered an error, and will prevent the interface from
starting.
</p>
+ <p>
+ portgroups also support the optional
+ parameter <code>trustGuestRxFilters</code> which can be used to
+ set that attribute of the same name for each domain interface
+ using this portgroup (<span class="since">since
+ 1.2.10</span>). See
+ the <a href="formatdomain.html#elementSNICS">Network
+ interfaces</a> section of the domain XML documentation for more
+ details. Note that an explicit setting of this attribute in the
+ portgroup overrides the network-wide setting, and an explicit
+ setting in the individual domain interface will override the
+ setting in the portgroup.
+ </p>
<h5><a name="elementsStaticroute">Static Routes</a></h5>
<p>
</interleave>
</group>
</choice>
+ <optional>
+ <attribute name="trustGuestRxFilters">
+ <ref name="virYesNo"/>
+ </attribute>
+ </optional>
</element>
</define>
<!--
<ref name="virYesNo"/>
</attribute>
</optional>
+ <optional>
+ <attribute name="trustGuestRxFilters">
+ <ref name="virYesNo"/>
+ </attribute>
+ </optional>
<interleave>
<!-- The name of the network, used to refer to it through the API
<ref name="virYesNo"/>
</attribute>
</optional>
+ <optional>
+ <attribute name="trustGuestRxFilters">
+ <ref name="virYesNo"/>
+ </attribute>
+ </optional>
<interleave>
<optional>
<ref name="virtualPortProfile"/>
char *type = NULL;
char *mode = NULL;
char *addrtype = NULL;
+ char *trustGuestRxFilters = NULL;
if (VIR_ALLOC(actual) < 0)
return -1;
goto error;
}
+ trustGuestRxFilters = virXMLPropString(node, "trustGuestRxFilters");
+ if (trustGuestRxFilters &&
+ ((actual->trustGuestRxFilters
+ = virTristateBoolTypeFromString(trustGuestRxFilters)) <= 0)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unknown trustGuestRxFilters value '%s'"),
+ trustGuestRxFilters);
+ goto error;
+ }
+
virtPortNode = virXPathNode("./virtualport", ctxt);
if (virtPortNode) {
if (actual->type == VIR_DOMAIN_NET_TYPE_BRIDGE ||
VIR_FREE(type);
VIR_FREE(mode);
VIR_FREE(addrtype);
+ VIR_FREE(trustGuestRxFilters);
virDomainActualNetDefFree(actual);
ctxt->node = save_ctxt;
char *vhostuser_mode = NULL;
char *vhostuser_path = NULL;
char *vhostuser_type = NULL;
+ char *trustGuestRxFilters = NULL;
virNWFilterHashTablePtr filterparams = NULL;
virDomainActualNetDefPtr actual = NULL;
xmlNodePtr oldnode = ctxt->node;
def->type = VIR_DOMAIN_NET_TYPE_USER;
}
+ trustGuestRxFilters = virXMLPropString(node, "trustGuestRxFilters");
+ if (trustGuestRxFilters &&
+ ((def->trustGuestRxFilters
+ = virTristateBoolTypeFromString(trustGuestRxFilters)) <= 0)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unknown trustGuestRxFilters value '%s'"),
+ trustGuestRxFilters);
+ goto error;
+ }
+
cur = node->children;
while (cur != NULL) {
if (cur->type == XML_ELEMENT_NODE) {
VIR_FREE(mode);
VIR_FREE(linkstate);
VIR_FREE(addrtype);
+ VIR_FREE(trustGuestRxFilters);
virNWFilterHashTableFree(filterparams);
return def;
if (hostdef && hostdef->managed)
virBufferAddLit(buf, " managed='yes'");
}
+ if (def->trustGuestRxFilters)
+ virBufferAsprintf(buf, " trustGuestRxFilters='%s'",
+ virTristateBoolTypeToString(def->trustGuestRxFilters));
virBufferAddLit(buf, ">\n");
virBufferAdjustIndent(buf, 2);
virBufferAsprintf(buf, "<interface type='%s'", typeStr);
if (hostdef && hostdef->managed)
virBufferAddLit(buf, " managed='yes'");
+ if (def->trustGuestRxFilters)
+ virBufferAsprintf(buf, " trustGuestRxFilters='%s'",
+ virTristateBoolTypeToString(def->trustGuestRxFilters));
virBufferAddLit(buf, ">\n");
virBufferAdjustIndent(buf, 2);
return NULL;
}
+
+bool
+virDomainNetGetActualTrustGuestRxFilters(virDomainNetDefPtr iface)
+{
+ if (iface->type == VIR_DOMAIN_NET_TYPE_NETWORK &&
+ iface->data.network.actual)
+ return (iface->data.network.actual->trustGuestRxFilters
+ == VIR_TRISTATE_BOOL_YES);
+ return iface->trustGuestRxFilters == VIR_TRISTATE_BOOL_YES;
+}
+
+
/* Return listens[i] from the appropriate union for the graphics
* type, or NULL if this is an unsuitable type, or the index is out of
* bounds. If force0 is TRUE, i == 0, and there is no listen array,
virNetDevVPortProfilePtr virtPortProfile;
virNetDevBandwidthPtr bandwidth;
virNetDevVlan vlan;
+ int trustGuestRxFilters; /* enum virTristateBool */
unsigned int class_id; /* class ID for bandwidth 'floor' */
};
virNWFilterHashTablePtr filterparams;
virNetDevBandwidthPtr bandwidth;
virNetDevVlan vlan;
+ int trustGuestRxFilters; /* enum virTristateBool */
int linkstate;
};
virNetDevBandwidthPtr
virDomainNetGetActualBandwidth(virDomainNetDefPtr iface);
virNetDevVlanPtr virDomainNetGetActualVlan(virDomainNetDefPtr iface);
+bool virDomainNetGetActualTrustGuestRxFilters(virDomainNetDefPtr iface);
int virDomainControllerInsert(virDomainDefPtr def,
virDomainControllerDefPtr controller)
xmlNodePtr vlanNode;
xmlNodePtr bandwidth_node;
char *isDefault = NULL;
+ char *trustGuestRxFilters = NULL;
int result = -1;
isDefault = virXPathString("string(./@default)", ctxt);
def->isDefault = isDefault && STRCASEEQ(isDefault, "yes");
+ trustGuestRxFilters
+ = virXPathString("string(./@trustGuestRxFilters)", ctxt);
+ if (trustGuestRxFilters) {
+ if ((def->trustGuestRxFilters
+ = virTristateBoolTypeFromString(trustGuestRxFilters)) <= 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Invalid trustGuestRxFilters setting '%s' "
+ "in portgroup"), trustGuestRxFilters);
+ goto cleanup;
+ }
+ }
+
virtPortNode = virXPathNode("./virtualport", ctxt);
if (virtPortNode &&
(!(def->virtPortProfile = virNetDevVPortProfileParse(virtPortNode, 0)))) {
virPortGroupDefClear(def);
}
VIR_FREE(isDefault);
+ VIR_FREE(trustGuestRxFilters);
ctxt->node = save;
return result;
xmlNodePtr virtPortNode = NULL;
xmlNodePtr forwardNode = NULL;
char *ipv6nogwStr = NULL;
+ char *trustGuestRxFilters = NULL;
xmlNodePtr save = ctxt->node;
xmlNodePtr bandwidthNode = NULL;
xmlNodePtr vlanNode;
VIR_FREE(ipv6nogwStr);
}
+ trustGuestRxFilters
+ = virXPathString("string(./@trustGuestRxFilters)", ctxt);
+ if (trustGuestRxFilters) {
+ if ((def->trustGuestRxFilters
+ = virTristateBoolTypeFromString(trustGuestRxFilters)) <= 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Invalid trustGuestRxFilters setting '%s' "
+ "in network '%s'"),
+ trustGuestRxFilters, def->name);
+ goto error;
+ }
+ VIR_FREE(trustGuestRxFilters);
+ }
+
/* Parse network domain information */
def->domain = virXPathString("string(./domain[1]/@name)", ctxt);
VIR_FREE(ipNodes);
VIR_FREE(portGroupNodes);
VIR_FREE(ipv6nogwStr);
+ VIR_FREE(trustGuestRxFilters);
ctxt->node = save;
return NULL;
}
if (def->isDefault) {
virBufferAddLit(buf, " default='yes'");
}
+ if (def->trustGuestRxFilters)
+ virBufferAsprintf(buf, " trustGuestRxFilters='%s'",
+ virTristateBoolTypeToString(def->trustGuestRxFilters));
virBufferAddLit(buf, ">\n");
virBufferAdjustIndent(buf, 2);
if (virNetDevVlanFormat(&def->vlan, buf) < 0)
}
if (def->ipv6nogw)
virBufferAddLit(buf, " ipv6='yes'");
+ if (def->trustGuestRxFilters)
+ virBufferAsprintf(buf, " trustGuestRxFilters='%s'",
+ virTristateBoolTypeToString(def->trustGuestRxFilters));
virBufferAddLit(buf, ">\n");
virBufferAdjustIndent(buf, 2);
virBufferEscapeString(buf, "<name>%s</name>\n", def->name);
virNetDevVPortProfilePtr virtPortProfile;
virNetDevBandwidthPtr bandwidth;
virNetDevVlan vlan;
+ int trustGuestRxFilters; /* enum virTristateBool */
};
typedef struct _virNetworkDef virNetworkDef;
virPortGroupDefPtr portGroups;
virNetDevBandwidthPtr bandwidth;
virNetDevVlan vlan;
+ int trustGuestRxFilters; /* enum virTristateBool */
};
typedef struct _virNetworkObj virNetworkObj;
virDomainNetGetActualDirectDev;
virDomainNetGetActualDirectMode;
virDomainNetGetActualHostdev;
+virDomainNetGetActualTrustGuestRxFilters;
virDomainNetGetActualType;
virDomainNetGetActualVirtPortProfile;
virDomainNetGetActualVlan;
-<network>
+<network trustGuestRxFilters="no">
<name>vepa-net</name>
<uuid>81ff0d90-c91e-6742-64da-4a736edb9a8b</uuid>
<forward mode="vepa">
<parameters typeid="2193047" typeidversion="3"/>
</virtualport>
</portgroup>
- <portgroup name="alice">
+ <portgroup name="alice" trustGuestRxFilters="yes">
<virtualport type="802.1Qbg">
<parameters managerid="13"/>
</virtualport>
-<network>
+<network trustGuestRxFilters='no'>
<name>vepa-net</name>
<uuid>81ff0d90-c91e-6742-64da-4a736edb9a8b</uuid>
<forward dev='eth1' mode='vepa'>
<parameters typeid='2193047' typeidversion='3'/>
</virtualport>
</portgroup>
- <portgroup name='alice'>
+ <portgroup name='alice' trustGuestRxFilters='yes'>
<virtualport type='802.1Qbg'>
<parameters managerid='13'/>
</virtualport>
<controller type='usb' index='0'/>
<controller type='ide' index='0'/>
<controller type='pci' index='0' model='pci-root'/>
- <interface type='network'>
+ <interface type='network' trustGuestRxFilters='yes'>
<mac address='00:11:22:33:44:55'/>
<source network='rednet' portgroup='bob'/>
<vlan>
</virtualport>
<model type='virtio'/>
</interface>
- <interface type='network'>
+ <interface type='network' trustGuestRxFilters='no'>
<mac address='10:11:22:33:44:55'/>
<source network='blue' portgroup='sam'/>
<virtualport>