summaryrefslogtreecommitdiff
path: root/sbin/pfctl
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2009-04-06 12:05:56 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2009-04-06 12:05:56 +0000
commit63f618ffc13737b6d73b157c8b7921c7b0e4be29 (patch)
tree0a1338ce99c5274fd3ecdcef7b8e017b3df9e461 /sbin/pfctl
parent4b3aad969b68381a5f8dc7beb977b479929205ec (diff)
1) scrub rules are completely gone.
2) packet reassembly: only one method remains, full reassembly. crop and drop-ovl are gone. . set reassemble yes|no [no-df] if no-df is given fragments (and only fragments!) with the df bit set have it cleared before entering the fragment cache, and thus the reassembled packet doesn't have df set either. it does NOT touch non-fragmented packets. 3) regular rules can have scrub options. . pass scrub(no-df, min-ttl 64, max-mss 1400, set-tos lowdelay) . match scrub(reassemble tcp, random-id) of course all options are optional. the individual options still do what they used to do on scrub rules, but everything is stateful now. 4) match rules "match" is a new action, just like pass and block are, and can be used like they do. opposed to pass or block, they do NOT change the pass/block state of a packet. i. e. . pass . match passes the packet, and . block . match blocks it. Every time (!) a match rule matches, i. e. not only when it is the last matching rule, the following actions are set: -queue assignment. can be overwritten later, the last rule that set a queue wins. note how this is different from the last matching rule wins, if the last matching rule has no queue assignments and the second last matching rule was a match rule with queue assignments, these assignments are taken. -rtable assignments. works the same as queue assignments. -set-tos, min-ttl, max-mss, no-df, random-id, reassemble tcp, all work like the above -logging. every matching rule causes the packet to be logged. this means a single packet can get logged more than once (think multiple log interfaces with different receivers, like pflogd and spamlogd) . almost entirely hacked at n2k9 in basel, could not be committed close to release. this really should have been multiple diffs, but splitting them now is not feasible any more. input from mcbride and dlg, and frantzen about the fragment handling. speedup around 7% for the common case, the more the more scrub rules were in use. manpage not up to date, being worked on.
Diffstat (limited to 'sbin/pfctl')
-rw-r--r--sbin/pfctl/parse.y205
-rw-r--r--sbin/pfctl/pfctl.c83
-rw-r--r--sbin/pfctl/pfctl_parser.c52
-rw-r--r--sbin/pfctl/pfctl_parser.h5
4 files changed, 151 insertions, 194 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 9c627390fce..3c3b9a67c85 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.555 2009/02/19 17:08:42 deraadt Exp $ */
+/* $OpenBSD: parse.y,v 1.556 2009/04/06 12:05:55 henning Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -108,7 +108,6 @@ int atoul(char *, u_long *);
enum {
PFCTL_STATE_NONE,
PFCTL_STATE_OPTION,
- PFCTL_STATE_SCRUB,
PFCTL_STATE_QUEUE,
PFCTL_STATE_NAT,
PFCTL_STATE_FILTER
@@ -205,11 +204,15 @@ struct node_qassign {
struct filter_opts {
int marker;
-#define FOM_FLAGS 0x01
-#define FOM_ICMP 0x02
-#define FOM_TOS 0x04
-#define FOM_KEEP 0x08
-#define FOM_SRCTRACK 0x10
+#define FOM_FLAGS 0x0001
+#define FOM_ICMP 0x0002
+#define FOM_TOS 0x0004
+#define FOM_KEEP 0x0008
+#define FOM_SRCTRACK 0x0010
+#define FOM_MINTTL 0x0020
+#define FOM_MAXMSS 0x0040
+#define FOM_SETTOS 0x0100
+#define FOM_SCRUB_TCP 0x0200
struct node_uid *uid;
struct node_gid *gid;
struct {
@@ -237,6 +240,13 @@ struct filter_opts {
struct node_host *addr;
u_int16_t port;
} divert;
+
+ /* scrub opts */
+ int nodf;
+ int minttl;
+ int settos;
+ int randomid;
+ int max_mss;
} filter_opts;
struct antispoof_opts {
@@ -246,20 +256,12 @@ struct antispoof_opts {
struct scrub_opts {
int marker;
-#define SOM_MINTTL 0x01
-#define SOM_MAXMSS 0x02
-#define SOM_FRAGCACHE 0x04
-#define SOM_SETTOS 0x08
int nodf;
int minttl;
int maxmss;
int settos;
- int fragcache;
int randomid;
int reassemble_tcp;
- char *match_tag;
- u_int8_t match_tag_not;
- u_int rtableid;
} scrub_opts;
struct queue_opts {
@@ -430,7 +432,7 @@ int parseport(char *, struct range *r, int);
%}
-%token PASS BLOCK SCRUB RETURN IN OS OUT LOG QUICK ON FROM TO FLAGS
+%token PASS BLOCK MATCH SCRUB RETURN IN OS OUT LOG QUICK ON FROM TO FLAGS
%token RETURNRST RETURNICMP RETURNICMP6 PROTO INET INET6 ALL ANY ICMPTYPE
%token ICMP6TYPE CODE KEEP MODULATE STATE PORT RDR NAT BINAT ARROW NODF
%token MINTTL ERROR ALLOWOPTS FASTROUTE FILENAME ROUTETO DUPTO REPLYTO NO LABEL
@@ -452,11 +454,11 @@ int parseport(char *, struct range *r, int);
%token <v.i> PORTBINARY
%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.number> tos not yesno optnodf
%type <v.probability> probability
-%type <v.i> no dir af fragcache optimizer
+%type <v.i> no dir af optimizer
%type <v.i> sourcetrack flush unaryop statelock
-%type <v.b> action nataction natpasslog scrubaction
+%type <v.b> action nataction natpasslog
%type <v.b> flags flag blockspec
%type <v.range> portplain portstar portrange
%type <v.hashkey> hashkey
@@ -504,7 +506,6 @@ ruleset : /* empty */
| ruleset include '\n'
| ruleset '\n'
| ruleset option '\n'
- | ruleset scrubrule '\n'
| ruleset natrule '\n'
| ruleset binatrule '\n'
| ruleset pfrule '\n'
@@ -560,7 +561,16 @@ optimizer : string {
}
;
-option : SET OPTIMIZATION STRING {
+optnodf : /* empty */ { $$ = 0; }
+ | NODF { $$ = 1; }
+ ;
+
+option : SET REASSEMBLE yesno optnodf {
+ if (check_rulestate(PFCTL_STATE_OPTION))
+ YYERROR;
+ pfctl_set_reassembly(pf, $3, $4);
+ }
+ | SET OPTIMIZATION STRING {
if (check_rulestate(PFCTL_STATE_OPTION)) {
free($3);
YYERROR;
@@ -1018,87 +1028,18 @@ loadrule : LOAD ANCHOR string FROM string {
free($5);
};
-scrubaction : no SCRUB {
- $$.b2 = $$.w = 0;
- if ($1)
- $$.b1 = PF_NOSCRUB;
- else
- $$.b1 = PF_SCRUB;
- }
- ;
-
-scrubrule : scrubaction dir logquick interface af proto fromto scrub_opts
- {
- struct pf_rule r;
-
- if (check_rulestate(PFCTL_STATE_SCRUB))
- YYERROR;
-
- memset(&r, 0, sizeof(r));
-
- r.action = $1.b1;
- r.direction = $2;
-
- r.log = $3.log;
- r.logif = $3.logif;
- if ($3.quick) {
- yyerror("scrub rules do not support 'quick'");
- YYERROR;
- }
-
- r.af = $5;
- if ($8.nodf)
- r.rule_flag |= PFRULE_NODF;
- if ($8.randomid)
- r.rule_flag |= PFRULE_RANDOMID;
- if ($8.reassemble_tcp) {
- if (r.direction != PF_INOUT) {
- yyerror("reassemble tcp rules can not "
- "specify direction");
- YYERROR;
- }
- r.rule_flag |= PFRULE_REASSEMBLE_TCP;
- }
- if ($8.minttl)
- r.min_ttl = $8.minttl;
- if ($8.maxmss)
- r.max_mss = $8.maxmss;
- if ($8.marker & SOM_SETTOS) {
- r.rule_flag |= PFRULE_SET_TOS;
- r.set_tos = $8.settos;
- }
- if ($8.fragcache)
- r.rule_flag |= $8.fragcache;
- if ($8.match_tag)
- if (strlcpy(r.match_tagname, $8.match_tag,
- PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
- yyerror("tag too long, max %u chars",
- PF_TAG_NAME_SIZE - 1);
- YYERROR;
- }
- r.match_tag_not = $8.match_tag_not;
- r.rtableid = $8.rtableid;
-
- expand_rule(&r, $4, NULL, $6, $7.src_os,
- $7.src.host, $7.src.port, $7.dst.host, $7.dst.port,
- NULL, NULL, NULL, "");
- }
- ;
-
scrub_opts : {
bzero(&scrub_opts, sizeof scrub_opts);
- scrub_opts.rtableid = -1;
}
scrub_opts_l
{ $$ = scrub_opts; }
| /* empty */ {
bzero(&scrub_opts, sizeof scrub_opts);
- scrub_opts.rtableid = -1;
$$ = scrub_opts;
}
;
-scrub_opts_l : scrub_opts_l scrub_opt
+scrub_opts_l : scrub_opts_l comma scrub_opt
| scrub_opt
;
@@ -1110,7 +1051,7 @@ scrub_opt : NODF {
scrub_opts.nodf = 1;
}
| MINTTL NUMBER {
- if (scrub_opts.marker & SOM_MINTTL) {
+ if (scrub_opts.marker & FOM_MINTTL) {
yyerror("min-ttl cannot be respecified");
YYERROR;
}
@@ -1118,11 +1059,11 @@ scrub_opt : NODF {
yyerror("illegal min-ttl value %d", $2);
YYERROR;
}
- scrub_opts.marker |= SOM_MINTTL;
+ scrub_opts.marker |= FOM_MINTTL;
scrub_opts.minttl = $2;
}
| MAXMSS NUMBER {
- if (scrub_opts.marker & SOM_MAXMSS) {
+ if (scrub_opts.marker & FOM_MAXMSS) {
yyerror("max-mss cannot be respecified");
YYERROR;
}
@@ -1130,25 +1071,17 @@ scrub_opt : NODF {
yyerror("illegal max-mss value %d", $2);
YYERROR;
}
- scrub_opts.marker |= SOM_MAXMSS;
+ scrub_opts.marker |= FOM_MAXMSS;
scrub_opts.maxmss = $2;
}
| SETTOS tos {
- if (scrub_opts.marker & SOM_SETTOS) {
+ if (scrub_opts.marker & FOM_SETTOS) {
yyerror("set-tos cannot be respecified");
YYERROR;
}
- scrub_opts.marker |= SOM_SETTOS;
+ scrub_opts.marker |= FOM_SETTOS;
scrub_opts.settos = $2;
}
- | fragcache {
- if (scrub_opts.marker & SOM_FRAGCACHE) {
- yyerror("fragcache cannot be respecified");
- YYERROR;
- }
- scrub_opts.marker |= SOM_FRAGCACHE;
- scrub_opts.fragcache = $1;
- }
| REASSEMBLE STRING {
if (strcasecmp($2, "tcp") != 0) {
yyerror("scrub reassemble supports only tcp, "
@@ -1170,22 +1103,6 @@ scrub_opt : NODF {
}
scrub_opts.randomid = 1;
}
- | RTABLE NUMBER {
- if ($2 < 0 || $2 > RT_TABLEID_MAX) {
- yyerror("invalid rtable id");
- YYERROR;
- }
- scrub_opts.rtableid = $2;
- }
- | not TAGGED string {
- scrub_opts.match_tag = $3;
- scrub_opts.match_tag_not = $1;
- }
- ;
-
-fragcache : FRAGMENT REASSEMBLE { $$ = 0; /* default */ }
- | FRAGMENT FRAGCROP { $$ = PFRULE_FRAGCROP; }
- | FRAGMENT FRAGDROP { $$ = PFRULE_FRAGDROP; }
;
antispoof : ANTISPOOF logquick antispoof_ifspc af antispoof_opts {
@@ -1872,6 +1789,21 @@ pfrule : action dir logquick interface route af proto fromto
r.prob = $9.prob;
r.rtableid = $9.rtableid;
+ if ($9.nodf)
+ r.scrub_flags |= PFSTATE_NODF;
+ if ($9.randomid)
+ r.scrub_flags |= PFSTATE_RANDOMID;
+ if ($9.minttl)
+ r.min_ttl = $9.minttl;
+ if ($9.max_mss)
+ r.max_mss = $9.max_mss;
+ if ($9.marker & FOM_SETTOS) {
+ r.scrub_flags |= PFSTATE_SETTOS;
+ r.set_tos = $9.settos;
+ }
+ if ($9.marker & FOM_SCRUB_TCP)
+ r.scrub_flags |= PFSTATE_SCRUB_TCP;
+
r.af = $6;
if ($9.tag)
if (strlcpy(r.tagname, $9.tag,
@@ -2377,6 +2309,16 @@ filter_opt : USER uids {
| DIVERTREPLY {
filter_opts.divert.port = 1; /* some random value */
}
+ | SCRUB '(' scrub_opts ')' {
+ filter_opts.nodf = $3.nodf;
+ filter_opts.minttl = $3.minttl;
+ filter_opts.settos = $3.settos;
+ filter_opts.randomid = $3.randomid;
+ filter_opts.max_mss = $3.maxmss;
+ if ($3.reassemble_tcp)
+ filter_opts.marker |= FOM_SCRUB_TCP;
+ filter_opts.marker |= $3.marker;
+ }
;
probability : STRING {
@@ -2402,6 +2344,7 @@ probability : STRING {
action : PASS { $$.b1 = PF_PASS; $$.b2 = $$.w = 0; }
+ | MATCH { $$.b1 = PF_MATCH; $$.b2 = $$.w = 0; }
| BLOCK blockspec { $$ = $2; $$.b1 = PF_DROP; }
;
@@ -4364,9 +4307,8 @@ rule_consistent(struct pf_rule *r, int anchor_call)
switch (r->action) {
case PF_PASS:
+ case PF_MATCH:
case PF_DROP:
- case PF_SCRUB:
- case PF_NOSCRUB:
problems = filter_consistent(r, anchor_call);
break;
case PF_NAT:
@@ -4434,8 +4376,8 @@ filter_consistent(struct pf_rule *r, int anchor_call)
yyerror("max-src-nodes requires 'source-track rule'");
problems++;
}
- if (r->action == PF_DROP && r->keep_state) {
- yyerror("keep state on block rules doesn't make sense");
+ if (r->action != PF_PASS && r->keep_state) {
+ yyerror("keep state is great, but only for pass rules");
problems++;
}
if (r->rule_flag & PFRULE_STATESLOPPY &&
@@ -4445,6 +4387,18 @@ filter_consistent(struct pf_rule *r, int anchor_call)
"synproxy state or modulate state");
problems++;
}
+ /* match rules rules */
+ if (r->action == PF_MATCH) {
+ if (r->divert.port) {
+ yyerror("divert is not supported on match rules");
+ problems++;
+ }
+ if (r->rt) {
+ yyerror("route-to, reply-to, dup-to and fastroute "
+ "must not be used on match rules");
+ problems++;
+ }
+ }
return (-problems);
}
@@ -5267,6 +5221,7 @@ lookup(char *s)
{ "load", LOAD},
{ "log", LOG},
{ "loginterface", LOGINTERFACE},
+ { "match", MATCH},
{ "max", MAXIMUM},
{ "max-mss", MAXMSS},
{ "max-src-conn", MAXSRCCONN},
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index 12f59517c7f..ff03a04d02d 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl.c,v 1.280 2009/02/23 06:58:30 deraadt Exp $ */
+/* $OpenBSD: pfctl.c,v 1.281 2009/04/06 12:05:55 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -78,6 +78,7 @@ int pfctl_load_timeout(struct pfctl *, unsigned int, unsigned int);
int pfctl_load_debug(struct pfctl *, unsigned int);
int pfctl_load_logif(struct pfctl *, char *);
int pfctl_load_hostid(struct pfctl *, unsigned int);
+int pfctl_load_reassembly(struct pfctl *, u_int32_t);
int pfctl_get_pool(int, struct pf_pool *, u_int32_t, u_int32_t, int,
char *);
void pfctl_print_rule_counters(struct pf_rule *, int);
@@ -310,8 +311,7 @@ pfctl_clear_rules(int dev, int opts, char *anchorname)
memset(&t, 0, sizeof(t));
t.pfrb_type = PFRB_TRANS;
- if (pfctl_add_trans(&t, PF_RULESET_SCRUB, anchorname) ||
- pfctl_add_trans(&t, PF_RULESET_FILTER, anchorname) ||
+ if (pfctl_add_trans(&t, PF_RULESET_FILTER, anchorname) ||
pfctl_trans(dev, &t, DIOCXBEGIN, 0) ||
pfctl_trans(dev, &t, DIOCXCOMMIT, 0))
err(1, "pfctl_clear_rules");
@@ -835,47 +835,15 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
}
header++;
}
- pr.rule.action = PF_SCRUB;
- if (ioctl(dev, DIOCGETRULES, &pr)) {
- warn("DIOCGETRULES");
- goto error;
- }
if (opts & PF_OPT_SHOWALL) {
if (format == PFCTL_SHOW_RULES && (pr.nr > 0 || header))
pfctl_print_title("FILTER RULES:");
else if (format == PFCTL_SHOW_LABELS && labels)
pfctl_print_title("LABEL COUNTERS:");
}
- mnr = pr.nr;
if (opts & PF_OPT_CLRRULECTRS)
pr.action = PF_GET_CLR_CNTR;
- for (nr = 0; nr < mnr; ++nr) {
- pr.nr = nr;
- if (ioctl(dev, DIOCGETRULE, &pr)) {
- warn("DIOCGETRULE");
- goto error;
- }
-
- if (pfctl_get_pool(dev, &pr.rule.rpool,
- nr, pr.ticket, PF_SCRUB, path) != 0)
- goto error;
-
- switch (format) {
- case PFCTL_SHOW_LABELS:
- break;
- case PFCTL_SHOW_RULES:
- if (pr.rule.label[0] && (opts & PF_OPT_SHOWALL))
- labels = 1;
- print_rule(&pr.rule, pr.anchor_call, rule_numbers);
- printf("\n");
- pfctl_print_rule_counters(&pr.rule, opts);
- break;
- case PFCTL_SHOW_NOTHING:
- break;
- }
- pfctl_clear_pool(&pr.rule.rpool);
- }
pr.rule.action = PF_PASS;
if (ioctl(dev, DIOCGETRULES, &pr)) {
warn("DIOCGETRULES");
@@ -1180,7 +1148,8 @@ pfctl_add_rule(struct pfctl *pf, struct pf_rule *r, const char *anchor_call)
struct pf_ruleset *rs;
char *p;
- rs_num = pf_get_ruleset_number(r->action);
+ rs_num = pf_get_ruleset_number(r->action == PF_MATCH ? PF_PASS :
+ r->action);
if (rs_num == PF_RULESET_MAX)
errx(1, "Invalid rule type %d", r->action);
@@ -1236,8 +1205,7 @@ pfctl_ruleset_trans(struct pfctl *pf, char *path, struct pf_anchor *a)
return (2);
}
if ((pf->loadopt & PFCTL_FLAG_FILTER) != 0) {
- if (pfctl_add_trans(pf->trans, PF_RULESET_SCRUB, path) ||
- pfctl_add_trans(pf->trans, PF_RULESET_FILTER, path))
+ if (pfctl_add_trans(pf->trans, PF_RULESET_FILTER, path))
return (3);
}
if (pf->loadopt & PFCTL_FLAG_TABLE)
@@ -1470,9 +1438,7 @@ pfctl_rules(int dev, char *filename, int opts, int optimize,
goto _error;
}
- if ((pf.loadopt & PFCTL_FLAG_FILTER &&
- (pfctl_load_ruleset(&pf, path, rs, PF_RULESET_SCRUB, 0))) ||
- (pf.loadopt & PFCTL_FLAG_NAT &&
+ if ((pf.loadopt & PFCTL_FLAG_NAT &&
(pfctl_load_ruleset(&pf, path, rs, PF_RULESET_NAT, 0) ||
pfctl_load_ruleset(&pf, path, rs, PF_RULESET_RDR, 0) ||
pfctl_load_ruleset(&pf, path, rs, PF_RULESET_BINAT, 0))) ||
@@ -1636,6 +1602,11 @@ pfctl_load_options(struct pfctl *pf)
if (pfctl_load_hostid(pf, pf->hostid))
error = 1;
+ /* load reassembly settings */
+ if (!(pf->opts & PF_OPT_MERGE) || pf->reass_set)
+ if (pfctl_load_reassembly(pf, pf->reassemble))
+ error = 1;
+
return (error);
}
@@ -1725,6 +1696,26 @@ pfctl_load_timeout(struct pfctl *pf, unsigned int timeout, unsigned int seconds)
}
int
+pfctl_set_reassembly(struct pfctl *pf, int on, int nodf)
+{
+ if ((loadopt & PFCTL_FLAG_OPTION) == 0)
+ return (0);
+
+ pf->reass_set = 1;
+ if (on) {
+ pf->reassemble = PF_REASS_ENABLED;
+ if (nodf)
+ pf->reassemble &= PF_REASS_NODF;
+ }
+
+ if (pf->opts & PF_OPT_VERBOSE)
+ printf("set reassemble %s %s\n", on ? "yes" : "no",
+ nodf ? "no-df" : "");
+
+ return (0);
+}
+
+int
pfctl_set_optimization(struct pfctl *pf, const char *opt)
{
const struct pf_hint *hint;
@@ -1823,6 +1814,16 @@ pfctl_load_hostid(struct pfctl *pf, u_int32_t hostid)
}
int
+pfctl_load_reassembly(struct pfctl *pf, u_int32_t reassembly)
+{
+ if (ioctl(dev, DIOCSETREASS, &reassembly)) {
+ warnx("DIOCSETREASS");
+ return (1);
+ }
+ return (0);
+}
+
+int
pfctl_set_debug(struct pfctl *pf, char *d)
{
u_int32_t level;
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
index 86c5f90ffeb..e31f83e92d1 100644
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_parser.c,v 1.241 2008/09/09 13:56:38 henning Exp $ */
+/* $OpenBSD: pfctl_parser.c,v 1.242 2009/04/06 12:05:55 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -413,6 +413,7 @@ print_pool(struct pf_pool *pool, u_int16_t p1, u_int16_t p2,
print_addr(&pooladdr->addr, af, 0);
break;
case PF_PASS:
+ case PF_MATCH:
if (PF_AZERO(&pooladdr->addr.v.a.addr, af))
printf("%s", pooladdr->ifname);
else {
@@ -651,6 +652,7 @@ print_src_node(struct pf_src_node *sn, int opts)
printf(", rdr rule %u", sn->rule.nr);
break;
case PF_PASS:
+ case PF_MATCH:
if (sn->rule.nr != -1)
printf(", filter rule %u", sn->rule.nr);
break;
@@ -663,7 +665,8 @@ void
print_rule(struct pf_rule *r, const char *anchor_call, int verbose)
{
static const char *actiontypes[] = { "pass", "block", "scrub",
- "no scrub", "nat", "no nat", "binat", "no binat", "rdr", "no rdr" };
+ "no scrub", "nat", "no nat", "binat", "no binat", "rdr", "no rdr",
+ "", "", "match"};
static const char *anchortypes[] = { "anchor", "anchor", "anchor",
"anchor", "nat-anchor", "nat-anchor", "binat-anchor",
"binat-anchor", "rdr-anchor", "rdr-anchor" };
@@ -671,7 +674,7 @@ print_rule(struct pf_rule *r, const char *anchor_call, int verbose)
if (verbose)
printf("@%d ", r->nr);
- if (r->action > PF_NORDR)
+ if (r->action > PF_MATCH)
printf("action(%d)", r->action);
else if (anchor_call[0]) {
if (anchor_call[0] == '_') {
@@ -799,7 +802,7 @@ print_rule(struct pf_rule *r, const char *anchor_call, int verbose)
print_flags(r->flags);
printf("/");
print_flags(r->flagset);
- } else if (r->action == PF_PASS &&
+ } else if ((r->action == PF_PASS || r->action == PF_MATCH) &&
(!r->proto || r->proto == IPPROTO_TCP) &&
!(r->rule_flag & PFRULE_FRAGMENT) &&
!anchor_call[0] && r->keep_state)
@@ -957,31 +960,26 @@ print_rule(struct pf_rule *r, const char *anchor_call, int verbose)
}
printf(")");
}
- if (r->rule_flag & PFRULE_FRAGMENT)
- printf(" fragment");
- if (r->rule_flag & PFRULE_NODF)
- printf(" no-df");
- if (r->rule_flag & PFRULE_RANDOMID)
- printf(" random-id");
- if (r->min_ttl)
- printf(" min-ttl %d", r->min_ttl);
- if (r->max_mss)
- printf(" max-mss %d", r->max_mss);
- if (r->rule_flag & PFRULE_SET_TOS)
- printf(" set-tos 0x%2.2x", r->set_tos);
- if (r->allow_opts)
- printf(" allow-opts");
- if (r->action == PF_SCRUB) {
- if (r->rule_flag & PFRULE_REASSEMBLE_TCP)
- printf(" reassemble tcp");
- if (r->rule_flag & PFRULE_FRAGDROP)
- printf(" fragment drop-ovl");
- else if (r->rule_flag & PFRULE_FRAGCROP)
- printf(" fragment crop");
- else
- printf(" fragment reassemble");
+ if (r->scrub_flags & PFSTATE_NODF || r->min_ttl || r->max_mss) {
+ printf(" scrub(");
+ if (r->scrub_flags & PFSTATE_NODF)
+ printf(" no-df");
+ if (r->scrub_flags & PFSTATE_RANDOMID)
+ printf(" random-id");
+ if (r->min_ttl)
+ printf(" min-ttl %d", r->min_ttl);
+ if (r->scrub_flags & PFSTATE_SETTOS)
+ printf(" set-tos 0x%2.2x", r->set_tos);
+ if (r->scrub_flags & PFSTATE_SCRUB_TCP)
+ printf(" reassemble tcp");
+ if (r->max_mss)
+ printf(" max-mss %d", r->max_mss);
+ printf(")");
}
+
+ if (r->allow_opts)
+ printf(" allow-opts");
if (r->label[0])
printf(" label \"%s\"", r->label);
if (r->qname[0] && r->pqname[0])
diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h
index 97b0325ddc7..758c576b4c4 100644
--- a/sbin/pfctl/pfctl_parser.h
+++ b/sbin/pfctl/pfctl_parser.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_parser.h,v 1.87 2007/10/13 16:35:18 deraadt Exp $ */
+/* $OpenBSD: pfctl_parser.h,v 1.88 2009/04/06 12:05:55 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -91,6 +91,7 @@ struct pfctl {
u_int32_t limit[PF_LIMIT_MAX];
u_int32_t debug;
u_int32_t hostid;
+ u_int32_t reassemble;
char *ifname;
u_int8_t timeout_set[PFTM_MAX];
@@ -98,6 +99,7 @@ struct pfctl {
u_int8_t debug_set;
u_int8_t hostid_set;
u_int8_t ifname_set;
+ u_int8_t reass_set;
};
struct node_if {
@@ -197,6 +199,7 @@ void pfctl_move_pool(struct pf_pool *, struct pf_pool *);
void pfctl_clear_pool(struct pf_pool *);
int pfctl_set_timeout(struct pfctl *, const char *, int, int);
+int pfctl_set_reassembly(struct pfctl *, int, int);
int pfctl_set_optimization(struct pfctl *, const char *);
int pfctl_set_limit(struct pfctl *, const char *, unsigned int);
int pfctl_set_logif(struct pfctl *, char *);