/* Add an IP address to the list of IP addresses an interface is * known to use. This function feeds the per-interface cache that * is used to instantiate filters with variable '$IP'. * * @ifname: The name of the (tap) interface * @addr: An IPv4 address in dotted decimal format that the (tap) * interface is known to use. * * This function returns 0 on success, -1 otherwise */ int virNWFilterIPAddrMapAddIPAddr(const char *ifname, char *addr) { int ret = -1; virNWFilterVarValuePtr val; virMutexLock(&ipAddressMapLock); val = virHashLookup(ipAddressMap->hashTable, ifname); if (!val) { val = virNWFilterVarValueCreateSimple(addr); if (!val) { virReportOOMError(); goto cleanup; } ret = virNWFilterHashTablePut(ipAddressMap, ifname, val, 1); goto cleanup; } else { if (virNWFilterVarValueAddValue(val, addr) < 0) goto cleanup; } ret = 0; cleanup: virMutexUnlock(&ipAddressMapLock); return ret; }
static int testSetOneParameter(virNWFilterHashTablePtr vars, const char *name, const char *value) { int ret = -1; virNWFilterVarValuePtr val; if ((val = virHashLookup(vars->hashTable, name)) == NULL) { val = virNWFilterVarValueCreateSimpleCopyValue(value); if (!val) goto cleanup; if (virNWFilterHashTablePut(vars, name, val) < 0) { virNWFilterVarValueFree(val); goto cleanup; } } else { if (virNWFilterVarValueAddValueCopy(val, value) < 0) goto cleanup; } ret = 0; cleanup: return ret; }
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; }