These two objects were previously always parsed as a part of an IpDef, but we will now need to be able to parse them on their own for virNetworkUpdate(). Split the parsing functions out, with no functional changes. --- src/conf/network_conf.c | 255 +++++++++++++++++++++++++++++------------------- 1 file changed, 154 insertions(+), 101 deletions(-) diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c index 1ee0951..d916427 100644 --- a/src/conf/network_conf.c +++ b/src/conf/network_conf.c @@ -111,6 +111,13 @@ virNetworkForwardPfDefClear(virNetworkForwardPfDefPtr def) VIR_FREE(def->dev); } +static void +virNetworkDHCPHostDefClear(virNetworkDHCPHostDefPtr def) +{ + VIR_FREE(def->mac); + VIR_FREE(def->name); +} + static void virNetworkIpDefClear(virNetworkIpDefPtr def) { int ii; @@ -118,10 +125,8 @@ static void virNetworkIpDefClear(virNetworkIpDefPtr def) VIR_FREE(def->family); VIR_FREE(def->ranges); - for (ii = 0 ; ii < def->nhosts && def->hosts ; ii++) { - VIR_FREE(def->hosts[ii].mac); - VIR_FREE(def->hosts[ii].name); - } + for (ii = 0 ; ii < def->nhosts && def->hosts ; ii++) + virNetworkDHCPHostDefClear(&def->hosts[ii]); VIR_FREE(def->hosts); VIR_FREE(def->tftproot); @@ -370,9 +375,140 @@ int virNetworkIpDefNetmask(const virNetworkIpDefPtr def, static int -virNetworkDHCPRangeDefParseXML(const char *networkName, - virNetworkIpDefPtr def, - xmlNodePtr node) +virNetworkDHCPRangeDefParse(const char *networkName, + xmlNodePtr node, + virNetworkDHCPRangeDefPtr range) +{ + + + char *start = NULL, *end = NULL; + int ret = -1; + + if (!(start = virXMLPropString(node, "start"))) { + virReportError(VIR_ERR_XML_ERROR, + _("Missing 'start' attribute in dhcp range for network '%s'"), + networkName); + goto cleanup; + } + if (virSocketAddrParse(&range->start, start, AF_UNSPEC) < 0) + goto cleanup; + + if (!(end = virXMLPropString(node, "end"))) { + virReportError(VIR_ERR_XML_ERROR, + _("Missing 'end' attribute in dhcp range for network '%s'"), + networkName); + goto cleanup; + } + if (virSocketAddrParse(&range->end, end, AF_UNSPEC) < 0) + goto cleanup; + + /* do a sanity check of the range */ + if (virSocketAddrGetRange(&range->start, &range->end) < 0) { + virReportError(VIR_ERR_XML_ERROR, + _("Invalid dhcp range '%s' to '%s' in network '%s'"), + start, end, networkName); + goto cleanup; + } + + ret = 0; + +cleanup: + VIR_FREE(start); + VIR_FREE(end); + return ret; +} + +static int +virNetworkDHCPHostDefParse(const char *networkName, + xmlNodePtr node, + virNetworkDHCPHostDefPtr host, + bool partialOkay) +{ + char *mac = NULL, *name = NULL, *ip = NULL; + virMacAddr addr; + virSocketAddr inaddr; + int ret = -1; + + mac = virXMLPropString(node, "mac"); + if (mac != NULL) { + if (virMacAddrParse(mac, &addr) < 0) { + virReportError(VIR_ERR_XML_ERROR, + _("Cannot parse MAC address '%s' in network '%s'"), + mac, networkName); + goto cleanup; + } + if (virMacAddrIsMulticast(&addr)) { + virReportError(VIR_ERR_XML_ERROR, + _("expected unicast mac address, found " + "multicast '%s' in network '%s'"), + (const char *)mac, networkName); + goto cleanup; + } + } + + name = virXMLPropString(node, "name"); + if (name && (!c_isalpha(name[0]))) { + virReportError(VIR_ERR_XML_ERROR, + _("Cannot use name address '%s' in network '%s'"), + name, networkName); + goto cleanup; + } + + ip = virXMLPropString(node, "ip"); + if (ip && (virSocketAddrParse(&inaddr, ip, AF_UNSPEC) < 0)) { + virReportError(VIR_ERR_XML_ERROR, + _("Invalid IP address in static host definition " + "for network '%s'"), + networkName); + goto cleanup; + } + + if (partialOkay) { + /* for search/match, you just need one of the three */ + if (!(mac || name || ip)) { + virReportError(VIR_ERR_XML_ERROR, + _("At least one of name, mac, or ip attribute " + "must be specified for static host definition " + "in network '%s' "), + networkName); + } + } else { + /* normal usage - you need at least one MAC address or one host name */ + if (!(mac || name)) { + virReportError(VIR_ERR_XML_ERROR, + _("Static host definition in network '%s' " + "must have mac or name attribute"), + networkName); + goto cleanup; + } + if (!ip) { + virReportError(VIR_ERR_XML_ERROR, + _("Missing IP address in static host definition " + "for network '%s'"), + networkName); + goto cleanup; + } + } + + host->mac = mac; + mac = NULL; + host->name = name; + name = NULL; + if (ip) + host->ip = inaddr; + ret = 0; + +cleanup: + VIR_FREE(mac); + VIR_FREE(name); + VIR_FREE(ip); + return ret; +} + +static int +virNetworkDHCPDefParse(const char *networkName, + virNetworkIpDefPtr def, + xmlNodePtr node) { xmlNodePtr cur; @@ -381,112 +517,29 @@ virNetworkDHCPRangeDefParseXML(const char *networkName, while (cur != NULL) { if (cur->type == XML_ELEMENT_NODE && xmlStrEqual(cur->name, BAD_CAST "range")) { - char *start, *end; - virSocketAddr saddr, eaddr; - int range; - - if (!(start = virXMLPropString(cur, "start"))) { - cur = cur->next; - continue; - } - if (!(end = virXMLPropString(cur, "end"))) { - VIR_FREE(start); - cur = cur->next; - continue; - } - - if (virSocketAddrParse(&saddr, start, AF_UNSPEC) < 0) { - VIR_FREE(start); - VIR_FREE(end); - return -1; - } - if (virSocketAddrParse(&eaddr, end, AF_UNSPEC) < 0) { - VIR_FREE(start); - VIR_FREE(end); - return -1; - } - - range = virSocketAddrGetRange(&saddr, &eaddr); - if (range < 0) { - virReportError(VIR_ERR_XML_ERROR, - _("Invalid dhcp range '%s' to '%s' in network '%s'"), - start, end, networkName); - VIR_FREE(start); - VIR_FREE(end); - return -1; - } - VIR_FREE(start); - VIR_FREE(end); if (VIR_REALLOC_N(def->ranges, def->nranges + 1) < 0) { virReportOOMError(); return -1; } - def->ranges[def->nranges].start = saddr; - def->ranges[def->nranges].end = eaddr; + if (virNetworkDHCPRangeDefParse(networkName, cur, + &def->ranges[def->nranges]) < 0) { + return -1; + } def->nranges++; + } else if (cur->type == XML_ELEMENT_NODE && xmlStrEqual(cur->name, BAD_CAST "host")) { - char *mac = NULL, *name = NULL, *ip; - virMacAddr addr; - virSocketAddr inaddr; - mac = virXMLPropString(cur, "mac"); - if (mac != NULL) { - if (virMacAddrParse(mac, &addr) < 0) { - virReportError(VIR_ERR_XML_ERROR, - _("Cannot parse MAC address '%s' in network '%s'"), - mac, networkName); - VIR_FREE(mac); - return -1; - } - if (virMacAddrIsMulticast(&addr)) { - virReportError(VIR_ERR_XML_ERROR, - _("expected unicast mac address, found multicast '%s' in network '%s'"), - (const char *)mac, networkName); - VIR_FREE(mac); - return -1; - } - } - name = virXMLPropString(cur, "name"); - if ((name != NULL) && (!c_isalpha(name[0]))) { - virReportError(VIR_ERR_XML_ERROR, - _("Cannot use name address '%s' in network '%s'"), - name, networkName); - VIR_FREE(mac); - VIR_FREE(name); - return -1; - } - /* - * You need at least one MAC address or one host name - */ - if ((mac == NULL) && (name == NULL)) { - virReportError(VIR_ERR_XML_ERROR, - _("Static host definition in network '%s' must have mac or name attribute"), - networkName); - return -1; - } - ip = virXMLPropString(cur, "ip"); - if ((ip == NULL) || - (virSocketAddrParse(&inaddr, ip, AF_UNSPEC) < 0)) { - virReportError(VIR_ERR_XML_ERROR, - _("Missing IP address in static host definition for network '%s'"), - networkName); - VIR_FREE(ip); - VIR_FREE(mac); - VIR_FREE(name); - return -1; - } - VIR_FREE(ip); if (VIR_REALLOC_N(def->hosts, def->nhosts + 1) < 0) { - VIR_FREE(mac); - VIR_FREE(name); virReportOOMError(); return -1; } - def->hosts[def->nhosts].mac = mac; - def->hosts[def->nhosts].name = name; - def->hosts[def->nhosts].ip = inaddr; + if (virNetworkDHCPHostDefParse(networkName, cur, + &def->hosts[def->nhosts], + false) < 0) { + return -1; + } def->nhosts++; } else if (cur->type == XML_ELEMENT_NODE && @@ -853,7 +906,7 @@ virNetworkIPParseXML(const char *networkName, while (cur != NULL) { if (cur->type == XML_ELEMENT_NODE && xmlStrEqual(cur->name, BAD_CAST "dhcp")) { - result = virNetworkDHCPRangeDefParseXML(networkName, def, cur); + result = virNetworkDHCPDefParse(networkName, def, cur); if (result) goto error; -- 1.7.11.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list