mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
network: backend for virNetworkUpdate of dhcp range
The dhcp range element is contained in the <dhcp> element of one of a network's <ip> elements. There can be multiple <range> elements. Because there are only two attributes (start and end), and those are exactly what you would use to identify a particular range, it doesn't really make sense to modify an existing element, so VIR_NETWORK_UPDATE_COMMAND_MODIFY isn't supported for this section, only ADD_FIRST, ADD_LAST, and DELETE. Since virsh already has support for understanding all the defined sections, this new backend is automatically supported by virsh. You would use it like this: virsh net-update mynet add ip-dhcp-range \ "<range start='1.2.3.4' end='1.2.3.20'/>" --live --config The bridge driver also already supports all sections, so it's doing the correct thing in this case as well - since the dhcp range is placed on the dnsmasq commandline, the bridge driver recreates the dnsmasq commandline, and re-runs dnsmasq whenever a range is added/deleted (and AFFECT_LIVE is specified in the flags).
This commit is contained in:
parent
fe7872827f
commit
1100f61074
@ -2494,14 +2494,98 @@ cleanup:
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
virNetworkDefUpdateIPDHCPRange(virNetworkDefPtr def,
|
virNetworkDefUpdateIPDHCPRange(virNetworkDefPtr def,
|
||||||
unsigned int command ATTRIBUTE_UNUSED,
|
unsigned int command,
|
||||||
int parentIndex ATTRIBUTE_UNUSED,
|
int parentIndex ATTRIBUTE_UNUSED,
|
||||||
xmlXPathContextPtr ctxt ATTRIBUTE_UNUSED,
|
xmlXPathContextPtr ctxt,
|
||||||
/* virNetworkUpdateFlags */
|
/* virNetworkUpdateFlags */
|
||||||
unsigned int fflags ATTRIBUTE_UNUSED)
|
unsigned int fflags ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
virNetworkDefUpdateNoSupport(def, "ip dhcp range");
|
int ii, ret = -1;
|
||||||
return -1;
|
virNetworkIpDefPtr ipdef = virNetworkIpDefByIndex(def, parentIndex);
|
||||||
|
virNetworkDHCPRangeDef range;
|
||||||
|
|
||||||
|
memset(&range, 0, sizeof(range));
|
||||||
|
|
||||||
|
if (virNetworkDefUpdateCheckElementName(def, ctxt->node, "range") < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
/* ipdef is the ip element that needs its range array updated */
|
||||||
|
if (!ipdef)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
/* parse the xml into a virNetworkDHCPRangeDef */
|
||||||
|
if (command == VIR_NETWORK_UPDATE_COMMAND_MODIFY) {
|
||||||
|
|
||||||
|
virReportError(VIR_ERR_NO_SUPPORT, "%s",
|
||||||
|
_("dhcp ranges cannot be modified, "
|
||||||
|
"only added or deleted"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virNetworkDHCPRangeDefParse(def->name, ctxt->node, &range) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
/* check if an entry with same name/address/ip already exists */
|
||||||
|
for (ii = 0; ii < ipdef->nranges; ii++) {
|
||||||
|
if (virSocketAddrEqual(&range.start, &ipdef->ranges[ii].start) &&
|
||||||
|
virSocketAddrEqual(&range.end, &ipdef->ranges[ii].end)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST) ||
|
||||||
|
(command == VIR_NETWORK_UPDATE_COMMAND_ADD_LAST)) {
|
||||||
|
|
||||||
|
if (ii < ipdef->nranges) {
|
||||||
|
char *startip = virSocketAddrFormat(&range.start);
|
||||||
|
char *endip = virSocketAddrFormat(&range.end);
|
||||||
|
|
||||||
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
||||||
|
_("there is an existing dhcp range entry in "
|
||||||
|
"network '%s' that matches "
|
||||||
|
"\"<range start='%s' end='%s'/>\""),
|
||||||
|
def->name,
|
||||||
|
startip ? startip : "unknown",
|
||||||
|
endip ? endip : "unknown");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add to beginning/end of list */
|
||||||
|
if (VIR_REALLOC_N(ipdef->ranges, ipdef->nranges +1) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command == VIR_NETWORK_UPDATE_COMMAND_ADD_LAST) {
|
||||||
|
ipdef->ranges[ipdef->nranges] = range;
|
||||||
|
} else { /* implied (command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST) */
|
||||||
|
memmove(ipdef->ranges + 1, ipdef->ranges,
|
||||||
|
sizeof(*ipdef->ranges) * ipdef->nranges);
|
||||||
|
ipdef->ranges[0] = range;
|
||||||
|
}
|
||||||
|
ipdef->nranges++;
|
||||||
|
memset(&range, 0, sizeof(range));
|
||||||
|
|
||||||
|
} else if (command == VIR_NETWORK_UPDATE_COMMAND_DELETE) {
|
||||||
|
|
||||||
|
if (ii == ipdef->nranges) {
|
||||||
|
virReportError(VIR_ERR_OPERATION_INVALID,
|
||||||
|
_("couldn't locate a matching dhcp range entry "
|
||||||
|
"in network '%s'"), def->name);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remove it */
|
||||||
|
/* NB: nothing to clear from a RangeDef that's being freed */
|
||||||
|
memmove(ipdef->ranges + ii, ipdef->ranges + ii + 1,
|
||||||
|
sizeof(*ipdef->ranges) * (ipdef->nranges - ii - 1));
|
||||||
|
ipdef->nranges--;
|
||||||
|
ignore_value(VIR_REALLOC_N(ipdef->ranges, ipdef->nranges));
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
Loading…
Reference in New Issue
Block a user