summaryrefslogtreecommitdiff
path: root/sbin/pfctl/pfctl_optimize.c
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/pfctl/pfctl_optimize.c')
-rw-r--r--sbin/pfctl/pfctl_optimize.c88
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