Change the type of txtrecords from virNetworkDNSTxtRecordsDefPtr to virNetworkDNSTxtRecordsDefPtr *. Refacotr the virNetworkDNSDefParseXML to create a new TXT xml Parsing function. Make value (text field in TXT RR) optional according to dnsmasq manpage. --txt-record=<name>[[,<text>],<text>] --- src/conf/network_conf.c | 111 +++++++++++++++++++++++++++---------------- src/conf/network_conf.h | 2 +- src/network/bridge_driver.c | 16 +++++- 3 files changed, 84 insertions(+), 45 deletions(-) diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index 99c6fc1..b720c9f 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -125,8 +125,8 @@ static void virNetworkDNSDefFree(virNetworkDNSDefPtr def) if (def) { if (def->txtrecords) { while (def->ntxtrecords--) { - VIR_FREE(def->txtrecords[def->ntxtrecords].name); - VIR_FREE(def->txtrecords[def->ntxtrecords].value); + VIR_FREE(def->txtrecords[def->ntxtrecords]->name); + VIR_FREE(def->txtrecords[def->ntxtrecords]->value); } } VIR_FREE(def->txtrecords); @@ -512,6 +512,44 @@ virNetworkDHCPRangeDefParseXML(const char *networkName, return 0; } +static virNetworkDNSTxtRecordsDefPtr +virNetworkDNSTxtDefParseXML(xmlNodePtr cur) + +{ + virNetworkDNSTxtRecordsDefPtr txt = NULL; + + if (VIR_ALLOC(txt) < 0) { + virReportOOMError(); + return NULL; + } + + if (!(txt->name = virXMLPropString(cur, "name"))) { + virNetworkReportError(VIR_ERR_XML_DETAIL, + "%s", _("Missing required name attribute in dns txt record")); + goto error; + } + + /* The text field for dnsmasq is optional */ + txt->value = virXMLPropString(cur, "value"); + if (txt->value && *txt->value == '\0') + txt->value = NULL; + + if (strchr(txt->name, ' ') != NULL) { + virNetworkReportError(VIR_ERR_XML_DETAIL, + _("spaces are not allowed in DNS TXT record names (name is '%s')"), txt->name); + goto error; + } + + return txt; +error: + if (txt) { + VIR_FREE(txt->name); + VIR_FREE(txt->value); + } + VIR_FREE(txt); + return NULL; +} + static int virNetworkDNSHostsDefParseXML(virNetworkDNSDefPtr def, xmlNodePtr node) @@ -751,8 +789,6 @@ virNetworkDNSDefParseXML(virNetworkDNSDefPtr *dnsdef, xmlNodePtr cur; int i, n; int ret = -1; - char *name = NULL; - char *value = NULL; virNetworkDNSDefPtr def = NULL; if (VIR_ALLOC(def) < 0) { @@ -781,38 +817,31 @@ virNetworkDNSDefParseXML(virNetworkDNSDefPtr *dnsdef, } VIR_FREE(nodes); - cur = node->children; - while (cur != NULL) { - if (cur->type == XML_ELEMENT_NODE && - xmlStrEqual(cur->name, BAD_CAST "txt")) { - if (!(name = virXMLPropString(cur, "name"))) { - virNetworkReportError(VIR_ERR_XML_DETAIL, - "%s", _("Missing required name attribute in dns txt record")); - goto error; - } - if (!(value = virXMLPropString(cur, "value"))) { - virNetworkReportError(VIR_ERR_XML_DETAIL, - _("Missing required value attribute in dns txt record '%s'"), name); - goto error; - } + if ((n = virXPathNodeSet("./dns/txt", ctxt, &nodes)) < 0) { + virNetworkReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("cannot extract txt nodes")); + goto error; + } - if (strchr(name, ' ') != NULL) { - virNetworkReportError(VIR_ERR_XML_DETAIL, - _("spaces are not allowed in DNS TXT record names (name is '%s')"), name); - goto error; - } + if (n && VIR_REALLOC_N(def->txtrecords, def->ntxtrecords + n) < 0) { + virReportOOMError(); + goto error; + } + for (i = 0; i < n; i++) { + virNetworkDNSTxtRecordsDefPtr txt; - if (VIR_REALLOC_N(def->txtrecords, def->ntxtrecords + 1) < 0) { - virReportOOMError(); - goto error; - } + txt = virNetworkDNSTxtDefParseXML(nodes[i]); + if (!txt) + goto error; - def->txtrecords[def->ntxtrecords].name = name; - def->txtrecords[def->ntxtrecords].value = value; - def->ntxtrecords++; - name = NULL; - value = NULL; - } else if (cur->type == XML_ELEMENT_NODE && + def->txtrecords[def->ntxtrecords++] = txt; + } + VIR_FREE(nodes); + + + cur = node->children; + while (cur != NULL) { + if (cur->type == XML_ELEMENT_NODE && xmlStrEqual(cur->name, BAD_CAST "host")) { ret = virNetworkDNSHostsDefParseXML(def, cur); if (ret < 0) @@ -824,13 +853,11 @@ virNetworkDNSDefParseXML(virNetworkDNSDefPtr *dnsdef, ret = 0; error: - if (ret < 0) { - VIR_FREE(name); - VIR_FREE(value); + if (ret < 0) virNetworkDNSDefFree(def); - } else { + else *dnsdef = def; - } + return ret; } @@ -1400,9 +1427,11 @@ virNetworkDNSDefFormat(virBufferPtr buf, virBufferAddLit(buf, " <dns>\n"); for (i = 0 ; i < def->ntxtrecords ; i++) { - virBufferAsprintf(buf, " <txt name='%s' value='%s' />\n", - def->txtrecords[i].name, - def->txtrecords[i].value); + virBufferAsprintf(buf, " <txt name='%s'", def->txtrecords[i]->name); + if (def->txtrecords[i]->value) + virBufferAsprintf(buf, " value='%s'", def->txtrecords[i]->value); + + virBufferAsprintf(buf, "/>\n"); } for (i = 0 ; i < def->nsrvrecords ; i++) { diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h index 345c99f..16fbe81 100644 --- a/src/conf/network_conf.h +++ b/src/conf/network_conf.h @@ -99,7 +99,7 @@ typedef struct _virNetworkDNSHostsDef *virNetworkDNSHostsDefPtr; struct _virNetworkDNSDef { unsigned int ntxtrecords; - virNetworkDNSTxtRecordsDefPtr txtrecords; + virNetworkDNSTxtRecordsDefPtr *txtrecords; unsigned int nhosts; virNetworkDNSHostsDefPtr hosts; unsigned int nsrvrecords; diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 95a9b96..c0b05bd 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -459,6 +459,7 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network, int r, ret = -1; int nbleases = 0; int ii; + char *txtValue = NULL; char *domain = NULL; char *target = NULL; char *record = NULL; @@ -522,9 +523,17 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network, int i; for (i = 0; i < dns->ntxtrecords; i++) { - virCommandAddArgFormat(cmd, "--txt-record=%s,%s", - dns->txtrecords[i].name, - dns->txtrecords[i].value); + if (dns->txtrecords[i]->value) { + if (virAsprintf(&txtValue, ",%s", + dns->txtrecords[i]->value) < 0) { + virReportOOMError(); + goto cleanup; + } + } + virCommandAddArgFormat(cmd, "--txt-record=%s%s", + dns->txtrecords[i]->name, + txtValue ? txtValue : ""); + VIR_FREE(txtValue); } for (i = 0; i < dns->nsrvrecords; i++) { @@ -682,6 +691,7 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network, ret = 0; cleanup: + VIR_FREE(txtValue); VIR_FREE(domain); VIR_FREE(target); VIR_FREE(record); -- 1.7.7.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list