Example #1
0
static int
virNWFilterIncludeDefToRuleInst(virNWFilterIncludeDefPtr inc,
                                virNWFilterHashTablePtr vars,
                                virNWFilterInstPtr inst)
{
    virNWFilterHashTablePtr tmpvars = NULL;
    int ret = -1;
    char *xml;

    if (virAsprintf(&xml, "%s/nwfilterxml2firewalldata/%s.xml",
                    abs_srcdir, inc->filterref) < 0)
        return -1;

    /* create a temporary hashmap for depth-first tree traversal */
    if (!(tmpvars = virNWFilterCreateVarsFrom(inc->params,
                                              vars)))
        goto cleanup;

    if (virNWFilterDefToInst(xml,
                             tmpvars,
                             inst) < 0)
        goto cleanup;

    ret = 0;
 cleanup:
    if (ret < 0)
        virNWFilterInstReset(inst);
    virNWFilterHashTableFree(tmpvars);
    VIR_FREE(xml);
    return ret;
}
Example #2
0
static void
virNWFilterRuleInstFree(virNWFilterRuleInstPtr inst)
{
    if (!inst)
        return;

    virNWFilterHashTableFree(inst->vars);
    VIR_FREE(inst);
}
static void
virNWFilterIPAddrLearnReqFree(virNWFilterIPAddrLearnReqPtr req)
{
    if (!req)
        return;

    VIR_FREE(req->filtername);
    virNWFilterHashTableFree(req->filterparams);

    VIR_FREE(req);
}
Example #4
0
/**
 * virNWFilterCreateVarHashmap:
 * @macaddr: pointer to string containing formatted MAC address of interface
 * @ipaddr: pointer to string containing formatted IP address used by
 *          VM on this interface; may be NULL
 *
 * Create a hashmap used for evaluating the firewall rules. Initializes
 * it with the standard variable 'MAC' and 'IP' if provided.
 *
 * Returns pointer to hashmap, NULL if an error occcurred.
 */
virNWFilterHashTablePtr
virNWFilterCreateVarHashmap(char *macaddr,
                            const virNWFilterVarValuePtr ipaddr) {
    virNWFilterHashTablePtr table = virNWFilterHashTableCreate(0);
    if (!table)
        return NULL;

    if (virNWFilterVarHashmapAddStdValues(table, macaddr, ipaddr) < 0) {
        virNWFilterHashTableFree(table);
        return NULL;
    }
    return table;
}
Example #5
0
/**
 * virNWFilterCreateVarHashmap:
 * @macaddr: pointer to string containing formatted MAC address of interface
 * @ipaddr: pointer to string containing formatted IP address used by
 *          VM on this interface; may be NULL
 *
 * Create a hashmap used for evaluating the firewall rules. Initializes
 * it with the standard variable 'MAC' and 'IP' if provided.
 *
 * Returns pointer to hashmap, NULL if an error occcurred and error message
 * is attached to the virConnect object.
 */
