From: Laine Stump direct network connections (described
- below), a connection of type network may specify
- a virtportprofile element, with configuration data
- to be forwarded to a vepa or 802.1Qbh compliant switch.
+ connections. Since 0.9.4.
+
+ Also, similar to direct network connections
+ (described below), a connection of type network may
+ specify a virtualport element, with configuration
+ data to be forwarded to a vepa (802.1Qbg) or 802.1Qbh compliant
+ switch (Since 0.8.2), or to an
+ Open vSwitch virtual switch (Since
+ 0.9.11).
+
+ Since the actual type of switch may vary depending on the
+ configuration in the <network> on the host,
+ it is acceptable to omit the virtualport type
+ attribute, and specify attributes from multiple different
+ virtualport types (and also to leave out certain attributes); at
+ domain startup time, a complete <virtualport>
+ element will be constructed by merging together the type and
+ attributes found in the which will be filled in from the network
+ or portgroup <virtualport>)
+ (Since 0.10.0). For example, in order
+ to work properly with both an 802.1Qbh switch and an Open vSwitch
+ switch, you may choose to specify no type, but both
+ an instanceid (in case the switch is 802.1Qbh) and
+ an interfaceid (in case the switch is Open vSwitch)
+ (you may also omit the other attributes, such as managerid,
+ typeid, or profileid, to be filled in from the
+ network's <virtualport>). If you want to
+ limit a guest to connecting only to certain types of switches,
+ you can specify the virtualport type, but still omit some/all of
+ the parameters - in this case if the host's network has a
+ different type of virtualport, connection of the interface will
+ fail.
@@ -2248,8 +2277,8 @@
<source network='default' portgroup='engineering'/>
<target dev='vnet7'/>
<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>
+ <parameters instanceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/>
</virtualport>
</interface>
@@ -2261,7 +2290,7 @@
This is the recommended config for general guest connectivity on
- hosts with static wired networking configs
+ hosts with static wired networking configs.
@@ -2276,19 +2305,40 @@
configuration is whatever is used on the LAN. This provides the guest VM
full incoming & outgoing net access just like a physical machine.
-
+
+ On Linux systems, the bridge device is normally a standard Linux
+ host bridge. On hosts that support Open vSwitch, it is also
+ possible to connect to an open vSwitch bridge device by adding
+ a <virtualport type='openvswitch'/> to the
+ interface definition. (Since
+ 0.9.11). The Open vSwitch type virtualport accepts two
+ parameters in its <parameters> element -
+ an interfaceid which is a standard uuid used to
+ uniquely identify this particular interface to Open vSwitch (if
+ you do no specify one, a random interfaceid will be generated
+ for you when you first define the interface), and an
+ optional profileid which is sent to Open vSwitch as
+ the interfaces "port-profile".
+
...
<devices>
+ ...
<interface type='bridge'>
<source bridge='br0'/>
</interface>
- ...
<interface type='bridge'>
- <source bridge='br0'/>
+ <source bridge='br1'/>
<target dev='vnet7'/>
<mac address="00:11:22:33:44:55"/>
</interface>
+ <interface type='bridge'>
+ <source bridge='ovsbr'/>
+ <virtualport type='openvswitch'/>
+ <parameters profileid='menial' interfaceid='09b11c53-8b5c-4eeb-8f00-d84eaa0aaa4f'/>
+ </virtualport>
+ </interface>
+ ...
</devices>
...
diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
index 7e8e991b4b..daa6524f0f 100644
--- a/docs/formatnetwork.html.in
+++ b/docs/formatnetwork.html.in
@@ -147,10 +147,17 @@
This network describes either 1) an existing host bridge
that was configured outside of libvirt (if
a <bridge name='xyz'/> element has been
- specified), or 2) an interface or group of interfaces to
- be used for a "direct" connection via macvtap using
- macvtap's "bridge" mode (if the forward element has one or
- more <interface> subelements)
+ specified, Since 0.9.4), 2) an
+ existing Open vSwitch bridge that was configured outside of
+ libvirt (if both a <bridge name='xyz'/>
+ element and a <virtualport
+ type='openvswitch'/> have been
+ specified Since 0.10.0) 3) an
+ interface or group of interfaces to be used for a "direct"
+ connection via macvtap using macvtap's "bridge" mode (if
+ the forward element has one or
+ more <interface>
+ subelements, Since 0.9.4)
(see Direct
attachment to physical interface for descriptions of
the various macvtap modes). libvirt doesn't attempt to
@@ -337,9 +344,15 @@
default portgroup will be used. If no portgroup is given in the
interface definition, and there is no default portgroup, then
none will be used. Any <bandwidth>
- or <virtualport> specified directly in the
- domain XML will take precedence over any setting in the chosen
- portgroup.
+
+ specified directly in the domain XML will take precedence over
+ any setting in the chosen portgroup. if
+ a <virtualport> is specified in the portgroup
+ (and/or directly in the network definition), the multiple
+ virtualports will be merged, and any parameter that is specified
+ in more than one virtualport, and is not identical, will be
+ considered an error, and will prevent the interface from
+ starting.
Addressing
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index d9646fb5d9..ec99e4dceb 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -61,6 +61,7 @@
#include "virnetdev.h"
#include "virnetdevbridge.h"
#include "virnetdevtap.h"
+#include "virnetdevvportprofile.h"
#define NETWORK_PID_DIR LOCALSTATEDIR "/run/libvirt/network"
#define NETWORK_STATE_DIR LOCALSTATEDIR "/lib/libvirt/network"
@@ -2746,6 +2747,8 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
virNetworkObjPtr network;
virNetworkDefPtr netdef;
virPortGroupDefPtr portgroup;
+ virNetDevVPortProfilePtr virtport = NULL;
+ virNetworkForwardIfDefPtr dev = NULL;
unsigned int num_virt_fns = 0;
char **vfname = NULL;
int ii;
@@ -2820,11 +2823,33 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
goto cleanup;
}
+ /* merge virtualports from interface, network, and portgroup to
+ * arrive at actual virtualport to use
+ */
+ if (virNetDevVPortProfileMerge3(&iface->data.network.actual->virtPortProfile,
+ iface->virtPortProfile,
+ netdef->virtPortProfile,
+ portgroup
+ ? portgroup->virtPortProfile : NULL) < 0) {
+ goto cleanup;
+ }
+ virtport = iface->data.network.actual->virtPortProfile;
+ if (virtport) {
+ /* only type='openvswitch' is allowed for bridges */
+ if (virtport->virtPortType != VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _(" not supported for network "
+ "'%s' which uses a bridge device"),
+ virNetDevVPortTypeToString(virtport->virtPortType),
+ netdef->name);
+ goto cleanup;
+ }
+ }
+
} else if ((netdef->forwardType == VIR_NETWORK_FORWARD_BRIDGE) ||
(netdef->forwardType == VIR_NETWORK_FORWARD_PRIVATE) ||
(netdef->forwardType == VIR_NETWORK_FORWARD_VEPA) ||
(netdef->forwardType == VIR_NETWORK_FORWARD_PASSTHROUGH)) {
- virNetDevVPortProfilePtr virtport = NULL;
/* are all
* VIR_DOMAIN_NET_TYPE_DIRECT.
@@ -2853,24 +2878,28 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
break;
}
- /* Find the most specific virtportprofile and copy it */
- if (iface->virtPortProfile) {
- virtport = iface->virtPortProfile;
- } else {
- if (portgroup)
- virtport = portgroup->virtPortProfile;
- else
- virtport = netdef->virtPortProfile;
+ /* merge virtualports from interface, network, and portgroup to
+ * arrive at actual virtualport to use
+ */
+ if (virNetDevVPortProfileMerge3(&iface->data.network.actual->virtPortProfile,
+ iface->virtPortProfile,
+ netdef->virtPortProfile,
+ portgroup
+ ? portgroup->virtPortProfile : NULL) < 0) {
+ goto cleanup;
}
+ virtport = iface->data.network.actual->virtPortProfile;
if (virtport) {
- if (VIR_ALLOC(iface->data.network.actual->virtPortProfile) < 0) {
- virReportOOMError();
+ /* make sure type is supported for macvtap connections */
+ if (virtport->virtPortType != VIR_NETDEV_VPORT_PROFILE_8021QBG &&
+ virtport->virtPortType != VIR_NETDEV_VPORT_PROFILE_8021QBH) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _(" not supported for network "
+ "'%s' which uses a macvtap device"),
+ virNetDevVPortTypeToString(virtport->virtPortType),
+ netdef->name);
goto cleanup;
}
- /* There are no pointers in a virtualPortProfile, so a shallow copy
- * is sufficient
- */
- *iface->data.network.actual->virtPortProfile = *virtport;
}
/* If there is only a single device, just return it (caller will detect
@@ -2883,8 +2912,6 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
netdef->name);
goto cleanup;
} else {
- virNetworkForwardIfDefPtr dev = NULL;
-
/* pick an interface from the pool */
/* PASSTHROUGH mode, and PRIVATE Mode + 802.1Qbh both require
@@ -2967,13 +2994,18 @@ networkAllocateActualDevice(virDomainNetDefPtr iface)
virReportOOMError();
goto cleanup;
}
- /* we are now assured of success, so mark the allocation */
- dev->usageCount++;
- VIR_DEBUG("Using physical device %s, usageCount %d",
- dev->dev, dev->usageCount);
}
}
+ if (virNetDevVPortProfileCheckComplete(virtport, true) < 0)
+ goto cleanup;
+
+ if (dev) {
+ /* we are now assured of success, so mark the allocation */
+ dev->usageCount++;
+ VIR_DEBUG("Using physical device %s, usageCount %d",
+ dev->dev, dev->usageCount);
+ }
ret = 0;
cleanup:
for (ii = 0; ii < num_virt_fns; ii++)