diff options
Diffstat (limited to 'sbin/pfctl/pfctl_optimize.c')
-rw-r--r-- | sbin/pfctl/pfctl_optimize.c | 88 |
1 files changed, 56 insertions, 32 deletions
diff --git a/sbin/pfctl/pfctl_optimize.c b/sbin/pfctl/pfctl_optimize.c index a63494d553f..e041073569d 100644 --- a/sbin/pfctl/pfctl_optimize.c +++ b/sbin/pfctl/pfctl_optimize.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_optimize.c,v 1.11 2006/10/25 14:50:21 henning Exp $ */ +/* $OpenBSD: pfctl_optimize.c,v 1.12 2006/10/28 14:29:05 mcbride Exp $ */ /* * Copyright (c) 2004 Mike Frantzen <frantzen@openbsd.org> @@ -112,6 +112,7 @@ struct pf_rule_field { PF_RULE_FIELD(max_src_states, BARRIER), PF_RULE_FIELD(max_src_conn, BARRIER), PF_RULE_FIELD(max_src_conn_rate, BARRIER), + PF_RULE_FIELD(anchor, BARRIER), /* for now */ /* * These fields must be the same between all rules in the same superblock. @@ -181,7 +182,6 @@ struct pf_rule_field { PF_RULE_FIELD(packets, DC), PF_RULE_FIELD(bytes, DC), PF_RULE_FIELD(kif, DC), - PF_RULE_FIELD(anchor, DC), PF_RULE_FIELD(states, DC), PF_RULE_FIELD(src_nodes, DC), PF_RULE_FIELD(nr, DC), @@ -255,22 +255,49 @@ int table_identifier; int -pfctl_optimize_rules(struct pfctl *pf) +pfctl_optimize_ruleset(struct pfctl *pf, struct pf_ruleset *rs) { struct superblocks superblocks; + struct pf_opt_queue opt_queue; struct superblock *block; struct pf_opt_rule *por; - int nr; + struct pf_rule *r; + struct pf_rulequeue *old_rules; DEBUG("optimizing ruleset"); memset(&table_buffer, 0, sizeof(table_buffer)); skip_init(); + TAILQ_INIT(&opt_queue); - if (TAILQ_FIRST(&pf->opt_queue)) - nr = TAILQ_FIRST(&pf->opt_queue)->por_rule.nr; + old_rules = rs->rules[PF_RULESET_FILTER].active.ptr; + rs->rules[PF_RULESET_FILTER].active.ptr = + rs->rules[PF_RULESET_FILTER].inactive.ptr; + rs->rules[PF_RULESET_FILTER].inactive.ptr = old_rules; + + /* + * XXX expanding the pf_opt_rule format throughout pfctl might allow + * us to avoid all this copying. + */ + while ((r = TAILQ_FIRST(rs->rules[PF_RULESET_FILTER].inactive.ptr)) + != NULL) { + TAILQ_REMOVE(rs->rules[PF_RULESET_FILTER].inactive.ptr, r, + entries); + if ((por = calloc(1, sizeof(*por))) == NULL) + err(1, "calloc"); + memcpy(&por->por_rule, r, sizeof(*r)); + if (TAILQ_FIRST(&r->rpool.list) != NULL) { + TAILQ_INIT(&por->por_rule.rpool.list); + pfctl_move_pool(&r->rpool, &por->por_rule.rpool); + } else + bzero(&por->por_rule.rpool, + sizeof(por->por_rule.rpool)); + + + TAILQ_INSERT_TAIL(&opt_queue, por, por_entry); + } TAILQ_INIT(&superblocks); - if (construct_superblocks(pf, &pf->opt_queue, &superblocks)) + if (construct_superblocks(pf, &opt_queue, &superblocks)) goto error; if (pf->opts & PF_OPT_OPTIMIZE_PROFILE) { @@ -283,24 +310,21 @@ pfctl_optimize_rules(struct pfctl *pf) goto error; } - - /* - * Optimizations are done so we turn off the optimization flag and - * put the rules right back into the regular codepath. - */ - pf->opts &= ~PF_OPT_OPTIMIZE; - + rs->anchor->refcnt = 0; while ((block = TAILQ_FIRST(&superblocks))) { TAILQ_REMOVE(&superblocks, block, sb_entry); while ((por = TAILQ_FIRST(&block->sb_rules))) { TAILQ_REMOVE(&block->sb_rules, por, por_entry); - por->por_rule.nr = nr++; - if (pfctl_add_rule(pf, &por->por_rule, - por->por_anchor)) { - free(por); - goto error; - } + por->por_rule.nr = rs->anchor->refcnt++; + if ((r = calloc(1, sizeof(*r))) == NULL) + err(1, "calloc"); + memcpy(r, &por->por_rule, sizeof(*r)); + TAILQ_INIT(&r->rpool.list); + pfctl_move_pool(&por->por_rule.rpool, &r->rpool); + TAILQ_INSERT_TAIL( + rs->rules[PF_RULESET_FILTER].active.ptr, + r, entries); free(por); } free(block); @@ -309,8 +333,8 @@ pfctl_optimize_rules(struct pfctl *pf) return (0); error: - while ((por = TAILQ_FIRST(&pf->opt_queue))) { - TAILQ_REMOVE(&pf->opt_queue, por, por_entry); + while ((por = TAILQ_FIRST(&opt_queue))) { + TAILQ_REMOVE(&opt_queue, por, por_entry); if (por->por_src_tbl) { pfr_buf_clear(por->por_src_tbl->pt_buf); free(por->por_src_tbl->pt_buf); @@ -379,7 +403,8 @@ optimize_superblock(struct pfctl *pf, struct superblock *block) printf("--- Superblock ---\n"); TAILQ_FOREACH(por, &block->sb_rules, por_entry) { printf(" "); - print_rule(&por->por_rule, por->por_anchor, 1); + print_rule(&por->por_rule, por->por_rule.anchor ? + por->por_rule.anchor->name : "", 1); } #endif /* OPT_DEBUG */ @@ -868,6 +893,7 @@ load_feedback_profile(struct pfctl *pf, struct superblocks *superblocks) DEBUG("Loading %d active rules for a feedback profile", mnr); for (nr = 0; nr < mnr; ++nr) { + struct pf_ruleset *rs; if ((por = calloc(1, sizeof(*por))) == NULL) { warn("calloc"); return (1); @@ -878,8 +904,8 @@ load_feedback_profile(struct pfctl *pf, struct superblocks *superblocks) return (1); } memcpy(&por->por_rule, &pr.rule, sizeof(por->por_rule)); - strlcpy(por->por_anchor, pr.anchor_call, - sizeof(por->por_anchor)); + rs = pf_find_or_create_ruleset(pr.anchor_call); + por->por_rule.anchor = rs->anchor; if (TAILQ_EMPTY(&por->por_rule.rpool.list)) memset(&por->por_rule.rpool, 0, sizeof(por->por_rule.rpool)); @@ -1286,8 +1312,8 @@ again: tablenum++; - if (pfctl_define_table(tbl->pt_name, PFR_TFLAG_CONST, 1, pf->anchor, - tbl->pt_buf, pf->tticket)) { + if (pfctl_define_table(tbl->pt_name, PFR_TFLAG_CONST, 1, + pf->anchor->name, tbl->pt_buf, pf->anchor->ruleset.tticket)) { warn("failed to create table %s", tbl->pt_name); return (1); } @@ -1386,9 +1412,8 @@ superblock_inclusive(struct superblock *block, struct pf_opt_rule *por) } } - /* 'anchor' heads and per-rule src-track are also hard breaks */ - if (por->por_anchor[0] != '\0' || - (por->por_rule.rule_flag & PFRULE_RULESRCTRACK)) + /* per-rule src-track is also a hard break */ + if (por->por_rule.rule_flag & PFRULE_RULESRCTRACK) return (0); /* @@ -1414,8 +1439,7 @@ superblock_inclusive(struct superblock *block, struct pf_opt_rule *por) comparable_rule(&a, &TAILQ_FIRST(&block->sb_rules)->por_rule, NOMERGE); comparable_rule(&b, &por->por_rule, NOMERGE); - if (strcmp(TAILQ_FIRST(&block->sb_rules)->por_anchor, - por->por_anchor) == 0 && memcmp(&a, &b, sizeof(a)) == 0) + if (memcmp(&a, &b, sizeof(a)) == 0) return (1); #ifdef OPT_DEBUG |