noit_boolean noit_apply_filterset(const char *filterset, noit_check_t *check, metric_t *metric) { /* We pass in filterset here just in case someone wants to apply * a filterset other than check->filterset.. You never know. */ void *vfs; if(!filterset) return noit_true; /* No filter */ if(!filtersets) return noit_false; /* Couldn't possibly match */ LOCKFS(); if(noit_hash_retrieve(filtersets, filterset, strlen(filterset), &vfs)) { filterset_t *fs = (filterset_t *)vfs; filterrule_t *r; noit_atomic_inc32(&fs->ref_cnt); UNLOCKFS(); #define MATCHES(rname, value) noit_apply_filterrule(r->rname, r->rname##_e, value) for(r = fs->rules; r; r = r->next) { if(MATCHES(target, check->target) && MATCHES(module, check->module) && MATCHES(name, check->name) && MATCHES(metric, metric->metric_name)) return (r->type == NOIT_FILTER_ACCEPT) ? noit_true : noit_false; } filterset_free(fs); return noit_false; } UNLOCKFS(); return noit_false; }
void free_networks(struct network_head *networks) { struct network *n; while ((n = TAILQ_FIRST(networks)) != NULL) { TAILQ_REMOVE(networks, n, entry); filterset_free(&n->net.attrset); free(n); } }
void free_rdomains(struct rdomain_head *rdomains) { struct rdomain *rd; while ((rd = SIMPLEQ_FIRST(rdomains)) != NULL) { SIMPLEQ_REMOVE_HEAD(rdomains, entry); filterset_free(&rd->export); filterset_free(&rd->import); free_networks(&rd->net_l); free(rd); } }
mtev_boolean noit_apply_filterset(const char *filterset, noit_check_t *check, metric_t *metric) { /* We pass in filterset here just in case someone wants to apply * a filterset other than check->filterset.. You never know. */ void *vfs; if(!filterset) return mtev_true; /* No filter */ if(!filtersets) return mtev_false; /* Couldn't possibly match */ LOCKFS(); if(mtev_hash_retrieve(filtersets, filterset, strlen(filterset), &vfs)) { filterset_t *fs = (filterset_t *)vfs; filterrule_t *r, *skipto_rule = NULL; int idx = 0; mtev_atomic_inc32(&fs->ref_cnt); UNLOCKFS(); #define MATCHES(rname, value) noit_apply_filterrule(r->rname##_ht, r->rname ? r->rname : r->rname##_override, r->rname ? r->rname##_e : NULL, value) for(r = fs->rules; r; r = r->next) { int need_target, need_module, need_name, need_metric; /* If we're targeting a skipto rule, match or continue */ idx++; if(skipto_rule && skipto_rule != r) continue; skipto_rule = NULL; need_target = !MATCHES(target, check->target); need_module = !MATCHES(module, check->module); need_name = !MATCHES(name, check->name); need_metric = !MATCHES(metric, metric->metric_name); if(!need_target && !need_module && !need_name && !need_metric) { if(r->type == NOIT_FILTER_SKIPTO) { skipto_rule = r->skipto_rule; continue; } return (r->type == NOIT_FILTER_ACCEPT) ? mtev_true : mtev_false; } /* If we need some of these and we have an auto setting that isn't fulfilled for each of them, we can add and succeed */ #define CHECK_ADD(rname) (!need_##rname || (r->rname##_auto_hash_max > 0 && r->rname##_ht && mtev_hash_size(r->rname##_ht) < r->rname##_auto_hash_max)) if(CHECK_ADD(target) && CHECK_ADD(module) && CHECK_ADD(name) && CHECK_ADD(metric)) { #define UPDATE_FILTER_RULE(rnum, rname, value) do { \ mtev_hash_replace(r->rname##_ht, strdup(value), strlen(value), NULL, free, NULL); \ if(noit_filter_update_conf_rule(fs->name, rnum, #rname, value) < 0) { \ mtevL(noit_error, "Error updating configuration for new filter auto_add on %s=%s\n", #rname, value); \ } \ } while(0) if(need_target) UPDATE_FILTER_RULE(idx, target, check->target); if(need_module) UPDATE_FILTER_RULE(idx, module, check->module); if(need_name) UPDATE_FILTER_RULE(idx, name, check->name); if(need_metric) UPDATE_FILTER_RULE(idx, metric, metric->metric_name); noit_filterset_log_auto_add(fs->name, check, metric, r->type == NOIT_FILTER_ACCEPT); if(r->type == NOIT_FILTER_SKIPTO) { skipto_rule = r->skipto_rule; continue; } return (r->type == NOIT_FILTER_ACCEPT) ? mtev_true : mtev_false; } } filterset_free(fs); return mtev_false; } UNLOCKFS(); return mtev_false; }