virNWFilterHashTablePtr
virNWFilterCreateVarHashmap(char *macaddr, char *ipaddr) {
    virNWFilterHashTablePtr table = virNWFilterHashTableCreate(0);
    if (!table) {
        virReportOOMError();
        return NULL;
    }

    if (virNWFilterVarHashmapAddStdValues(table, macaddr, ipaddr)) {
        virNWFilterHashTableFree(table);
        return NULL;
    }
    return table;
}
Example #6
0
static int testCompareXMLToArgvFiles(const char *xml,
                                     const char *cmdline)
{
    char *actualargv = NULL;
    virBuffer buf = VIR_BUFFER_INITIALIZER;
    virNWFilterHashTablePtr vars = virNWFilterHashTableCreate(0);
    virNWFilterInst inst;
    int ret = -1;

    memset(&inst, 0, sizeof(inst));

    virCommandSetDryRun(&buf, NULL, NULL);

    if (!vars)
        goto cleanup;

    if (testSetDefaultParameters(vars) < 0)
        goto cleanup;

    if (virNWFilterDefToInst(xml,
                             vars,
                             &inst) < 0)
        goto cleanup;

    if (ebiptables_driver.applyNewRules("vnet0", inst.rules, inst.nrules) < 0)
        goto cleanup;

    if (virBufferError(&buf))
        goto cleanup;

    actualargv = virBufferContentAndReset(&buf);
    virTestClearCommandPath(actualargv);
    virCommandSetDryRun(NULL, NULL, NULL);

    testRemoveCommonRules(actualargv);

    if (virTestCompareToFile(actualargv, cmdline) < 0)
        goto cleanup;

    ret = 0;

 cleanup:
    virBufferFreeAndReset(&buf);
    VIR_FREE(actualargv);
    virNWFilterInstReset(&inst);
    virNWFilterHashTableFree(vars);
    return ret;
}
Example #7
0
static virNWFilterHashTablePtr
virNWFilterCreateVarsFrom(virNWFilterHashTablePtr vars1,
                          virNWFilterHashTablePtr vars2)
{
    virNWFilterHashTablePtr res = virNWFilterHashTableCreate(0);
    if (!res)
        return NULL;

    if (virNWFilterHashTablePutAll(vars1, res) < 0)
        goto err_exit;

    if (virNWFilterHashTablePutAll(vars2, res) < 0)
        goto err_exit;

    return res;

 err_exit:
    virNWFilterHashTableFree(res);
    return NULL;
}
Example #8
0
void
virNWFilterIPAddrMapShutdown(void)
{
    virNWFilterHashTableFree(ipAddressMap);
    ipAddressMap = NULL;
}
Example #9
0
/*
 * Call this function while holding the NWFilter filter update lock
 */
static int
__virNWFilterInstantiateFilter(virConnectPtr conn,
                               bool teardownOld,
                               const char *ifname,
                               int ifindex,
                               const char *linkdev,
                               enum virDomainNetType nettype,
                               const unsigned char *macaddr,
                               const char *filtername,
                               virNWFilterHashTablePtr filterparams,
                               enum instCase useNewFilter,
                               virNWFilterDriverStatePtr driver,
                               bool forceWithPendingReq,
                               bool *foundNewFilter)
{
    int rc;
    const char *drvname = EBIPTABLES_DRIVER_ID;
    virNWFilterTechDriverPtr techdriver;
    virNWFilterObjPtr obj;
    virNWFilterHashTablePtr vars, vars1;
    virNWFilterDefPtr filter;
    char vmmacaddr[VIR_MAC_STRING_BUFLEN] = {0};
    char *str_macaddr = NULL;
    const char *ipaddr;
    char *str_ipaddr = NULL;

    techdriver = virNWFilterTechDriverForName(drvname);

    if (!techdriver) {
        virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
                               _("Could not get access to ACL tech "
                               "driver '%s'"),
                               drvname);
        return 1;
    }

    VIR_DEBUG("filter name: %s", filtername);

    obj = virNWFilterObjFindByName(&driver->nwfilters, filtername);
    if (!obj) {
        virNWFilterReportError(VIR_ERR_NO_NWFILTER,
                               _("Could not find filter '%s'"),
                               filtername);
        return 1;
    }

    if (obj->wantRemoved) {
        virNWFilterReportError(VIR_ERR_NO_NWFILTER,
                               _("Filter '%s' is in use."),
                               filtername);
        rc = 1;
        goto err_exit;
    }

    virFormatMacAddr(macaddr, vmmacaddr);
    str_macaddr = strdup(vmmacaddr);
    if (!str_macaddr) {
        virReportOOMError();
        rc = 1;
        goto err_exit;
    }

    ipaddr = virNWFilterGetIpAddrForIfname(ifname);
    if (ipaddr) {
        str_ipaddr = strdup(ipaddr);
        if (!str_ipaddr) {
            virReportOOMError();
            rc = 1;
            goto err_exit;
        }
    }

    vars1 = virNWFilterCreateVarHashmap(str_macaddr, str_ipaddr);
    if (!vars1) {
        rc = 1;
        goto err_exit;
    }

    str_macaddr = NULL;
    str_ipaddr = NULL;

    vars = virNWFilterCreateVarsFrom(vars1,
                                     filterparams);
    if (!vars) {
        rc = 1;
        goto err_exit_vars1;
    }

    filter = obj->def;

    switch (useNewFilter) {
    case INSTANTIATE_FOLLOW_NEWFILTER:
        if (obj->newDef) {
            filter = obj->newDef;
            *foundNewFilter = true;
        }
    break;

    case INSTANTIATE_ALWAYS:
    break;
    }

    rc = virNWFilterInstantiate(conn,
                                techdriver,
                                nettype,
                                filter,
                                ifname,
                                ifindex,
                                linkdev,
                                vars,
                                useNewFilter, foundNewFilter,
                                teardownOld,
                                macaddr,
                                driver,
                                forceWithPendingReq);

    virNWFilterHashTableFree(vars);

