mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-25 01:34:11 +03:00
conf: Add <lease/> option for <dhcp/> settings
If an user is trying to configure a dhcp neetwork settings, it is not possible to change the leasetime of a range or a host entry. This is available using dnsmasq extra options, but they are associated with dhcp-range or dhcp-hosts fields. This patch implements a leasetime for range and hosts tags. They can be defined under that settings: <dhcp> <range ...> <lease/> </range> <host ...> <lease/> </host> </dhcp> Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=913446 Signed-off-by: Julio Faracco <jcfaracco@gmail.com> Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
5670fb5794
commit
97a0aa2467
@ -607,4 +607,12 @@
|
||||
</element>
|
||||
</define>
|
||||
|
||||
<define name="leaseUnit">
|
||||
<choice>
|
||||
<value>seconds</value>
|
||||
<value>minutes</value>
|
||||
<value>hours</value>
|
||||
</choice>
|
||||
</define>
|
||||
|
||||
</grammar>
|
||||
|
@ -371,6 +371,16 @@
|
||||
<element name="range">
|
||||
<attribute name="start"><ref name="ipAddr"/></attribute>
|
||||
<attribute name="end"><ref name="ipAddr"/></attribute>
|
||||
<interleave>
|
||||
<optional>
|
||||
<element name="lease">
|
||||
<attribute name="expiry"><ref name="unsignedLong"/></attribute>
|
||||
<optional>
|
||||
<attribute name="unit"><ref name="leaseUnit"/></attribute>
|
||||
</optional>
|
||||
</element>
|
||||
</optional>
|
||||
</interleave>
|
||||
</element>
|
||||
</zeroOrMore>
|
||||
<zeroOrMore>
|
||||
@ -388,6 +398,16 @@
|
||||
<attribute name="name"><text/></attribute>
|
||||
</choice>
|
||||
<attribute name="ip"><ref name="ipAddr"/></attribute>
|
||||
<interleave>
|
||||
<optional>
|
||||
<element name="lease">
|
||||
<attribute name="expiry"><ref name="unsignedLong"/></attribute>
|
||||
<optional>
|
||||
<attribute name="unit"><ref name="leaseUnit"/></attribute>
|
||||
</optional>
|
||||
</element>
|
||||
</optional>
|
||||
</interleave>
|
||||
</element>
|
||||
</zeroOrMore>
|
||||
<optional>
|
||||
|
@ -70,6 +70,13 @@ VIR_ENUM_IMPL(virNetworkTaint,
|
||||
"hook-script",
|
||||
);
|
||||
|
||||
VIR_ENUM_IMPL(virNetworkDHCPLeaseTimeUnit,
|
||||
VIR_NETWORK_DHCP_LEASETIME_UNIT_LAST,
|
||||
"seconds",
|
||||
"minutes",
|
||||
"hours",
|
||||
);
|
||||
|
||||
static virClassPtr virNetworkXMLOptionClass;
|
||||
|
||||
static void
|
||||
@ -132,12 +139,20 @@ virNetworkForwardPfDefClear(virNetworkForwardPfDefPtr def)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
virNetworkDHCPLeaseTimeDefClear(virNetworkDHCPLeaseTimeDefPtr lease)
|
||||
{
|
||||
VIR_FREE(lease);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
virNetworkDHCPHostDefClear(virNetworkDHCPHostDefPtr def)
|
||||
{
|
||||
VIR_FREE(def->mac);
|
||||
VIR_FREE(def->id);
|
||||
VIR_FREE(def->name);
|
||||
VIR_FREE(def->lease);
|
||||
}
|
||||
|
||||
|
||||
@ -145,6 +160,9 @@ static void
|
||||
virNetworkIPDefClear(virNetworkIPDefPtr def)
|
||||
{
|
||||
VIR_FREE(def->family);
|
||||
|
||||
while (def->nranges)
|
||||
virNetworkDHCPLeaseTimeDefClear(def->ranges[--def->nranges].lease);
|
||||
VIR_FREE(def->ranges);
|
||||
|
||||
while (def->nhosts)
|
||||
@ -391,11 +409,62 @@ int virNetworkIPDefNetmask(const virNetworkIPDef *def,
|
||||
|
||||
|
||||
static int
|
||||
virSocketAddrRangeParseXML(const char *networkName,
|
||||
virNetworkIPDefPtr ipdef,
|
||||
xmlNodePtr node,
|
||||
virSocketAddrRangePtr range)
|
||||
virNetworkDHCPLeaseTimeDefParseXML(virNetworkDHCPLeaseTimeDefPtr *lease,
|
||||
xmlNodePtr node)
|
||||
{
|
||||
virNetworkDHCPLeaseTimeDefPtr new_lease = *lease;
|
||||
g_autofree char *expiry = NULL;
|
||||
g_autofree char *unit = NULL;
|
||||
int unitInt;
|
||||
|
||||
if (!(expiry = virXMLPropString(node, "expiry")))
|
||||
return 0;
|
||||
|
||||
if (VIR_ALLOC(new_lease) < 0)
|
||||
return -1;
|
||||
new_lease->unit = VIR_NETWORK_DHCP_LEASETIME_UNIT_MINUTES;
|
||||
|
||||
if (virStrToLong_ul(expiry, NULL, 10, &new_lease->expiry) < 0)
|
||||
return -1;
|
||||
|
||||
if ((unit = virXMLPropString(node, "unit"))) {
|
||||
if ((unitInt = virNetworkDHCPLeaseTimeUnitTypeFromString(unit)) < 0) {
|
||||
virReportError(VIR_ERR_XML_ERROR,
|
||||
_("Invalid unit: %s"), unit);
|
||||
return -1;
|
||||
}
|
||||
new_lease->unit = unitInt;
|
||||
}
|
||||
|
||||
/* infinite */
|
||||
if (new_lease->expiry > 0) {
|
||||
/* This boundary check is related to dnsmasq man page settings:
|
||||
* "The minimum lease time is two minutes." */
|
||||
if ((new_lease->unit == VIR_NETWORK_DHCP_LEASETIME_UNIT_SECONDS &&
|
||||
new_lease->expiry < 120) ||
|
||||
(new_lease->unit == VIR_NETWORK_DHCP_LEASETIME_UNIT_MINUTES &&
|
||||
new_lease->expiry < 2)) {
|
||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
_("The minimum lease time should be greater "
|
||||
"than 2 minutes"));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
*lease = new_lease;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virNetworkDHCPRangeDefParseXML(const char *networkName,
|
||||
virNetworkIPDefPtr ipdef,
|
||||
xmlNodePtr node,
|
||||
virNetworkDHCPRangeDefPtr range)
|
||||
{
|
||||
virSocketAddrRangePtr addr = &range->addr;
|
||||
xmlNodePtr cur = node->children;
|
||||
char *start = NULL, *end = NULL;
|
||||
int ret = -1;
|
||||
|
||||
@ -405,7 +474,7 @@ virSocketAddrRangeParseXML(const char *networkName,
|
||||
networkName);
|
||||
goto cleanup;
|
||||
}
|
||||
if (virSocketAddrParse(&range->start, start, AF_UNSPEC) < 0)
|
||||
if (virSocketAddrParse(&addr->start, start, AF_UNSPEC) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (!(end = virXMLPropString(node, "end"))) {
|
||||
@ -414,14 +483,24 @@ virSocketAddrRangeParseXML(const char *networkName,
|
||||
networkName);
|
||||
goto cleanup;
|
||||
}
|
||||
if (virSocketAddrParse(&range->end, end, AF_UNSPEC) < 0)
|
||||
if (virSocketAddrParse(&addr->end, end, AF_UNSPEC) < 0)
|
||||
goto cleanup;
|
||||
|
||||
/* do a sanity check of the range */
|
||||
if (virSocketAddrGetRange(&range->start, &range->end, &ipdef->address,
|
||||
if (virSocketAddrGetRange(&addr->start, &addr->end, &ipdef->address,
|
||||
virNetworkIPDefPrefix(ipdef)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
while (cur != NULL) {
|
||||
if (cur->type == XML_ELEMENT_NODE &&
|
||||
virXMLNodeNameEqual(cur, "lease")) {
|
||||
|
||||
if (virNetworkDHCPLeaseTimeDefParseXML(&range->lease, cur) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
@ -441,6 +520,7 @@ virNetworkDHCPHostDefParseXML(const char *networkName,
|
||||
char *mac = NULL, *name = NULL, *ip = NULL, *id = NULL;
|
||||
virMacAddr addr;
|
||||
virSocketAddr inaddr;
|
||||
xmlNodePtr cur = node->children;
|
||||
int ret = -1;
|
||||
|
||||
mac = virXMLPropString(node, "mac");
|
||||
@ -533,6 +613,16 @@ virNetworkDHCPHostDefParseXML(const char *networkName,
|
||||
}
|
||||
}
|
||||
|
||||
while (cur != NULL) {
|
||||
if (cur->type == XML_ELEMENT_NODE &&
|
||||
virXMLNodeNameEqual(cur, "lease")) {
|
||||
|
||||
if (virNetworkDHCPLeaseTimeDefParseXML(&host->lease, cur) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
host->mac = mac;
|
||||
mac = NULL;
|
||||
host->id = id;
|
||||
@ -559,7 +649,7 @@ virNetworkDHCPDefParseXML(const char *networkName,
|
||||
{
|
||||
int ret = -1;
|
||||
xmlNodePtr cur;
|
||||
virSocketAddrRange range;
|
||||
virNetworkDHCPRangeDef range;
|
||||
virNetworkDHCPHostDef host;
|
||||
|
||||
memset(&range, 0, sizeof(range));
|
||||
@ -570,7 +660,7 @@ virNetworkDHCPDefParseXML(const char *networkName,
|
||||
if (cur->type == XML_ELEMENT_NODE &&
|
||||
virXMLNodeNameEqual(cur, "range")) {
|
||||
|
||||
if (virSocketAddrRangeParseXML(networkName, def, cur, &range) < 0)
|
||||
if (virNetworkDHCPRangeDefParseXML(networkName, def, cur, &range) < 0)
|
||||
goto cleanup;
|
||||
if (VIR_APPEND_ELEMENT(def->ranges, def->nranges, range) < 0)
|
||||
goto cleanup;
|
||||
@ -583,7 +673,6 @@ virNetworkDHCPDefParseXML(const char *networkName,
|
||||
goto cleanup;
|
||||
if (VIR_APPEND_ELEMENT(def->hosts, def->nhosts, host) < 0)
|
||||
goto cleanup;
|
||||
|
||||
} else if (VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET) &&
|
||||
cur->type == XML_ELEMENT_NODE &&
|
||||
virXMLNodeNameEqual(cur, "bootp")) {
|
||||
@ -2300,20 +2389,39 @@ virNetworkIPDefFormat(virBufferPtr buf,
|
||||
virBufferAdjustIndent(buf, 2);
|
||||
|
||||
for (i = 0; i < def->nranges; i++) {
|
||||
char *saddr = virSocketAddrFormat(&def->ranges[i].start);
|
||||
virSocketAddrRange addr = def->ranges[i].addr;
|
||||
virNetworkDHCPLeaseTimeDefPtr lease = def->ranges[i].lease;
|
||||
|
||||
char *saddr = virSocketAddrFormat(&addr.start);
|
||||
if (!saddr)
|
||||
return -1;
|
||||
char *eaddr = virSocketAddrFormat(&def->ranges[i].end);
|
||||
char *eaddr = virSocketAddrFormat(&addr.end);
|
||||
if (!eaddr) {
|
||||
VIR_FREE(saddr);
|
||||
return -1;
|
||||
}
|
||||
virBufferAsprintf(buf, "<range start='%s' end='%s'/>\n",
|
||||
virBufferAsprintf(buf, "<range start='%s' end='%s'",
|
||||
saddr, eaddr);
|
||||
if (lease) {
|
||||
virBufferAddLit(buf, ">\n");
|
||||
virBufferAdjustIndent(buf, 2);
|
||||
if (!lease->expiry) {
|
||||
virBufferAddLit(buf, "<lease expiry='0'/>\n");
|
||||
} else {
|
||||
virBufferAsprintf(buf, "<lease expiry='%lu' unit='%s'/>\n",
|
||||
lease->expiry,
|
||||
virNetworkDHCPLeaseTimeUnitTypeToString(lease->unit));
|
||||
}
|
||||
virBufferAdjustIndent(buf, -2);
|
||||
virBufferAddLit(buf, "</range>\n");
|
||||
} else {
|
||||
virBufferAddLit(buf, "/>\n");
|
||||
}
|
||||
VIR_FREE(saddr);
|
||||
VIR_FREE(eaddr);
|
||||
}
|
||||
for (i = 0; i < def->nhosts; i++) {
|
||||
virNetworkDHCPLeaseTimeDefPtr lease = def->hosts[i].lease;
|
||||
virBufferAddLit(buf, "<host");
|
||||
if (def->hosts[i].mac)
|
||||
virBufferAsprintf(buf, " mac='%s'", def->hosts[i].mac);
|
||||
@ -2328,7 +2436,21 @@ virNetworkIPDefFormat(virBufferPtr buf,
|
||||
virBufferAsprintf(buf, " ip='%s'", ipaddr);
|
||||
VIR_FREE(ipaddr);
|
||||
}
|
||||
virBufferAddLit(buf, "/>\n");
|
||||
if (lease) {
|
||||
virBufferAddLit(buf, ">\n");
|
||||
virBufferAdjustIndent(buf, 2);
|
||||
if (!lease->expiry) {
|
||||
virBufferAddLit(buf, "<lease expiry='0'/>\n");
|
||||
} else {
|
||||
virBufferAsprintf(buf, "<lease expiry='%lu' unit='%s'/>\n",
|
||||
lease->expiry,
|
||||
virNetworkDHCPLeaseTimeUnitTypeToString(lease->unit));
|
||||
}
|
||||
virBufferAdjustIndent(buf, -2);
|
||||
virBufferAddLit(buf, "</host>\n");
|
||||
} else {
|
||||
virBufferAddLit(buf, "/>\n");
|
||||
}
|
||||
}
|
||||
if (def->bootfile) {
|
||||
virBufferEscapeString(buf, "<bootp file='%s'",
|
||||
@ -2343,7 +2465,6 @@ virNetworkIPDefFormat(virBufferPtr buf,
|
||||
virBufferAddLit(buf, "/>\n");
|
||||
|
||||
}
|
||||
|
||||
virBufferAdjustIndent(buf, -2);
|
||||
virBufferAddLit(buf, "</dhcp>\n");
|
||||
}
|
||||
@ -3080,7 +3201,7 @@ virNetworkDefUpdateIPDHCPRange(virNetworkDefPtr def,
|
||||
{
|
||||
size_t i;
|
||||
virNetworkIPDefPtr ipdef = virNetworkIPDefByIndex(def, parentIndex);
|
||||
virSocketAddrRange range;
|
||||
virNetworkDHCPRangeDef range;
|
||||
|
||||
memset(&range, 0, sizeof(range));
|
||||
|
||||
@ -3100,11 +3221,11 @@ virNetworkDefUpdateIPDHCPRange(virNetworkDefPtr def,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (virSocketAddrRangeParseXML(def->name, ipdef, ctxt->node, &range) < 0)
|
||||
if (virNetworkDHCPRangeDefParseXML(def->name, ipdef, ctxt->node, &range) < 0)
|
||||
return -1;
|
||||
|
||||
if (VIR_SOCKET_ADDR_FAMILY(&ipdef->address)
|
||||
!= VIR_SOCKET_ADDR_FAMILY(&range.start)) {
|
||||
!= VIR_SOCKET_ADDR_FAMILY(&range.addr.start)) {
|
||||
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||
_("the address family of a dhcp range must match "
|
||||
"the address family of the dhcp element's parent"));
|
||||
@ -3113,8 +3234,9 @@ virNetworkDefUpdateIPDHCPRange(virNetworkDefPtr def,
|
||||
|
||||
/* check if an entry with same name/address/ip already exists */
|
||||
for (i = 0; i < ipdef->nranges; i++) {
|
||||
if (virSocketAddrEqual(&range.start, &ipdef->ranges[i].start) &&
|
||||
virSocketAddrEqual(&range.end, &ipdef->ranges[i].end)) {
|
||||
virSocketAddrRange addr = ipdef->ranges[i].addr;
|
||||
if (virSocketAddrEqual(&range.addr.start, &addr.start) &&
|
||||
virSocketAddrEqual(&range.addr.end, &addr.end)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -3126,8 +3248,8 @@ virNetworkDefUpdateIPDHCPRange(virNetworkDefPtr def,
|
||||
return -1;
|
||||
|
||||
if (i < ipdef->nranges) {
|
||||
char *startip = virSocketAddrFormat(&range.start);
|
||||
char *endip = virSocketAddrFormat(&range.end);
|
||||
char *startip = virSocketAddrFormat(&range.addr.start);
|
||||
char *endip = virSocketAddrFormat(&range.addr.end);
|
||||
|
||||
virReportError(VIR_ERR_OPERATION_INVALID,
|
||||
_("there is an existing dhcp range entry in "
|
||||
|
@ -80,6 +80,16 @@ typedef enum {
|
||||
VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_LAST,
|
||||
} virNetworkForwardHostdevDeviceType;
|
||||
|
||||
typedef enum {
|
||||
VIR_NETWORK_DHCP_LEASETIME_UNIT_SECONDS = 0,
|
||||
VIR_NETWORK_DHCP_LEASETIME_UNIT_MINUTES,
|
||||
VIR_NETWORK_DHCP_LEASETIME_UNIT_HOURS,
|
||||
|
||||
VIR_NETWORK_DHCP_LEASETIME_UNIT_LAST,
|
||||
} virNetworkDHCPLeaseTimeUnitType;
|
||||
|
||||
VIR_ENUM_DECL(virNetworkDHCPLeaseTimeUnit);
|
||||
|
||||
/* The backend driver used for devices from the pool. Currently used
|
||||
* only for PCI devices (vfio vs. kvm), but could be used for other
|
||||
* device types in the future.
|
||||
@ -94,6 +104,20 @@ typedef enum {
|
||||
|
||||
VIR_ENUM_DECL(virNetworkForwardDriverName);
|
||||
|
||||
typedef struct _virNetworkDHCPLeaseTimeDef virNetworkDHCPLeaseTimeDef;
|
||||
typedef virNetworkDHCPLeaseTimeDef *virNetworkDHCPLeaseTimeDefPtr;
|
||||
struct _virNetworkDHCPLeaseTimeDef {
|
||||
unsigned long expiry;
|
||||
virNetworkDHCPLeaseTimeUnitType unit;
|
||||
};
|
||||
|
||||
typedef struct _virNetworkDHCPRangeDef virNetworkDHCPRangeDef;
|
||||
typedef virNetworkDHCPRangeDef *virNetworkDHCPRangeDefPtr;
|
||||
struct _virNetworkDHCPRangeDef {
|
||||
virSocketAddrRange addr;
|
||||
virNetworkDHCPLeaseTimeDefPtr lease;
|
||||
};
|
||||
|
||||
typedef struct _virNetworkDHCPHostDef virNetworkDHCPHostDef;
|
||||
typedef virNetworkDHCPHostDef *virNetworkDHCPHostDefPtr;
|
||||
struct _virNetworkDHCPHostDef {
|
||||
@ -101,6 +125,7 @@ struct _virNetworkDHCPHostDef {
|
||||
char *id;
|
||||
char *name;
|
||||
virSocketAddr ip;
|
||||
virNetworkDHCPLeaseTimeDefPtr lease;
|
||||
};
|
||||
|
||||
typedef struct _virNetworkDNSTxtDef virNetworkDNSTxtDef;
|
||||
@ -171,7 +196,7 @@ struct _virNetworkIPDef {
|
||||
int localPTR; /* virTristateBool */
|
||||
|
||||
size_t nranges; /* Zero or more dhcp ranges */
|
||||
virSocketAddrRangePtr ranges;
|
||||
virNetworkDHCPRangeDefPtr ranges;
|
||||
|
||||
size_t nhosts; /* Zero or more dhcp hosts */
|
||||
virNetworkDHCPHostDefPtr hosts;
|
||||
|
@ -772,6 +772,8 @@ virNetworkDefParseNode;
|
||||
virNetworkDefParseString;
|
||||
virNetworkDefParseXML;
|
||||
virNetworkDefUpdateSection;
|
||||
virNetworkDHCPLeaseTimeUnitTypeFromString;
|
||||
virNetworkDHCPLeaseTimeUnitTypeToString;
|
||||
virNetworkForwardTypeToString;
|
||||
virNetworkIPDefNetmask;
|
||||
virNetworkIPDefPrefix;
|
||||
@ -1950,6 +1952,7 @@ dnsmasqCapsRefresh;
|
||||
dnsmasqContextFree;
|
||||
dnsmasqContextNew;
|
||||
dnsmasqDelete;
|
||||
dnsmasqDhcpHostsToString;
|
||||
dnsmasqReload;
|
||||
dnsmasqSave;
|
||||
|
||||
|
@ -966,6 +966,30 @@ static int networkConnectIsAlive(virConnectPtr conn G_GNUC_UNUSED)
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
networkBuildDnsmasqLeaseTime(virNetworkDHCPLeaseTimeDefPtr lease)
|
||||
{
|
||||
char *leasetime = NULL;
|
||||
const char *unit;
|
||||
g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
|
||||
|
||||
if (!lease)
|
||||
return NULL;
|
||||
|
||||
if (lease->expiry == 0) {
|
||||
virBufferAddLit(&buf, "infinite");
|
||||
} else {
|
||||
unit = virNetworkDHCPLeaseTimeUnitTypeToString(lease->unit);
|
||||
/* We get only first compatible char from string: 's', 'm' or 'h' */
|
||||
virBufferAsprintf(&buf, "%lu%c", lease->expiry, unit[0]);
|
||||
}
|
||||
|
||||
leasetime = virBufferContentAndReset(&buf);
|
||||
|
||||
return leasetime;
|
||||
}
|
||||
|
||||
|
||||
/* the following does not build a file, it builds a list
|
||||
* which is later saved into a file
|
||||
*/
|
||||
@ -975,14 +999,18 @@ networkBuildDnsmasqDhcpHostsList(dnsmasqContext *dctx,
|
||||
{
|
||||
size_t i;
|
||||
bool ipv6 = false;
|
||||
g_autofree char *leasetime = NULL;
|
||||
|
||||
if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6))
|
||||
ipv6 = true;
|
||||
for (i = 0; i < ipdef->nhosts; i++) {
|
||||
virNetworkDHCPHostDefPtr host = &(ipdef->hosts[i]);
|
||||
|
||||
leasetime = networkBuildDnsmasqLeaseTime(host->lease);
|
||||
if (VIR_SOCKET_ADDR_VALID(&host->ip))
|
||||
if (dnsmasqAddDhcpHost(dctx, host->mac, &host->ip,
|
||||
host->name, host->id, ipv6) < 0)
|
||||
host->name, host->id, leasetime,
|
||||
ipv6) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1052,6 +1080,7 @@ int
|
||||
networkDnsmasqConfContents(virNetworkObjPtr obj,
|
||||
const char *pidfile,
|
||||
char **configstr,
|
||||
char **hostsfilestr,
|
||||
dnsmasqContext *dctx,
|
||||
dnsmasqCapsPtr caps G_GNUC_UNUSED)
|
||||
{
|
||||
@ -1381,13 +1410,15 @@ networkDnsmasqConfContents(virNetworkObjPtr obj,
|
||||
}
|
||||
for (r = 0; r < ipdef->nranges; r++) {
|
||||
int thisRange;
|
||||
virNetworkDHCPRangeDef range = ipdef->ranges[r];
|
||||
g_autofree char *leasetime = NULL;
|
||||
|
||||
if (!(saddr = virSocketAddrFormat(&ipdef->ranges[r].start)) ||
|
||||
!(eaddr = virSocketAddrFormat(&ipdef->ranges[r].end)))
|
||||
if (!(saddr = virSocketAddrFormat(&range.addr.start)) ||
|
||||
!(eaddr = virSocketAddrFormat(&range.addr.end)))
|
||||
goto cleanup;
|
||||
|
||||
if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6)) {
|
||||
virBufferAsprintf(&configbuf, "dhcp-range=%s,%s,%d\n",
|
||||
virBufferAsprintf(&configbuf, "dhcp-range=%s,%s,%d",
|
||||
saddr, eaddr, prefix);
|
||||
} else {
|
||||
/* IPv4 - dnsmasq requires a netmask rather than prefix */
|
||||
@ -1404,14 +1435,19 @@ networkDnsmasqConfContents(virNetworkObjPtr obj,
|
||||
|
||||
if (!(netmaskStr = virSocketAddrFormat(&netmask)))
|
||||
goto cleanup;
|
||||
virBufferAsprintf(&configbuf, "dhcp-range=%s,%s,%s\n",
|
||||
virBufferAsprintf(&configbuf, "dhcp-range=%s,%s,%s",
|
||||
saddr, eaddr, netmaskStr);
|
||||
}
|
||||
|
||||
if ((leasetime = networkBuildDnsmasqLeaseTime(range.lease)))
|
||||
virBufferAsprintf(&configbuf, ",%s", leasetime);
|
||||
|
||||
virBufferAddLit(&configbuf, "\n");
|
||||
|
||||
VIR_FREE(saddr);
|
||||
VIR_FREE(eaddr);
|
||||
thisRange = virSocketAddrGetRange(&ipdef->ranges[r].start,
|
||||
&ipdef->ranges[r].end,
|
||||
thisRange = virSocketAddrGetRange(&range.addr.start,
|
||||
&range.addr.end,
|
||||
&ipdef->address,
|
||||
virNetworkIPDefPrefix(ipdef));
|
||||
if (thisRange < 0)
|
||||
@ -1525,6 +1561,9 @@ networkDnsmasqConfContents(virNetworkObjPtr obj,
|
||||
if (!(*configstr = virBufferContentAndReset(&configbuf)))
|
||||
goto cleanup;
|
||||
|
||||
*hostsfilestr = dnsmasqDhcpHostsToString(dctx->hostsfile->hosts,
|
||||
dctx->hostsfile->nhosts);
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
@ -1549,11 +1588,12 @@ networkBuildDhcpDaemonCommandLine(virNetworkDriverStatePtr driver,
|
||||
int ret = -1;
|
||||
char *configfile = NULL;
|
||||
char *configstr = NULL;
|
||||
char *hostsfilestr = NULL;
|
||||
char *leaseshelper_path = NULL;
|
||||
|
||||
virNetworkObjSetDnsmasqPid(obj, -1);
|
||||
|
||||
if (networkDnsmasqConfContents(obj, pidfile, &configstr,
|
||||
if (networkDnsmasqConfContents(obj, pidfile, &configstr, &hostsfilestr,
|
||||
dctx, dnsmasq_caps) < 0)
|
||||
goto cleanup;
|
||||
if (!configstr)
|
||||
|
@ -46,5 +46,6 @@ int
|
||||
networkDnsmasqConfContents(virNetworkObjPtr obj,
|
||||
const char *pidfile,
|
||||
char **configstr,
|
||||
char **hostsfilestr,
|
||||
dnsmasqContext *dctx,
|
||||
dnsmasqCapsPtr caps);
|
||||
|
@ -5025,7 +5025,7 @@ testDomainInterfaceAddressFromNet(testDriverPtr driver,
|
||||
net_def->ips->prefix);
|
||||
|
||||
if (net_def->ips->nranges > 0)
|
||||
addr = net_def->ips->ranges[0].start;
|
||||
addr = net_def->ips->ranges[0].addr.start;
|
||||
else
|
||||
addr = net_def->ips->address;
|
||||
|
||||
|
@ -296,11 +296,14 @@ hostsfileAdd(dnsmasqHostsfile *hostsfile,
|
||||
virSocketAddr *ip,
|
||||
const char *name,
|
||||
const char *id,
|
||||
const char *leasetime,
|
||||
bool ipv6)
|
||||
{
|
||||
char *ipstr = NULL;
|
||||
g_autofree char *ipstr = NULL;
|
||||
g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
|
||||
|
||||
if (VIR_REALLOC_N(hostsfile->hosts, hostsfile->nhosts + 1) < 0)
|
||||
goto error;
|
||||
return -1;
|
||||
|
||||
if (!(ipstr = virSocketAddrFormat(ip)))
|
||||
return -1;
|
||||
@ -308,34 +311,30 @@ hostsfileAdd(dnsmasqHostsfile *hostsfile,
|
||||
/* the first test determines if it is a dhcpv6 host */
|
||||
if (ipv6) {
|
||||
if (name && id) {
|
||||
hostsfile->hosts[hostsfile->nhosts].host = g_strdup_printf("id:%s,%s,[%s]",
|
||||
id, name, ipstr);
|
||||
virBufferAsprintf(&buf, "id:%s,%s", id, name);
|
||||
} else if (name && !id) {
|
||||
hostsfile->hosts[hostsfile->nhosts].host = g_strdup_printf("%s,[%s]",
|
||||
name, ipstr);
|
||||
virBufferAsprintf(&buf, "%s", name);
|
||||
} else if (!name && id) {
|
||||
hostsfile->hosts[hostsfile->nhosts].host = g_strdup_printf("id:%s,[%s]",
|
||||
id, ipstr);
|
||||
virBufferAsprintf(&buf, "id:%s", id);
|
||||
}
|
||||
virBufferAsprintf(&buf, ",[%s]", ipstr);
|
||||
} else if (name && mac) {
|
||||
hostsfile->hosts[hostsfile->nhosts].host = g_strdup_printf("%s,%s,%s",
|
||||
mac, ipstr, name);
|
||||
virBufferAsprintf(&buf, "%s,%s,%s", mac, ipstr, name);
|
||||
} else if (name && !mac) {
|
||||
hostsfile->hosts[hostsfile->nhosts].host = g_strdup_printf("%s,%s", name,
|
||||
ipstr);
|
||||
virBufferAsprintf(&buf, "%s,%s", name, ipstr);
|
||||
} else {
|
||||
hostsfile->hosts[hostsfile->nhosts].host = g_strdup_printf("%s,%s", mac,
|
||||
ipstr);
|
||||
virBufferAsprintf(&buf, "%s,%s", mac, ipstr);
|
||||
}
|
||||
VIR_FREE(ipstr);
|
||||
|
||||
if (leasetime)
|
||||
virBufferAsprintf(&buf, ",%s", leasetime);
|
||||
|
||||
if (!(hostsfile->hosts[hostsfile->nhosts].host = virBufferContentAndReset(&buf)))
|
||||
return -1;
|
||||
|
||||
hostsfile->nhosts++;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
VIR_FREE(ipstr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static dnsmasqHostsfile *
|
||||
@ -501,9 +500,10 @@ dnsmasqAddDhcpHost(dnsmasqContext *ctx,
|
||||
virSocketAddr *ip,
|
||||
const char *name,
|
||||
const char *id,
|
||||
const char *leasetime,
|
||||
bool ipv6)
|
||||
{
|
||||
return hostsfileAdd(ctx->hostsfile, mac, ip, name, id, ipv6);
|
||||
return hostsfileAdd(ctx->hostsfile, mac, ip, name, id, leasetime, ipv6);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -862,3 +862,23 @@ dnsmasqCapsGet(dnsmasqCapsPtr caps, dnsmasqCapsFlags flag)
|
||||
{
|
||||
return caps && virBitmapIsBitSet(caps->flags, flag);
|
||||
}
|
||||
|
||||
|
||||
/** dnsmasqDhcpHostsToString:
|
||||
*
|
||||
* Turns a vector of dnsmasqDhcpHost into the string that is ought to be
|
||||
* stored in the hostsfile, this functionality is split to make hostsfiles
|
||||
* testable. Returs NULL if nhosts is 0.
|
||||
*/
|
||||
char *
|
||||
dnsmasqDhcpHostsToString(dnsmasqDhcpHost *hosts,
|
||||
unsigned int nhosts)
|
||||
{
|
||||
size_t i;
|
||||
g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
|
||||
|
||||
for (i = 0; i < nhosts; i++)
|
||||
virBufferAsprintf(&buf, "%s\n", hosts[i].host);
|
||||
|
||||
return virBufferContentAndReset(&buf);
|
||||
}
|
||||
|
@ -87,6 +87,7 @@ int dnsmasqAddDhcpHost(dnsmasqContext *ctx,
|
||||
virSocketAddr *ip,
|
||||
const char *name,
|
||||
const char *id,
|
||||
const char *leasetime,
|
||||
bool ipv6);
|
||||
int dnsmasqAddHost(dnsmasqContext *ctx,
|
||||
virSocketAddr *ip,
|
||||
@ -104,6 +105,8 @@ int dnsmasqCapsRefresh(dnsmasqCapsPtr *caps, const char *binaryPath);
|
||||
bool dnsmasqCapsGet(dnsmasqCapsPtr caps, dnsmasqCapsFlags flag);
|
||||
const char *dnsmasqCapsGetBinaryPath(dnsmasqCapsPtr caps);
|
||||
unsigned long dnsmasqCapsGetVersion(dnsmasqCapsPtr caps);
|
||||
char *dnsmasqDhcpHostsToString(dnsmasqDhcpHost *hosts,
|
||||
unsigned int nhosts);
|
||||
|
||||
#define DNSMASQ_DHCPv6_MAJOR_REQD 2
|
||||
#define DNSMASQ_DHCPv6_MINOR_REQD 64
|
||||
|
@ -379,6 +379,7 @@ vboxNetworkDefineCreateXML(virConnectPtr conn, const char *xml, bool start)
|
||||
virNetworkIPDefPtr ipdef = NULL;
|
||||
unsigned char uuid[VIR_UUID_BUFLEN];
|
||||
vboxIID vboxnetiid;
|
||||
virSocketAddrRange addr;
|
||||
virSocketAddr netmask;
|
||||
IHost *host = NULL;
|
||||
virNetworkPtr ret = NULL;
|
||||
@ -440,9 +441,10 @@ vboxNetworkDefineCreateXML(virConnectPtr conn, const char *xml, bool start)
|
||||
/* Currently support only one dhcp server per network
|
||||
* with contigious address space from start to end
|
||||
*/
|
||||
addr = ipdef->ranges[0].addr;
|
||||
if ((ipdef->nranges >= 1) &&
|
||||
VIR_SOCKET_ADDR_VALID(&ipdef->ranges[0].start) &&
|
||||
VIR_SOCKET_ADDR_VALID(&ipdef->ranges[0].end)) {
|
||||
VIR_SOCKET_ADDR_VALID(&addr.start) &&
|
||||
VIR_SOCKET_ADDR_VALID(&addr.end)) {
|
||||
IDHCPServer *dhcpServer = NULL;
|
||||
|
||||
gVBoxAPI.UIVirtualBox.FindDHCPServerByNetworkName(data->vboxObj,
|
||||
@ -464,8 +466,8 @@ vboxNetworkDefineCreateXML(virConnectPtr conn, const char *xml, bool start)
|
||||
|
||||
ipAddressUtf16 = vboxSocketFormatAddrUtf16(data, &ipdef->address);
|
||||
networkMaskUtf16 = vboxSocketFormatAddrUtf16(data, &netmask);
|
||||
fromIPAddressUtf16 = vboxSocketFormatAddrUtf16(data, &ipdef->ranges[0].start);
|
||||
toIPAddressUtf16 = vboxSocketFormatAddrUtf16(data, &ipdef->ranges[0].end);
|
||||
fromIPAddressUtf16 = vboxSocketFormatAddrUtf16(data, &addr.start);
|
||||
toIPAddressUtf16 = vboxSocketFormatAddrUtf16(data, &addr.end);
|
||||
|
||||
if (ipAddressUtf16 == NULL || networkMaskUtf16 == NULL ||
|
||||
fromIPAddressUtf16 == NULL || toIPAddressUtf16 == NULL) {
|
||||
@ -770,6 +772,7 @@ static char *vboxNetworkGetXMLDesc(virNetworkPtr network, unsigned int flags)
|
||||
vboxIID vboxnet0IID;
|
||||
IHost *host = NULL;
|
||||
char *ret = NULL;
|
||||
virSocketAddrRange addr;
|
||||
nsresult rc;
|
||||
|
||||
if (!data->vboxObj)
|
||||
@ -833,14 +836,15 @@ static char *vboxNetworkGetXMLDesc(virNetworkPtr network, unsigned int flags)
|
||||
/* Currently virtualbox supports only one dhcp server per network
|
||||
* with contigious address space from start to end
|
||||
*/
|
||||
addr = ipdef->ranges[0].addr;
|
||||
if (vboxSocketParseAddrUtf16(data, ipAddressUtf16,
|
||||
&ipdef->address) < 0 ||
|
||||
vboxSocketParseAddrUtf16(data, networkMaskUtf16,
|
||||
&ipdef->netmask) < 0 ||
|
||||
vboxSocketParseAddrUtf16(data, fromIPAddressUtf16,
|
||||
&ipdef->ranges[0].start) < 0 ||
|
||||
&addr.start) < 0 ||
|
||||
vboxSocketParseAddrUtf16(data, toIPAddressUtf16,
|
||||
&ipdef->ranges[0].end) < 0) {
|
||||
&addr.end) < 0) {
|
||||
errorOccurred = true;
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,8 @@
|
||||
static int
|
||||
testCompareXMLToConfFiles(const char *inxml, const char *outconf, dnsmasqCapsPtr caps)
|
||||
{
|
||||
char *actual = NULL;
|
||||
char *confactual = NULL;
|
||||
char *hostsfileactual = NULL;
|
||||
int ret = -1;
|
||||
virNetworkDefPtr def = NULL;
|
||||
virNetworkObjPtr obj = NULL;
|
||||
@ -43,28 +44,30 @@ testCompareXMLToConfFiles(const char *inxml, const char *outconf, dnsmasqCapsPtr
|
||||
if (dctx == NULL)
|
||||
goto fail;
|
||||
|
||||
if (networkDnsmasqConfContents(obj, pidfile, &actual, dctx, caps) < 0)
|
||||
if (networkDnsmasqConfContents(obj, pidfile, &confactual,
|
||||
&hostsfileactual, dctx, caps) < 0)
|
||||
goto fail;
|
||||
|
||||
/* Any changes to this function ^^ should be reflected here too. */
|
||||
#ifndef __linux__
|
||||
char * tmp;
|
||||
|
||||
if (!(tmp = virStringReplace(actual,
|
||||
if (!(tmp = virStringReplace(confactual,
|
||||
"except-interface=lo0\n",
|
||||
"except-interface=lo\n")))
|
||||
goto fail;
|
||||
VIR_FREE(actual);
|
||||
VIR_FREE(confactual);
|
||||
actual = g_steal_pointer(&tmp);
|
||||
#endif
|
||||
|
||||
if (virTestCompareToFile(actual, outconf) < 0)
|
||||
if (virTestCompareToFile(confactual, outconf) < 0)
|
||||
goto fail;
|
||||
|
||||
ret = 0;
|
||||
|
||||
fail:
|
||||
VIR_FREE(actual);
|
||||
VIR_FREE(confactual);
|
||||
VIR_FREE(hostsfileactual);
|
||||
VIR_FREE(pidfile);
|
||||
virCommandFree(cmd);
|
||||
virObjectUnref(xmlopt);
|
||||
|
Loading…
Reference in New Issue
Block a user