/* virNetworkUpdateFlags */
unsigned int fflags ATTRIBUTE_UNUSED)
{
- int ii, ret = -1;
+ int ii, foundName = -1, foundDefault = -1;
+ int ret = -1;
virPortGroupDef portgroup;
memset(&portgroup, 0, sizeof(portgroup));
/* check if a portgroup with same name already exists */
for (ii = 0; ii < def->nPortGroups; ii++) {
if (STREQ(portgroup.name, def->portGroups[ii].name))
- break;
+ foundName = ii;
+ if (def->portGroups[ii].isDefault)
+ foundDefault = ii;
}
- if (ii == def->nPortGroups &&
+ if (foundName == -1 &&
((command == VIR_NETWORK_UPDATE_COMMAND_MODIFY) ||
(command == VIR_NETWORK_UPDATE_COMMAND_DELETE))) {
virReportError(VIR_ERR_OPERATION_INVALID,
"in network '%s' matching <portgroup name='%s'>"),
def->name, portgroup.name);
goto cleanup;
- } else if (ii < def->nPortGroups &&
+ } else if (foundName >= 0 &&
((command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST) ||
(command == VIR_NETWORK_UPDATE_COMMAND_ADD_LAST))) {
virReportError(VIR_ERR_OPERATION_INVALID,
goto cleanup;
}
+ /* if there is already a different default, we can't make this
+ * one the default.
+ */
+ if (command != VIR_NETWORK_UPDATE_COMMAND_DELETE &&
+ portgroup.isDefault &&
+ foundDefault >= 0 && foundDefault != foundName) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ _("a different portgroup entry in "
+ "network '%s' is already set as the default. "
+ "Only one default is allowed."),
+ def->name);
+ goto cleanup;
+ }
+
if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY) {
/* replace existing entry */
- virPortGroupDefClear(&def->portGroups[ii]);
- def->portGroups[ii] = portgroup;
+ virPortGroupDefClear(&def->portGroups[foundName]);
+ def->portGroups[foundName] = portgroup;
memset(&portgroup, 0, sizeof(portgroup));
} else if ((command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST) ||
} else if (command == VIR_NETWORK_UPDATE_COMMAND_DELETE) {
/* remove it */
- virPortGroupDefClear(&def->portGroups[ii]);
- memmove(def->portGroups + ii, def->portGroups + ii + 1,
- sizeof(*def->portGroups) * (def->nPortGroups - ii - 1));
+ virPortGroupDefClear(&def->portGroups[foundName]);
+ memmove(def->portGroups + foundName, def->portGroups + foundName + 1,
+ sizeof(*def->portGroups) * (def->nPortGroups - foundName - 1));
def->nPortGroups--;
ignore_value(VIR_REALLOC_N(def->portGroups, def->nPortGroups));
} else {
{
int ii;
bool vlanUsed, vlanAllowed;
+ const char *defaultPortGroup = NULL;
/* The only type of networks that currently support transparent
* vlan configuration are those using hostdev sr-iov devices from
== VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH)) {
vlanAllowed = true;
}
+ if (def->portGroups[ii].isDefault) {
+ if (defaultPortGroup) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("network '%s' has multiple default "
+ "<portgroup> elements (%s and %s), "
+ "but only one default is allowed"),
+ def->name, defaultPortGroup,
+ def->portGroups[ii].name);
+ }
+ defaultPortGroup = def->portGroups[ii].name;
+ }
}
if (vlanUsed && !vlanAllowed) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,