err_exit_vars1:
    virNWFilterHashTableFree(vars1);

err_exit:
    virNWFilterObjUnlock(obj);

    VIR_FREE(str_ipaddr);
    VIR_FREE(str_macaddr);

    return rc;
}
Example #10
0
/**
 * virNWFilterInstantiate:
 * @conn: pointer to virConnect object
 * @techdriver: The driver to use for instantiation
 * @filter: The filter to instantiate
 * @ifname: The name of the interface to apply the rules to
 * @vars: A map holding variable names and values used for instantiating
 *  the filter and its subfilters.
 * @forceWithPendingReq: Ignore the check whether a pending learn request
 *  is active; 'true' only when the rules are applied late
 *
 * Returns 0 on success, a value otherwise.
 *
 * Instantiate a filter by instantiating the filter itself along with
 * all its subfilters in a depth-first traversal of the tree of referenced
 * filters. The name of the interface to which the rules belong must be
 * provided. Apply the values of variables as needed.
 *
 * Call this function while holding the NWFilter filter update lock
 */
static int
virNWFilterInstantiate(virConnectPtr conn,
                       virNWFilterTechDriverPtr techdriver,
                       enum virDomainNetType nettype,
                       virNWFilterDefPtr filter,
                       const char *ifname,
                       int ifindex,
                       const char *linkdev,
                       virNWFilterHashTablePtr vars,
                       enum instCase useNewFilter, bool *foundNewFilter,
                       bool teardownOld,
                       const unsigned char *macaddr,
                       virNWFilterDriverStatePtr driver,
                       bool forceWithPendingReq)
{
    int rc;
    int j, nptrs;
    int nEntries = 0;
    virNWFilterRuleInstPtr *insts = NULL;
    void **ptrs = NULL;
    int instantiate = 1;

    virNWFilterHashTablePtr missing_vars = virNWFilterHashTableCreate(0);
    if (!missing_vars) {
        virReportOOMError();
        rc = 1;
        goto err_exit;
    }

    rc = virNWFilterDetermineMissingVarsRec(conn,
                                            filter,
                                            vars,
                                            missing_vars,
                                            useNewFilter,
                                            driver);
    if (rc)
        goto err_exit;

    if (virHashSize(missing_vars->hashTable) == 1) {
        if (virHashLookup(missing_vars->hashTable,
                          NWFILTER_STD_VAR_IP) != NULL) {
            if (virNWFilterLookupLearnReq(ifindex) == NULL) {
                rc = virNWFilterLearnIPAddress(techdriver,
                                               ifname,
                                               ifindex,
                                               linkdev,
                                               nettype, macaddr,
                                               filter->name,
                                               vars, driver,
                                               DETECT_DHCP|DETECT_STATIC);
            }
            goto err_exit;
        }
        rc = 1;
        goto err_exit;
    } else if (virHashSize(missing_vars->hashTable) > 1) {
        rc = 1;
        goto err_exit;
    } else if (!forceWithPendingReq &&
               virNWFilterLookupLearnReq(ifindex) != NULL) {
        goto err_exit;
    }

    rc = _virNWFilterInstantiateRec(conn,
                                    techdriver,
                                    nettype,
                                    filter,
                                    ifname,
                                    vars,
                                    &nEntries, &insts,
                                    useNewFilter, foundNewFilter,
                                    driver);

    if (rc)
        goto err_exit;

    switch (useNewFilter) {
    case INSTANTIATE_FOLLOW_NEWFILTER:
        instantiate = *foundNewFilter;
    break;
    case INSTANTIATE_ALWAYS:
        instantiate = 1;
    break;
    }

    if (instantiate) {

        rc = virNWFilterRuleInstancesToArray(nEntries, insts,
                                             &ptrs, &nptrs);
        if (rc)
            goto err_exit;

        if (virNWFilterLockIface(ifname))
            goto err_exit;

        rc = techdriver->applyNewRules(conn, ifname, nptrs, ptrs);

        if (teardownOld && rc == 0)
            techdriver->tearOldRules(conn, ifname);

        if (rc == 0 && ifaceCheck(false, ifname, NULL, ifindex)) {
            /* interface changed/disppeared */
            techdriver->allTeardown(ifname);
            rc = 1;
        }

        virNWFilterUnlockIface(ifname);
    }

err_exit:

    for (j = 0; j < nEntries; j++)
        virNWFilterRuleInstFree(insts[j]);

    VIR_FREE(insts);
    VIR_FREE(ptrs);

    virNWFilterHashTableFree(missing_vars);

    return rc;
}
Example #11
0
static int
virNWFilterDetermineMissingVarsRec(virConnectPtr conn,
                                   virNWFilterDefPtr filter,
                                   virNWFilterHashTablePtr vars,
                                   virNWFilterHashTablePtr missing_vars,
                                   int useNewFilter,
                                   virNWFilterDriverStatePtr driver)
{
    virNWFilterObjPtr obj;
    int rc = 0;
    int i, j;
    virNWFilterDefPtr next_filter;

    for (i = 0; i < filter->nentries; i++) {
        virNWFilterRuleDefPtr    rule = filter->filterEntries[i]->rule;
        virNWFilterIncludeDefPtr inc  = filter->filterEntries[i]->include;
        if (rule) {
            /* check all variables of this rule */
            for (j = 0; j < rule->nvars; j++) {
                if (!virHashLookup(vars->hashTable, rule->vars[j])) {
                    virNWFilterHashTablePut(missing_vars, rule->vars[j],
                                            strdup("1"), 1);
                }
            }
        } else if (inc) {
            VIR_DEBUG("Following filter %s\n", inc->filterref);
            obj = virNWFilterObjFindByName(&driver->nwfilters, inc->filterref);
            if (obj) {

                if (obj->wantRemoved) {
                    virNWFilterReportError(VIR_ERR_NO_NWFILTER,
                                           _("Filter '%s' is in use."),
                                           inc->filterref);
                    rc = 1;
                    virNWFilterObjUnlock(obj);
                    break;
                }

                /* create a temporary hashmap for depth-first tree traversal */
                virNWFilterHashTablePtr tmpvars =
                                      virNWFilterCreateVarsFrom(inc->params,
                                                                vars);
                if (!tmpvars) {
                    virReportOOMError();
                    rc = 1;
                    virNWFilterObjUnlock(obj);
                    break;
                }

                next_filter = obj->def;

                switch (useNewFilter) {
                case INSTANTIATE_FOLLOW_NEWFILTER:
                    if (obj->newDef) {
                        next_filter = obj->newDef;
                    }
                break;
                case INSTANTIATE_ALWAYS:
                break;
                }

                rc = virNWFilterDetermineMissingVarsRec(conn,
                                                        next_filter,
                                                        tmpvars,
                                                        missing_vars,
                                                        useNewFilter,
                                                        driver);

                virNWFilterHashTableFree(tmpvars);

                virNWFilterObjUnlock(obj);
                if (rc)
                    break;
            } else {
                virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
                                       _("referenced filter '%s' is missing"),
                                       inc->filterref);
                rc = 1;
                break;
            }
        }
    }
    return rc;
}
Example #12
0
/**
 * _virNWFilterInstantiateRec:
 * @conn: pointer to virConnect object
 * @techdriver: The driver to use for instantiation
 * @filter: The filter to instantiate
 * @ifname: The name of the interface to apply the rules to
 * @vars: A map holding variable names and values used for instantiating
 *  the filter and its subfilters.
 * @nEntries: number of virNWFilterInst objects collected
 * @insts: pointer to array for virNWFilterIns object pointers
 * @useNewFilter: instruct whether to use a newDef pointer rather than a
 *  def ptr which is useful during a filter update
 * @foundNewFilter: pointer to int indivating whether a newDef pointer was
 *  ever used; variable expected to be initialized to 0 by caller
 *
 * Returns 0 on success, a value otherwise.
 *
 * Recursively instantiate a filter by instantiating the given filter along
 * with all its subfilters in a depth-first traversal of the tree of
 * referenced filters. The name of the interface to which the rules belong
 * must be provided. Apply the values of variables as needed. Terminate with
 * error when a referenced filter is missing or a variable could not be
 * resolved -- among other reasons.
 */
