This was found during testing of the fix for: https://bugzilla.redhat.com/show_bug.cgi?id=868483 networkValidate was supposed to check for the existence of multiple portgroups and report an error if this was encountered. It did, but there were two problems: 1) even though it logged an error, it still returned success, allowing the operation to continue. 2) It could exit the portgroup checking loop early (or possibly not even do it once) if a vlan tag was supplied in the base network config or one of the portgroups. This patch fixes networkValidate to return failure in addition to logging the error, and also changes it to not exit the portgroup checking loop early. The logic was a bit off in the checking for vlan anyway, and it's intertwined with fixing the early loop exit, so I fixed that as well. Now it correctly checks for combinations where a <virtualport> is specified in the base network def and <vlan> is given in a portgroup, as well as the opposite (<vlan> in base network def and <virtualport> in portgroup), and ignores the case of a disallowed vlan when using *no* portgroup if there is a default portgroup (since in that case there is no way to not use any portgroup). --- src/network/bridge_driver.c | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 8837843..f814f6f 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -2617,8 +2617,8 @@ static int networkValidate(virNetworkDefPtr def) { int ii; - bool vlanUsed, vlanAllowed; - const char *defaultPortGroup = NULL; + bool vlanUsed, vlanAllowed, badVlanUse = false; + virPortGroupDefPtr defaultPortGroup = NULL; /* The only type of networks that currently support transparent * vlan configuration are those using hostdev sr-iov devices from @@ -2630,14 +2630,23 @@ networkValidate(virNetworkDefPtr def) def->virtPortProfile->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH); vlanUsed = def->vlan.nTags > 0; - for (ii = 0; ii < def->nPortGroups && !(vlanUsed && vlanAllowed); ii++) { - if (def->portGroups[ii].vlan.nTags > 0) - vlanUsed = true; - if (def->forwardType == VIR_NETWORK_FORWARD_BRIDGE && - def->portGroups[ii].virtPortProfile && - (def->portGroups[ii].virtPortProfile->virtPortType - == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH)) { - vlanAllowed = true; + for (ii = 0; ii < def->nPortGroups; ii++) { + if (vlanUsed || def->portGroups[ii].vlan.nTags > 0) { + /* anyone using this portgroup will get a vlan tag. Verify + * that they will also be using an openvswitch connection, + * as that is the only type of network that currently + * supports a vlan tag. + */ + if (def->portGroups[ii].virtPortProfile) { + if (def->forwardType != VIR_NETWORK_FORWARD_BRIDGE || + def->portGroups[ii].virtPortProfile->virtPortType + != VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH) { + badVlanUse = true; + } + } else if (!vlanAllowed) { + /* virtualport taken from base network definition */ + badVlanUse = true; + } } if (def->portGroups[ii].isDefault) { if (defaultPortGroup) { @@ -2645,13 +2654,20 @@ networkValidate(virNetworkDefPtr def) _("network '%s' has multiple default " "<portgroup> elements (%s and %s), " "but only one default is allowed"), - def->name, defaultPortGroup, + def->name, defaultPortGroup->name, def->portGroups[ii].name); + return -1; } - defaultPortGroup = def->portGroups[ii].name; + defaultPortGroup = &def->portGroups[ii]; } } - if (vlanUsed && !vlanAllowed) { + if (badVlanUse || + (vlanUsed && !vlanAllowed && !defaultPortGroup)) { + /* NB: if defaultPortGroup is set, we don't directly look at + * vlanUsed && !vlanAllowed, because the network will never be + * used without having a portgroup added in, so all necessary + * checks were done in the loop above. + */ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("<vlan> element specified for network %s, " "whose type doesn't support vlan configuration"), -- 1.7.11.7 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list