Esempio n. 1
0
static int
virInterfaceDefParseIp(virInterfaceIpDefPtr def,
                       xmlXPathContextPtr ctxt) {
    int ret = 0;
    char *tmp;
    long l;

    tmp = virXPathString("string(./@address)", ctxt);
    def->address = tmp;
    if (tmp != NULL) {
        ret = virXPathLong("string(./@prefix)", ctxt, &l);
        if (ret == 0)
            def->prefix = (int) l;
        else if (ret == -2) {
            virInterfaceReportError(VIR_ERR_XML_ERROR,
                              "%s", _("Invalid ip address prefix value"));
            return -1;
        }
    }

    return 0;
}
Esempio n. 2
0
static int
virInterfaceDefParseBondArpValid(xmlXPathContextPtr ctxt) {
    char *tmp;
    int ret = 0;

    tmp = virXPathString("string(./arpmon/@validate)", ctxt);
    if (tmp == NULL)
        return VIR_INTERFACE_BOND_ARP_NONE;
    if (STREQ(tmp, "active"))
        ret = VIR_INTERFACE_BOND_ARP_ACTIVE;
    else if (STREQ(tmp, "backup"))
        ret = VIR_INTERFACE_BOND_ARP_BACKUP;
    else if (STREQ(tmp, "all"))
        ret = VIR_INTERFACE_BOND_ARP_ALL;
    else {
        virInterfaceReportError(VIR_ERR_XML_ERROR,
                                _("unknown arp bonding validate %s"), tmp);
        ret = -1;
    }
    VIR_FREE(tmp);
    return ret;
}
Esempio n. 3
0
static int
virInterfaceDefParseBondItfs(virInterfaceDefPtr def,
                             xmlXPathContextPtr ctxt) {
    xmlNodePtr *interfaces = NULL;
    xmlNodePtr bond = ctxt->node;
    virInterfaceDefPtr itf;
    int nbItf, i;
    int ret = 0;

    nbItf = virXPathNodeSet("./interface", ctxt, &interfaces);
    if (nbItf <= 0) {
        virInterfaceReportError(VIR_ERR_XML_ERROR,
                                "%s", _("bond has no interfaces"));
        ret = -1;
        goto error;
    }
    if (VIR_ALLOC_N(def->data.bond.itf, nbItf) < 0) {
        virReportOOMError();
        ret = -1;
        goto error;
    }
    def->data.bond.nbItf = nbItf;

    for (i = 0; i < nbItf;i++) {
        ctxt->node = interfaces[i];
        itf = virInterfaceDefParseXML(ctxt, VIR_INTERFACE_TYPE_BOND);
        if (itf == NULL) {
            ret = -1;
            def->data.bond.nbItf = i;
            goto error;
        }
        def->data.bond.itf[i] = itf;
    }

error:
    VIR_FREE(interfaces);
    ctxt->node = bond;
    return(ret);
}
Esempio n. 4
0
static int
virInterfaceDefParseStartMode(virInterfaceDefPtr def,
                              xmlXPathContextPtr ctxt) {
    char *tmp;

    tmp = virXPathString("string(./start/@mode)", ctxt);
    if (tmp == NULL)
        def->startmode = VIR_INTERFACE_START_UNSPECIFIED;
    else if (STREQ(tmp, "onboot"))
        def->startmode = VIR_INTERFACE_START_ONBOOT;
    else if (STREQ(tmp, "hotplug"))
        def->startmode = VIR_INTERFACE_START_HOTPLUG;
    else if (STREQ(tmp, "none"))
        def->startmode = VIR_INTERFACE_START_NONE;
    else {
        virInterfaceReportError(VIR_ERR_XML_ERROR,
                                _("unknown interface startmode %s"), tmp);
        VIR_FREE(tmp);
        return -1;
    }
    VIR_FREE(tmp);
    return 0;
}
Esempio n. 5
0
virInterfaceObjPtr virInterfaceAssignDef(virInterfaceObjListPtr interfaces,
                                         const virInterfaceDefPtr def)
{
    virInterfaceObjPtr iface;

    if ((iface = virInterfaceFindByName(interfaces, def->name))) {
        virInterfaceDefFree(iface->def);
        iface->def = def;

        return iface;
    }

    if (VIR_ALLOC(iface) < 0) {
        virReportOOMError();
        return NULL;
    }
    if (virMutexInit(&iface->lock) < 0) {
        virInterfaceReportError(VIR_ERR_INTERNAL_ERROR,
                                "%s", _("cannot initialize mutex"));
        VIR_FREE(iface);
        return NULL;
    }
    virInterfaceObjLock(iface);
    iface->def = def;

    if (VIR_REALLOC_N(interfaces->objs, interfaces->count + 1) < 0) {
        virReportOOMError();
        VIR_FREE(iface);
        return NULL;
    }

    interfaces->objs[interfaces->count] = iface;
    interfaces->count++;

    return iface;

}
Esempio n. 6
0
static virInterfaceDefPtr
virInterfaceDefParseXML(xmlXPathContextPtr ctxt, int parentIfType) {
    virInterfaceDefPtr def;
    int type;
    char *tmp;
    xmlNodePtr cur = ctxt->node;

    /* check @type */
    tmp = virXPathString("string(./@type)", ctxt);
    if (tmp == NULL) {
        virInterfaceReportError(VIR_ERR_XML_ERROR,
                                "%s", _("interface misses the type attribute"));
        return NULL;
    }
    type = virInterfaceTypeFromString(tmp);
    if (type == -1) {
        virInterfaceReportError(VIR_ERR_XML_ERROR,
                                _("unknown interface type %s"), tmp);
        VIR_FREE(tmp);
        return NULL;
    }
    VIR_FREE(tmp);

    if (VIR_ALLOC(def) < 0) {
        virReportOOMError();
        return NULL;
    }

    if (((parentIfType == VIR_INTERFACE_TYPE_BOND)
         && (type != VIR_INTERFACE_TYPE_ETHERNET))
        || ((parentIfType == VIR_INTERFACE_TYPE_BRIDGE)
            && (type != VIR_INTERFACE_TYPE_ETHERNET)
            && (type != VIR_INTERFACE_TYPE_BOND)
            && (type != VIR_INTERFACE_TYPE_VLAN))
        || (parentIfType == VIR_INTERFACE_TYPE_ETHERNET)
        || (parentIfType == VIR_INTERFACE_TYPE_VLAN))
        {
        virInterfaceReportError(VIR_ERR_XML_ERROR,
                                _("interface has unsupported type '%s'"),
                                virInterfaceTypeToString(type));
        goto error;
    }
    def->type = type;
    switch (type) {
        case VIR_INTERFACE_TYPE_ETHERNET:
            if (virInterfaceDefParseName(def, ctxt) < 0)
                goto error;
            tmp = virXPathString("string(./mac/@address)", ctxt);
            if (tmp != NULL)
                def->mac = tmp;
            if (parentIfType == VIR_INTERFACE_TYPE_LAST) {
                /* only recognize these in toplevel bond interfaces */
                if (virInterfaceDefParseStartMode(def, ctxt) < 0)
                    goto error;
                if (virInterfaceDefParseMtu(def, ctxt) < 0)
                    goto error;
                if (virInterfaceDefParseIfAdressing(def, ctxt) < 0)
                    goto error;
            }
            break;
        case VIR_INTERFACE_TYPE_BRIDGE: {
            xmlNodePtr bridge;

            if (virInterfaceDefParseName(def, ctxt) < 0)
                goto error;
            if (virInterfaceDefParseStartMode(def, ctxt) < 0)
                goto error;
            if (virInterfaceDefParseMtu(def, ctxt) < 0)
                goto error;
            if (virInterfaceDefParseIfAdressing(def, ctxt) < 0)
                goto error;

            bridge = virXPathNode("./bridge[1]", ctxt);
            if (bridge == NULL) {
                virInterfaceReportError(VIR_ERR_XML_ERROR,
                                        "%s", _("bridge interface misses the bridge element"));
                goto error;
            }
            tmp = virXMLPropString(bridge, "stp");
            def->data.bridge.stp = -1;
            if (tmp != NULL) {
                if (STREQ(tmp, "on")) {
                    def->data.bridge.stp = 1;
                } else if (STREQ(tmp, "off")) {
                    def->data.bridge.stp = 0;
                } else {
                    virInterfaceReportError(VIR_ERR_XML_ERROR,
                          _("bridge interface stp should be on or off got %s"),
                                            tmp);
                    VIR_FREE(tmp);
                    goto error;
                }
                VIR_FREE(tmp);
            }
            def->data.bridge.delay = virXMLPropString(bridge, "delay");
            ctxt->node = bridge;
            virInterfaceDefParseBridge(def, ctxt);
            break;
        }
        case VIR_INTERFACE_TYPE_BOND: {
            xmlNodePtr bond;

            if (virInterfaceDefParseName(def, ctxt) < 0)
                goto error;
            if (parentIfType == VIR_INTERFACE_TYPE_LAST) {
                /* only recognize these in toplevel bond interfaces */
                if (virInterfaceDefParseStartMode(def, ctxt) < 0)
                    goto error;
                if (virInterfaceDefParseMtu(def, ctxt) < 0)
                    goto error;
                if (virInterfaceDefParseIfAdressing(def, ctxt) < 0)
                    goto error;
            }

            bond = virXPathNode("./bond[1]", ctxt);
            if (bond == NULL) {
                virInterfaceReportError(VIR_ERR_XML_ERROR,
                            "%s", _("bond interface misses the bond element"));
                goto error;
            }
            ctxt->node = bond;
            if (virInterfaceDefParseBond(def, ctxt)  < 0)
                goto error;
            break;
        }
        case VIR_INTERFACE_TYPE_VLAN: {
            xmlNodePtr vlan;

            tmp = virXPathString("string(./@name)", ctxt);
            if (tmp != NULL)
                def->name = tmp;
            if (virInterfaceDefParseStartMode(def, ctxt) < 0)
                goto error;
            if (virInterfaceDefParseIfAdressing(def, ctxt) < 0)
                goto error;
            vlan = virXPathNode("./vlan[1]", ctxt);
            if (vlan == NULL) {
                virInterfaceReportError(VIR_ERR_XML_ERROR,
                            "%s", _("vlan interface misses the vlan element"));
                goto error;
            }
            ctxt->node = vlan;
            if (virInterfaceDefParseVlan(def, ctxt)  < 0)
                goto error;
            break;
        }

    }

    ctxt->node = cur;
    return def;

error:
    ctxt->node = cur;
    virInterfaceDefFree(def);
    return NULL;
}
Esempio n. 7
0
static int
virInterfaceDefParseBond(virInterfaceDefPtr def,
                         xmlXPathContextPtr ctxt) {
    int ret = -1;
    unsigned long tmp;

    def->data.bond.mode = virInterfaceDefParseBondMode(ctxt);
    if (def->data.bond.mode < 0)
        goto error;

    ret = virInterfaceDefParseBondItfs(def, ctxt);
    if (ret != 0)
       goto error;

    if (virXPathNode("./miimon[1]", ctxt) != NULL) {
        def->data.bond.monit = VIR_INTERFACE_BOND_MONIT_MII;

        ret = virXPathULong("string(./miimon/@freq)", ctxt, &tmp);
        if ((ret == -2) || (ret == -1)) {
            virInterfaceReportError(VIR_ERR_XML_ERROR,
                     "%s", _("bond interface miimon freq missing or invalid"));
            goto error;
        }
        def->data.bond.frequency = (int) tmp;

        ret = virXPathULong("string(./miimon/@downdelay)", ctxt, &tmp);
        if (ret == -2) {
            virInterfaceReportError(VIR_ERR_XML_ERROR,
                     "%s", _("bond interface miimon downdelay invalid"));
            goto error;
        } else if (ret == 0) {
            def->data.bond.downdelay = (int) tmp;
        }

        ret = virXPathULong("string(./miimon/@updelay)", ctxt, &tmp);
        if (ret == -2) {
            virInterfaceReportError(VIR_ERR_XML_ERROR,
                     "%s", _("bond interface miimon updelay invalid"));
            goto error;
        } else if (ret == 0) {
            def->data.bond.updelay = (int) tmp;
        }

        def->data.bond.carrier = virInterfaceDefParseBondMiiCarrier(ctxt);
        if (def->data.bond.carrier < 0) {
            ret = -1;
            goto error;
        }

    } else if (virXPathNode("./arpmon[1]", ctxt) != NULL) {

        def->data.bond.monit = VIR_INTERFACE_BOND_MONIT_ARP;

        ret = virXPathULong("string(./arpmon/@interval)", ctxt, &tmp);
        if ((ret == -2) || (ret == -1)) {
            virInterfaceReportError(VIR_ERR_XML_ERROR,
                 "%s", _("bond interface arpmon interval missing or invalid"));
            goto error;
        }
        def->data.bond.interval = (int) tmp;

        def->data.bond.target =
            virXPathString("string(./arpmon/@target)", ctxt);
        if (def->data.bond.target == NULL) {
            virInterfaceReportError(VIR_ERR_XML_ERROR,
                 "%s", _("bond interface arpmon target missing"));
            ret = -1;
            goto error;
        }

        def->data.bond.validate = virInterfaceDefParseBondArpValid(ctxt);
        if (def->data.bond.validate < 0) {
            ret = -1;
            goto error;
        }
    }
error:
    return ret;
}
Esempio n. 8
0
static int
virInterfaceDefParseIfAdressing(virInterfaceDefPtr def,
                                xmlXPathContextPtr ctxt) {
    xmlNodePtr save;
    xmlNodePtr *protoNodes = NULL;
    int nProtoNodes, pp, ret = -1;
    char *tmp;

    save = ctxt->node;

    nProtoNodes = virXPathNodeSet("./protocol", ctxt, &protoNodes);
    if (nProtoNodes < 0)
        goto error;

    if (nProtoNodes == 0) {
        /* no protocols is an acceptable outcome */
        return 0;
    }

    if (VIR_ALLOC_N(def->protos, nProtoNodes) < 0) {
        virReportOOMError();
        goto error;
    }

    def->nprotos = 0;
    for (pp = 0; pp < nProtoNodes; pp++) {

        virInterfaceProtocolDefPtr proto;

        if (VIR_ALLOC(proto) < 0) {
            virReportOOMError();
            goto error;
        }

        ctxt->node = protoNodes[pp];
        tmp = virXPathString("string(./@family)", ctxt);
        if (tmp == NULL) {
            virInterfaceReportError(VIR_ERR_XML_ERROR,
                                    "%s", _("protocol misses the family attribute"));
            virInterfaceProtocolDefFree(proto);
            goto error;
        }
        proto->family = tmp;
        if (STREQ(tmp, "ipv4")) {
            ret = virInterfaceDefParseProtoIPv4(proto, ctxt);
            if (ret != 0) {
                virInterfaceProtocolDefFree(proto);
                goto error;
            }
        } else if (STREQ(tmp, "ipv6")) {
            ret = virInterfaceDefParseProtoIPv6(proto, ctxt);
            if (ret != 0) {
                virInterfaceProtocolDefFree(proto);
                goto error;
            }
        } else {
            virInterfaceReportError(VIR_ERR_XML_ERROR,
                                    _("unsupported protocol family '%s'"), tmp);
            virInterfaceProtocolDefFree(proto);
            goto error;
        }
        def->protos[def->nprotos++] = proto;
    }

    ret = 0;

error:
    VIR_FREE(protoNodes);
    ctxt->node = save;
    return ret;

}
Esempio n. 9
0
static int
virInterfaceDefDevFormat(virBufferPtr buf,
                         const virInterfaceDefPtr def, int level) {
    const char *type = NULL;

    if (def == NULL) {
        virInterfaceReportError(VIR_ERR_INTERNAL_ERROR,
                        "%s", _("virInterfaceDefFormat NULL def"));
        goto cleanup;
    }

    if ((def->name == NULL) && (def->type != VIR_INTERFACE_TYPE_VLAN)) {
        virInterfaceReportError(VIR_ERR_INTERNAL_ERROR,
                        "%s", _("virInterfaceDefFormat missing interface name"));
        goto cleanup;
    }

    if (!(type = virInterfaceTypeToString(def->type))) {
        virInterfaceReportError(VIR_ERR_INTERNAL_ERROR,
                        _("unexpected interface type %d"), def->type);
        goto cleanup;
    }

    virBufferAsprintf(buf, "%*s<interface type='%s' ", level*2, "", type);
    if (def->name != NULL)
        virBufferEscapeString(buf, "name='%s'", def->name);
    virBufferAddLit(buf, ">\n");

    switch (def->type) {
        case VIR_INTERFACE_TYPE_ETHERNET:
            virInterfaceStartmodeDefFormat(buf, def->startmode, level);
            if (def->mac != NULL)
                virBufferAsprintf(buf, "%*s  <mac address='%s'/>\n",
                                  level*2, "", def->mac);
            if (def->mtu != 0)
                virBufferAsprintf(buf, "%*s  <mtu size='%d'/>\n",
                                  level*2, "", def->mtu);
            virInterfaceProtocolDefFormat(buf, def, level);
            break;
        case VIR_INTERFACE_TYPE_BRIDGE:
            virInterfaceStartmodeDefFormat(buf, def->startmode, level);
            if (def->mtu != 0)
                virBufferAsprintf(buf, "%*s  <mtu size='%d'/>\n",
                                  level*2, "", def->mtu);
            virInterfaceProtocolDefFormat(buf, def, level);
            virInterfaceBridgeDefFormat(buf, def, level);
            break;
        case VIR_INTERFACE_TYPE_BOND:
            virInterfaceStartmodeDefFormat(buf, def->startmode, level);
            if (def->mtu != 0)
                virBufferAsprintf(buf, "%*s  <mtu size='%d'/>\n",
                                  level*2, "", def->mtu);
            virInterfaceProtocolDefFormat(buf, def, level);
            virInterfaceBondDefFormat(buf, def, level);
            break;
        case VIR_INTERFACE_TYPE_VLAN:
            virInterfaceStartmodeDefFormat(buf, def->startmode, level);
            if (def->mac != NULL)
                virBufferAsprintf(buf, "%*s  <mac address='%s'/>\n",
                                  level*2, "", def->mac);
            if (def->mtu != 0)
                virBufferAsprintf(buf, "%*s  <mtu size='%d'/>\n",
                                  level*2, "", def->mtu);
            virInterfaceProtocolDefFormat(buf, def, level);
            virInterfaceVlanDefFormat(buf, def, level);
            break;
    }

    virBufferAsprintf(buf, "%*s</interface>\n", level*2, "");

    if (virBufferError(buf))
        goto no_memory;
    return 0;
no_memory:
    virReportOOMError();
cleanup:
    return -1;
}