static int
_virNWFilterInstantiateRec(virConnectPtr conn,
                           virNWFilterTechDriverPtr techdriver,
                           enum virDomainNetType nettype,
                           virNWFilterDefPtr filter,
                           const char *ifname,
                           virNWFilterHashTablePtr vars,
                           int *nEntries,
                           virNWFilterRuleInstPtr **insts,
                           enum instCase useNewFilter, bool *foundNewFilter,
                           virNWFilterDriverStatePtr driver)
{
    virNWFilterObjPtr obj;
    int rc = 0;
    int i;
    virNWFilterRuleInstPtr inst;
    virNWFilterDefPtr next_filter;

    for (i = 0; i < filter->nentries; i++) {
        virNWFilterRuleDefPtr    rule = filter->filterEntries[i]->rule;
        virNWFilterIncludeDefPtr inc  = filter->filterEntries[i]->include;
        if (rule) {
            inst = virNWFilterRuleInstantiate(conn,
                                              techdriver,
                                              nettype,
                                              filter,
                                              rule,
                                              ifname,
                                              vars);
            if (!inst) {
                rc = 1;
                break;
            }

            if (VIR_REALLOC_N(*insts, (*nEntries)+1) < 0) {
                virReportOOMError();
                rc = 1;
                break;
            }

            (*insts)[(*nEntries)++] = inst;

        } else if (inc) {
            VIR_DEBUG("Instantiating filter %s", inc->filterref);
            obj = virNWFilterObjFindByName(&driver->nwfilters, inc->filterref);
            if (obj) {

                if (obj->wantRemoved) {
                    virNWFilterReportError(VIR_ERR_NO_NWFILTER,
                                           _("Filter '%s' is in use."),
                                           inc->filterref);
                    rc = 1;
                    virNWFilterObjUnlock(obj);
                    break;
                }

                /* create a temporary hashmap for depth-first tree traversal */
                virNWFilterHashTablePtr tmpvars =
                                      virNWFilterCreateVarsFrom(inc->params,
                                                                vars);
                if (!tmpvars) {
                    virReportOOMError();
                    rc = 1;
                    virNWFilterObjUnlock(obj);
                    break;
                }

                next_filter = obj->def;

                switch (useNewFilter) {
                case INSTANTIATE_FOLLOW_NEWFILTER:
                    if (obj->newDef) {
                        next_filter = obj->newDef;
                        *foundNewFilter = true;
                    }
                break;
                case INSTANTIATE_ALWAYS:
                break;
                }

                rc = _virNWFilterInstantiateRec(conn,
                                                techdriver,
                                                nettype,
                                                next_filter,
                                                ifname,
                                                tmpvars,
                                                nEntries, insts,
                                                useNewFilter,
                                                foundNewFilter,
                                                driver);

                virNWFilterHashTableFree(tmpvars);

                virNWFilterObjUnlock(obj);
                if (rc)
                    break;
            } else {
                virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
                                       _("referenced filter '%s' is missing"),
                                       inc->filterref);
                rc = 1;
                break;
            }
        }
    }
    return rc;
}