summaryrefslogtreecommitdiff
path: root/sbin/pfctl
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/pfctl')
-rw-r--r--sbin/pfctl/parse.y35
-rw-r--r--sbin/pfctl/pfctl.c63
-rw-r--r--sbin/pfctl/pfctl_optimize.c6
-rw-r--r--sbin/pfctl/pfctl_parser.h11
4 files changed, 88 insertions, 27 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 454bd58e80f..3066bdb00fd 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.514 2006/10/31 07:02:35 mcbride Exp $ */
+/* $OpenBSD: parse.y,v 1.515 2006/10/31 14:17:44 mcbride Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -414,7 +414,7 @@ typedef struct {
%token BITMASK RANDOM SOURCEHASH ROUNDROBIN STATICPORT PROBABILITY
%token ALTQ CBQ PRIQ HFSC BANDWIDTH TBRSIZE LINKSHARE REALTIME UPPERLIMIT
%token QUEUE PRIORITY QLIMIT RTABLE
-%token LOAD
+%token LOAD RULESET_OPTIMIZATION
%token STICKYADDRESS MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE
%token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH
%token TAGGED TAG IFBOUND FLOATING STATEPOLICY ROUTE
@@ -423,7 +423,7 @@ typedef struct {
%type <v.interface> interface if_list if_item_not if_item
%type <v.number> number icmptype icmp6type uid gid
%type <v.number> tos not yesno
-%type <v.i> no dir af fragcache
+%type <v.i> no dir af fragcache optimizer
%type <v.i> sourcetrack flush unaryop statelock
%type <v.b> action nataction natpass scrubaction
%type <v.b> flags flag blockspec
@@ -496,6 +496,20 @@ fakeanchor : fakeanchor '\n'
| fakeanchor error '\n'
;
+optimizer : string {
+ if (!strcmp($1, "none"))
+ $$ = 0;
+ else if (!strcmp($1, "basic"))
+ $$ = PF_OPTIMIZE_BASIC;
+ else if (!strcmp($1, "profile"))
+ $$ = PF_OPTIMIZE_BASIC | PF_OPTIMIZE_PROFILE;
+ else {
+ yyerror("unknown ruleset-optimization %s", $$);
+ YYERROR;
+ }
+ }
+ ;
+
option : SET OPTIMIZATION STRING {
if (check_rulestate(PFCTL_STATE_OPTION)) {
free($3);
@@ -508,6 +522,12 @@ option : SET OPTIMIZATION STRING {
}
free($3);
}
+ | SET RULESET_OPTIMIZATION optimizer {
+ if (!(pf->opts & PF_OPT_OPTIMIZE)) {
+ pf->opts |= PF_OPT_OPTIMIZE;
+ pf->optimize = $3;
+ }
+ }
| SET TIMEOUT timeout_spec
| SET TIMEOUT '{' timeout_list '}'
| SET LIMIT limit_spec
@@ -4919,6 +4939,7 @@ lookup(char *s)
{ "route-to", ROUTETO},
{ "rtable", RTABLE},
{ "rule", RULE},
+ { "ruleset-optimization", RULESET_OPTIMIZATION},
{ "scrub", SCRUB},
{ "set", SET},
{ "skip", SKIP},
@@ -5452,21 +5473,21 @@ parseicmpspec(char *w, sa_family_t af)
}
int
-pfctl_load_anchors(int dev, int opts, struct pfr_buffer *trans)
+pfctl_load_anchors(int dev, struct pfctl *pf, struct pfr_buffer *trans)
{
struct loadanchors *la;
FILE *fin;
TAILQ_FOREACH(la, &loadanchorshead, entries) {
- if (opts & PF_OPT_VERBOSE)
+ if (pf->opts & PF_OPT_VERBOSE)
fprintf(stderr, "\nLoading anchor %s from %s\n",
la->anchorname, la->filename);
if ((fin = pfctl_fopen(la->filename, "r")) == NULL) {
warn("%s", la->filename);
continue;
}
- if (pfctl_rules(dev, la->filename, fin, opts, la->anchorname,
- trans) == -1)
+ if (pfctl_rules(dev, la->filename, fin, pf->opts, pf->optimize,
+ la->anchorname, trans) == -1)
return (-1);
}
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index 1d8020ef03b..5f434f3d988 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl.c,v 1.249 2006/10/31 07:02:35 mcbride Exp $ */
+/* $OpenBSD: pfctl.c,v 1.250 2006/10/31 14:17:45 mcbride Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -102,6 +102,7 @@ char *rulesopt;
const char *showopt;
const char *debugopt;
char *anchoropt;
+const char *optiopt = NULL;
char *pf_device = "/dev/pf";
char *ifaceopt;
char *tableopt;
@@ -215,6 +216,9 @@ static const char *debugopt_list[] = {
"none", "urgent", "misc", "loud", NULL
};
+static const char *optiopt_list[] = {
+ "o", "none", "basic", "profile", NULL
+};
void
usage(void)
@@ -1063,7 +1067,7 @@ pfctl_load_ruleset(struct pfctl *pf, char *path, struct pf_ruleset *rs,
}
}
- if ((pf->opts & PF_OPT_OPTIMIZE) && rs_num == PF_RULESET_FILTER)
+ if (pf->optimize && rs_num == PF_RULESET_FILTER)
pfctl_optimize_ruleset(pf, rs);
while ((r = TAILQ_FIRST(rs->rules[rs_num].active.ptr)) != NULL) {
@@ -1142,8 +1146,8 @@ pfctl_add_altq(struct pfctl *pf, struct pf_altq *a)
}
int
-pfctl_rules(int dev, char *filename, FILE *fin, int opts, char *anchorname,
- struct pfr_buffer *trans)
+pfctl_rules(int dev, char *filename, FILE *fin, int opts, int optimize,
+ char *anchorname, struct pfr_buffer *trans)
{
#define ERR(x) do { warn(x); goto _error; } while(0)
#define ERRX(x) do { warnx(x); goto _error; } while(0)
@@ -1181,6 +1185,7 @@ pfctl_rules(int dev, char *filename, FILE *fin, int opts, char *anchorname,
infile = filename;
pf.dev = dev;
pf.opts = opts;
+ pf.optimize = optimize;
pf.loadopt = loadopt;
pf.anchor = pf_find_or_create_ruleset(anchorname)->anchor;
rs = &pf.anchor->ruleset;
@@ -1241,7 +1246,7 @@ pfctl_rules(int dev, char *filename, FILE *fin, int opts, char *anchorname,
/* process "load anchor" directives */
if (!anchorname[0])
- if (pfctl_load_anchors(dev, opts, t) == -1)
+ if (pfctl_load_anchors(dev, &pf, t) == -1)
ERRX("load anchors");
if (trans == NULL && (opts & PF_OPT_NOACTION) == 0) {
@@ -1480,7 +1485,7 @@ pfctl_set_optimization(struct pfctl *pf, const char *opt)
hint = pf_hints[i].hint;
if (hint == NULL) {
- warnx("Bad hint name.");
+ warnx("invalid state timeouts optimization");
return (1);
}
@@ -1745,6 +1750,7 @@ main(int argc, char *argv[])
int ch;
int mode = O_RDONLY;
int opts = 0;
+ int optimize = 0;
char anchorname[MAXPATHLEN];
FILE *fin = NULL;
@@ -1752,7 +1758,7 @@ main(int argc, char *argv[])
usage();
while ((ch = getopt(argc, argv,
- "a:AdD:eqf:F:ghi:k:mnNOop:rRs:t:T:vx:z")) != -1) {
+ "a:AdD:eqf:F:ghi:k:mnNOo::p:rRs:t:T:vx:z")) != -1) {
switch (ch) {
case 'a':
anchoropt = optarg;
@@ -1819,10 +1825,25 @@ main(int argc, char *argv[])
loadopt |= PFCTL_FLAG_FILTER;
break;
case 'o':
- if (opts & PF_OPT_OPTIMIZE)
- opts |= PF_OPT_OPTIMIZE_PROFILE;
- else
- opts |= PF_OPT_OPTIMIZE;
+ if (optarg) {
+ optiopt = pfctl_lookup_option(optarg,
+ optiopt_list);
+ if (optiopt == NULL) {
+ warnx("Unknown optimization '%s'",
+ optarg);
+ usage();
+ }
+ }
+ if (opts & PF_OPT_OPTIMIZE) {
+ if (optiopt != NULL) {
+ warnx("Cannot specify -o multiple times"
+ "with optimizer level");
+ usage();
+ }
+ optimize |= PF_OPTIMIZE_PROFILE;
+ }
+ optimize |= PF_OPTIMIZE_BASIC;
+ opts |= PF_OPT_OPTIMIZE;
break;
case 'O':
loadopt |= PFCTL_FLAG_OPTION;
@@ -2040,7 +2061,22 @@ main(int argc, char *argv[])
tblcmdopt, rulesopt, anchorname, opts);
rulesopt = NULL;
}
- if (rulesopt != NULL) {
+ if (optiopt != NULL) {
+ switch (*optiopt) {
+ case 'n':
+ optimize = 0;
+ break;
+ case 'b':
+ optimize |= PF_OPTIMIZE_BASIC;
+ break;
+ case 'o':
+ case 'p':
+ optimize |= PF_OPTIMIZE_PROFILE;
+ break;
+ }
+ }
+
+ if (rulesopt != NULL) {
if (strcmp(rulesopt, "-") == 0) {
fin = stdin;
rulesopt = "stdin";
@@ -2063,7 +2099,8 @@ main(int argc, char *argv[])
if (anchorname[0] == '_' || strstr(anchorname, "/_") != NULL)
errx(1, "anchor names beginning with '_' cannot "
"be modified from the command line");
- if (pfctl_rules(dev, rulesopt, fin, opts, anchorname, NULL))
+ if (pfctl_rules(dev, rulesopt, fin, opts, optimize,
+ anchorname, NULL))
error = 1;
else if (!(opts & PF_OPT_NOACTION) &&
(loadopt & PFCTL_FLAG_TABLE))
diff --git a/sbin/pfctl/pfctl_optimize.c b/sbin/pfctl/pfctl_optimize.c
index e041073569d..37d9320ac22 100644
--- a/sbin/pfctl/pfctl_optimize.c
+++ b/sbin/pfctl/pfctl_optimize.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_optimize.c,v 1.12 2006/10/28 14:29:05 mcbride Exp $ */
+/* $OpenBSD: pfctl_optimize.c,v 1.13 2006/10/31 14:17:45 mcbride Exp $ */
/*
* Copyright (c) 2004 Mike Frantzen <frantzen@openbsd.org>
@@ -300,7 +300,7 @@ pfctl_optimize_ruleset(struct pfctl *pf, struct pf_ruleset *rs)
if (construct_superblocks(pf, &opt_queue, &superblocks))
goto error;
- if (pf->opts & PF_OPT_OPTIMIZE_PROFILE) {
+ if (pf->optimize & PF_OPTIMIZE_PROFILE) {
if (load_feedback_profile(pf, &superblocks))
goto error;
}
@@ -413,7 +413,7 @@ optimize_superblock(struct pfctl *pf, struct superblock *block)
return (1);
if (combine_rules(pf, block))
return (1);
- if ((pf->opts & PF_OPT_OPTIMIZE_PROFILE) &&
+ if ((pf->optimize & PF_OPTIMIZE_PROFILE) &&
TAILQ_FIRST(&block->sb_rules)->por_rule.quick &&
block->sb_profiled_block) {
if (block_feedback(pf, block))
diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h
index a43ad9e3629..f6f45bc0fa5 100644
--- a/sbin/pfctl/pfctl_parser.h
+++ b/sbin/pfctl/pfctl_parser.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_parser.h,v 1.84 2006/10/28 14:29:05 mcbride Exp $ */
+/* $OpenBSD: pfctl_parser.h,v 1.85 2006/10/31 14:17:45 mcbride Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -47,7 +47,6 @@
#define PF_OPT_DEBUG 0x0200
#define PF_OPT_SHOWALL 0x0400
#define PF_OPT_OPTIMIZE 0x0800
-#define PF_OPT_OPTIMIZE_PROFILE 0x1000
#define PF_OPT_MERGE 0x2000
#define PF_TH_ALL 0xFF
@@ -55,6 +54,9 @@
#define PF_NAT_PROXY_PORT_LOW 50001
#define PF_NAT_PROXY_PORT_HIGH 65535
+#define PF_OPTIMIZE_BASIC 0x0001
+#define PF_OPTIMIZE_PROFILE 0x0002
+
#define FCNT_NAMES { \
"searches", \
"inserts", \
@@ -68,6 +70,7 @@ struct pfr_buffer; /* forward definition */
struct pfctl {
int dev;
int opts;
+ int optimize;
int loadopt;
int asd; /* anchor stack depth */
int bn; /* brace number */
@@ -183,7 +186,7 @@ struct pf_opt_rule {
TAILQ_HEAD(pf_opt_queue, pf_opt_rule);
-int pfctl_rules(int, char *, FILE *, int, char *, struct pfr_buffer *);
+int pfctl_rules(int, char *, FILE *, int, int, char *, struct pfr_buffer *);
int pfctl_optimize_ruleset(struct pfctl *, struct pf_ruleset *);
int pfctl_add_rule(struct pfctl *, struct pf_rule *, const char *);
@@ -202,7 +205,7 @@ int pfctl_set_interface_flags(struct pfctl *, char *, int, int);
int parse_rules(FILE *, struct pfctl *);
int parse_flags(char *);
-int pfctl_load_anchors(int, int, struct pfr_buffer *);
+int pfctl_load_anchors(int, struct pfctl *, struct pfr_buffer *);
void print_pool(struct pf_pool *, u_int16_t, u_int16_t, sa_family_t, int);
void print_src_node(struct pf_src_node *, int);