virNodeDevCapNetParseXML(xmlXPathContextPtr ctxt,
                         virNodeDeviceDefPtr def,
                         xmlNodePtr node,
                         virNodeDevCapNetPtr net)
{
    VIR_XPATH_NODE_AUTORESTORE(ctxt)
    xmlNodePtr lnk;
    size_t i = -1;
    int ret = -1, n = -1;
    char *tmp = NULL;
    xmlNodePtr *nodes = NULL;

    ctxt->node = node;

    net->ifname = virXPathString("string(./interface[1])", ctxt);
    if (!net->ifname) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("no network interface supplied for '%s'"),
                       def->name);
        goto out;
    }

    net->address = virXPathString("string(./address[1])", ctxt);

    if ((n = virXPathNodeSet("./feature", ctxt, &nodes)) < 0)
        goto out;

    if (n > 0)
        net->features = virBitmapNew(VIR_NET_DEV_FEAT_LAST);

    for (i = 0; i < n; i++) {
        int val;
        if (!(tmp = virXMLPropString(nodes[i], "name"))) {
            virReportError(VIR_ERR_XML_ERROR, "%s",
                           _("missing network device feature name"));
            goto out;
        }

        if ((val = virNetDevFeatureTypeFromString(tmp)) < 0) {
            virReportError(VIR_ERR_XML_ERROR,
                           _("unknown network device feature '%s'"),
                           tmp);
            goto out;
        }
        ignore_value(virBitmapSetBit(net->features, val));
        VIR_FREE(tmp);
    }

    net->subtype = VIR_NODE_DEV_CAP_NET_LAST;

    tmp = virXPathString("string(./capability/@type)", ctxt);
    if (tmp) {
        int val = virNodeDevNetCapTypeFromString(tmp);
        VIR_FREE(tmp);
        if (val < 0) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("invalid network type supplied for '%s'"),
                           def->name);
            goto out;
        }
        net->subtype = val;
    }

    lnk = virXPathNode("./link", ctxt);
    if (lnk && virInterfaceLinkParseXML(lnk, &net->lnk) < 0)
        goto out;

    ret = 0;
 out:
    VIR_FREE(nodes);
    VIR_FREE(tmp);
    return ret;
}
virNodeDevCapNetParseXML(xmlXPathContextPtr ctxt,
                         virNodeDeviceDefPtr def,
                         xmlNodePtr node,
                         virNodeDevCapNetPtr net)
{
    VIR_XPATH_NODE_AUTORESTORE(ctxt)
    xmlNodePtr lnk;
    size_t i = -1;
    int ret = -1, n = -1;
    char *tmp = NULL;
    xmlNodePtr *nodes = NULL;

    ctxt->node = node;

    net->ifname = virXPathString("string(./interface[1])", ctxt);
    if (!net->ifname) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("no network interface supplied for '%s'"),
                       def->name);
        goto out;
    }

    net->address = virXPathString("string(./address[1])", ctxt);

    if ((n = virXPathNodeSet("./feature", ctxt, &nodes)) < 0)
        goto out;

    if (n > 0)
        net->features = virBitmapNew(VIR_NET_DEV_FEAT_LAST);

    for (i = 0; i < n; i++) {
        int val;
        if (!(tmp = virXMLPropString(nodes[i], "name"))) {
            virReportError(VIR_ERR_XML_ERROR, "%s",
                           _("missing network device feature name"));
            goto out;
        }

        if ((val = virNetDevFeatureTypeFromString(tmp)) < 0) {
            virReportError(VIR_ERR_XML_ERROR,
                           _("unknown network device feature '%s'"),
                           tmp);
            goto out;
        }
        ignore_value(virBitmapSetBit(net->features, val));
        VIR_FREE(tmp);
    }

    net->subtype = VIR_NODE_DEV_CAP_NET_LAST;

    tmp = virXPathString("string(./capability/@type)", ctxt);
    if (tmp) {
        int val = virNodeDevNetCapTypeFromString(tmp);
        VIR_FREE(tmp);
        if (val < 0) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                           _("invalid network type supplied for '%s'"),
                           def->name);
            goto out;
        }
        net->subtype = val;
    }

    lnk = virXPathNode("./link", ctxt);
    if (lnk && virInterfaceLinkParseXML(lnk, &net->lnk) < 0)
        goto out;

    ret = 0;
 out:
    VIR_FREE(nodes);
    VIR_FREE(tmp);
    return ret;
}