summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2009-09-02 13:28:04 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2009-09-02 13:28:04 +0000
commit41a51176f9e0dd52dfaffaab7ad0f3f12394606c (patch)
tree11ac4ee15c4bdb19f6663ace6d21d1a9f4044114
parenta9cd8b4f408038cc0254e16238a3f06a8d8642e1 (diff)
all the new *-to options are part of the "filteropts" section at the
end of a pf rule (nat-to, divert-to, rdr-to, ...). take the historical chance to upgrade the grammar and move the route options to the filteropts section as well. for example, pass in on em0 route-to (em1 192.168.1.1) from 10.1.1.1 becomes pass in on em0 from 10.1.1.1 route-to (em1 192.168.1.1) many people like this including pyr@ mk@ kettenis@ todd@ and others ok henning@
-rw-r--r--sbin/pfctl/parse.y228
-rw-r--r--sbin/pfctl/pfctl_parser.c30
-rw-r--r--share/man/man5/pf.conf.58
3 files changed, 134 insertions, 132 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 45a4247f323..eba164a89ac 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.563 2009/09/01 13:42:00 henning Exp $ */
+/* $OpenBSD: parse.y,v 1.564 2009/09/02 13:28:03 reyk Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -275,6 +275,15 @@ struct filter_opts {
int settos;
int randomid;
int max_mss;
+
+ /* route opts */
+ struct {
+ struct node_host *host;
+ u_int8_t rt;
+ u_int8_t pool_opts;
+ sa_family_t af;
+ struct pf_poolhashkey *key;
+ } route;
} filter_opts;
struct antispoof_opts {
@@ -395,13 +404,6 @@ typedef struct {
struct peer src, dst;
struct node_os *src_os;
} fromto;
- struct {
- struct node_host *host;
- u_int8_t rt;
- u_int8_t pool_opts;
- sa_family_t af;
- struct pf_poolhashkey *key;
- } route;
struct redirection *redirection;
struct {
int action;
@@ -487,7 +489,6 @@ int parseport(char *, struct range *r, int);
%type <v.port> portspec port_list port_item
%type <v.uid> uids uid_list uid_item
%type <v.gid> gids gid_list gid_item
-%type <v.route> route
%type <v.redirection> redirpool
%type <v.string> label stringall anchorname
%type <v.string> string varstring numberstring
@@ -882,6 +883,12 @@ anchorrule : ANCHOR anchorname dir quick interface af proto fromto
YYERROR;
}
+ if ($9.route.rt) {
+ yyerror("cannot specify route handling "
+ "on anchors");
+ YYERROR;
+ }
+
if ($9.match_tag)
if (strlcpy(r.match_tagname, $9.match_tag,
PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
@@ -1652,7 +1659,7 @@ qassign_item : STRING {
}
;
-pfrule : action dir logquick interface route af proto fromto
+pfrule : action dir logquick interface af proto fromto
filter_opts
{
struct pf_rule r;
@@ -1689,67 +1696,67 @@ pfrule : action dir logquick interface route af proto fromto
r.log = $3.log;
r.logif = $3.logif;
r.quick = $3.quick;
- r.prob = $9.prob;
- r.rtableid = $9.rtableid;
+ r.prob = $8.prob;
+ r.rtableid = $8.rtableid;
- if ($9.nodf)
+ if ($8.nodf)
r.scrub_flags |= PFSTATE_NODF;
- if ($9.randomid)
+ if ($8.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) {
+ if ($8.minttl)
+ r.min_ttl = $8.minttl;
+ if ($8.max_mss)
+ r.max_mss = $8.max_mss;
+ if ($8.marker & FOM_SETTOS) {
r.scrub_flags |= PFSTATE_SETTOS;
- r.set_tos = $9.settos;
+ r.set_tos = $8.settos;
}
- if ($9.marker & FOM_SCRUB_TCP)
+ if ($8.marker & FOM_SCRUB_TCP)
r.scrub_flags |= PFSTATE_SCRUB_TCP;
- r.af = $6;
- if ($9.tag)
- if (strlcpy(r.tagname, $9.tag,
+ r.af = $5;
+ if ($8.tag)
+ if (strlcpy(r.tagname, $8.tag,
PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
yyerror("tag too long, max %u chars",
PF_TAG_NAME_SIZE - 1);
YYERROR;
}
- if ($9.match_tag)
- if (strlcpy(r.match_tagname, $9.match_tag,
+ 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 = $9.match_tag_not;
- if (rule_label(&r, $9.label))
+ r.match_tag_not = $8.match_tag_not;
+ if (rule_label(&r, $8.label))
YYERROR;
- free($9.label);
- r.flags = $9.flags.b1;
- r.flagset = $9.flags.b2;
- if (($9.flags.b1 & $9.flags.b2) != $9.flags.b1) {
+ free($8.label);
+ r.flags = $8.flags.b1;
+ r.flagset = $8.flags.b2;
+ if (($8.flags.b1 & $8.flags.b2) != $8.flags.b1) {
yyerror("flags always false");
YYERROR;
}
- if ($9.flags.b1 || $9.flags.b2 || $8.src_os) {
- for (proto = $7; proto != NULL &&
+ if ($8.flags.b1 || $8.flags.b2 || $7.src_os) {
+ for (proto = $6; proto != NULL &&
proto->proto != IPPROTO_TCP;
proto = proto->next)
; /* nothing */
- if (proto == NULL && $7 != NULL) {
- if ($9.flags.b1 || $9.flags.b2)
+ if (proto == NULL && $6 != NULL) {
+ if ($8.flags.b1 || $8.flags.b2)
yyerror(
"flags only apply to tcp");
- if ($8.src_os)
+ if ($7.src_os)
yyerror(
"OS fingerprinting only "
"apply to tcp");
YYERROR;
}
#if 0
- if (($9.flags.b1 & parse_flags("S")) == 0 &&
- $8.src_os) {
+ if (($8.flags.b1 & parse_flags("S")) == 0 &&
+ $7.src_os) {
yyerror("OS fingerprinting requires "
"the SYN TCP flag (flags S/SA)");
YYERROR;
@@ -1757,13 +1764,13 @@ pfrule : action dir logquick interface route af proto fromto
#endif
}
- r.tos = $9.tos;
- r.keep_state = $9.keep.action;
- o = $9.keep.options;
+ r.tos = $8.tos;
+ r.keep_state = $8.keep.action;
+ o = $8.keep.options;
/* 'keep state' by default on pass rules. */
if (!r.keep_state && !r.action &&
- !($9.marker & FOM_KEEP)) {
+ !($8.marker & FOM_KEEP)) {
r.keep_state = PF_STATE_NORMAL;
o = keep_state_defaults;
defaults = 1;
@@ -1941,7 +1948,7 @@ pfrule : action dir logquick interface route af proto fromto
/* 'flags S/SA' by default on stateful rules */
if (!r.action && !r.flags && !r.flagset &&
- !$9.fragment && !($9.marker & FOM_FLAGS) &&
+ !$8.fragment && !($8.marker & FOM_FLAGS) &&
r.keep_state) {
r.flags = parse_flags("S");
r.flagset = parse_flags("SA");
@@ -1985,50 +1992,52 @@ pfrule : action dir logquick interface route af proto fromto
if (r.keep_state && !statelock)
r.rule_flag |= default_statelock;
- if ($9.fragment)
+ if ($8.fragment)
r.rule_flag |= PFRULE_FRAGMENT;
- r.allow_opts = $9.allowopts;
+ r.allow_opts = $8.allowopts;
- decide_address_family($8.src.host, &r.af);
- decide_address_family($8.dst.host, &r.af);
+ decide_address_family($7.src.host, &r.af);
+ decide_address_family($7.dst.host, &r.af);
- if ($5.rt) {
+ if ($8.route.rt) {
if (!r.direction) {
yyerror("direction must be explicit "
"with rules that specify routing");
YYERROR;
}
- r.rt = $5.rt;
- r.rdr.opts = $5.pool_opts;
- if ($5.key != NULL)
- memcpy(&r.rdr.key, $5.key,
+ r.rt = $8.route.rt;
+ r.rdr.opts = $8.route.pool_opts;
+ if ($8.route.key != NULL)
+ memcpy(&r.rdr.key, $8.route.key,
sizeof(struct pf_poolhashkey));
}
if (r.rt && r.rt != PF_FASTROUTE) {
- decide_address_family($5.host, &r.af);
- remove_invalid_hosts(&$5.host, &r.af);
- if ($5.host == NULL) {
+ decide_address_family($8.route.host, &r.af);
+ remove_invalid_hosts(&$8.route.host, &r.af);
+ if ($8.route.host == NULL) {
yyerror("no routing address with "
"matching address family found.");
YYERROR;
}
if ((r.rdr.opts & PF_POOL_TYPEMASK) ==
- PF_POOL_NONE && ($5.host->next != NULL ||
- $5.host->addr.type == PF_ADDR_TABLE ||
- DYNIF_MULTIADDR($5.host->addr)))
+ PF_POOL_NONE && ($8.route.host->next != NULL ||
+ $8.route.host->addr.type == PF_ADDR_TABLE ||
+ DYNIF_MULTIADDR($8.route.host->addr)))
r.rdr.opts |= PF_POOL_ROUNDROBIN;
if ((r.rdr.opts & PF_POOL_TYPEMASK) !=
PF_POOL_ROUNDROBIN &&
- disallow_table($5.host, "tables are only "
+ disallow_table($8.route.host,
+ "tables are only "
"supported in round-robin routing pools"))
YYERROR;
if ((r.rdr.opts & PF_POOL_TYPEMASK) !=
PF_POOL_ROUNDROBIN &&
- disallow_alias($5.host, "interface (%s) "
+ disallow_alias($8.route.host,
+ "interface (%s) "
"is only supported in round-robin "
"routing pools"))
YYERROR;
- if ($5.host->next != NULL) {
+ if ($8.route.host->next != NULL) {
if ((r.rdr.opts & PF_POOL_TYPEMASK) !=
PF_POOL_ROUNDROBIN) {
yyerror("r.rpool.opts must "
@@ -2037,32 +2046,32 @@ pfrule : action dir logquick interface route af proto fromto
}
}
/* fake redirspec */
- if (($9.rdr.rdr = calloc(1,
- sizeof(*$9.rdr.rdr))) == NULL)
- err(1, "$9.rdr.rdr");
- $9.rdr.rdr->host = $5.host;
+ if (($8.rdr.rdr = calloc(1,
+ sizeof(*$8.rdr.rdr))) == NULL)
+ err(1, "$8.rdr.rdr");
+ $8.rdr.rdr->host = $8.route.host;
}
- if ($9.queues.qname != NULL) {
- if (strlcpy(r.qname, $9.queues.qname,
+ if ($8.queues.qname != NULL) {
+ if (strlcpy(r.qname, $8.queues.qname,
sizeof(r.qname)) >= sizeof(r.qname)) {
yyerror("rule qname too long (max "
"%d chars)", sizeof(r.qname)-1);
YYERROR;
}
- free($9.queues.qname);
+ free($8.queues.qname);
}
- if ($9.queues.pqname != NULL) {
- if (strlcpy(r.pqname, $9.queues.pqname,
+ if ($8.queues.pqname != NULL) {
+ if (strlcpy(r.pqname, $8.queues.pqname,
sizeof(r.pqname)) >= sizeof(r.pqname)) {
yyerror("rule pqname too long (max "
"%d chars)", sizeof(r.pqname)-1);
YYERROR;
}
- free($9.queues.pqname);
+ free($8.queues.pqname);
}
- if ((r.divert.port = $9.divert.port)) {
+ if ((r.divert.port = $8.divert.port)) {
if (r.direction == PF_OUT) {
- if ($9.divert.addr) {
+ if ($8.divert.addr) {
yyerror("address specified "
"for outgoing divert");
YYERROR;
@@ -2070,24 +2079,24 @@ pfrule : action dir logquick interface route af proto fromto
bzero(&r.divert.addr,
sizeof(r.divert.addr));
} else {
- if (!$9.divert.addr) {
+ if (!$8.divert.addr) {
yyerror("no address specified "
"for incoming divert");
YYERROR;
}
- if ($9.divert.addr->af != r.af) {
+ if ($8.divert.addr->af != r.af) {
yyerror("address family "
"mismatch for divert");
YYERROR;
}
r.divert.addr =
- $9.divert.addr->addr.v.a.addr;
+ $8.divert.addr->addr.v.a.addr;
}
}
- expand_rule(&r, $4, &$9.nat, &$9.rdr, $7, $8.src_os,
- $8.src.host, $8.src.port, $8.dst.host, $8.dst.port,
- $9.uid, $9.gid, $9.icmpspec, "");
+ expand_rule(&r, $4, &$8.nat, &$8.rdr, $6, $7.src_os,
+ $7.src.host, $7.src.port, $7.dst.host, $7.dst.port,
+ $8.uid, $8.gid, $8.icmpspec, "");
}
;
@@ -2245,6 +2254,32 @@ filter_opt : USER uids {
memcpy(&filter_opts.rdr.pool_opts, &$3,
sizeof(filter_opts.rdr.pool_opts));
}
+ | FASTROUTE {
+ filter_opts.route.host = NULL;
+ filter_opts.route.rt = PF_FASTROUTE;
+ filter_opts.route.pool_opts = 0;
+ }
+ | ROUTETO routespec pool_opts {
+ filter_opts.route.host = $2;
+ filter_opts.route.rt = PF_ROUTETO;
+ filter_opts.route.pool_opts = $3.type | $3.opts;
+ if ($3.key != NULL)
+ filter_opts.route.key = $3.key;
+ }
+ | REPLYTO routespec pool_opts {
+ filter_opts.route.host = $2;
+ filter_opts.route.rt = PF_REPLYTO;
+ filter_opts.route.pool_opts = $3.type | $3.opts;
+ if ($3.key != NULL)
+ filter_opts.route.key = $3.key;
+ }
+ | DUPTO routespec pool_opts {
+ filter_opts.route.host = $2;
+ filter_opts.route.rt = PF_DUPTO;
+ filter_opts.route.pool_opts = $3.type | $3.opts;
+ if ($3.key != NULL)
+ filter_opts.route.key = $3.key;
+ }
;
probability : STRING {
@@ -3665,39 +3700,6 @@ routespec : route_host { $$ = $1; }
| '{' optnl route_host_list '}' { $$ = $3; }
;
-route : /* empty */ {
- $$.host = NULL;
- $$.rt = 0;
- $$.pool_opts = 0;
- }
- | FASTROUTE {
- $$.host = NULL;
- $$.rt = PF_FASTROUTE;
- $$.pool_opts = 0;
- }
- | ROUTETO routespec pool_opts {
- $$.host = $2;
- $$.rt = PF_ROUTETO;
- $$.pool_opts = $3.type | $3.opts;
- if ($3.key != NULL)
- $$.key = $3.key;
- }
- | REPLYTO routespec pool_opts {
- $$.host = $2;
- $$.rt = PF_REPLYTO;
- $$.pool_opts = $3.type | $3.opts;
- if ($3.key != NULL)
- $$.key = $3.key;
- }
- | DUPTO routespec pool_opts {
- $$.host = $2;
- $$.rt = PF_DUPTO;
- $$.pool_opts = $3.type | $3.opts;
- if ($3.key != NULL)
- $$.key = $3.key;
- }
- ;
-
timeout_spec : STRING NUMBER
{
if (check_rulestate(PFCTL_STATE_OPTION)) {
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
index 1f1d4899150..dc744ec3d7f 100644
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_parser.c,v 1.245 2009/09/01 13:42:00 henning Exp $ */
+/* $OpenBSD: pfctl_parser.c,v 1.246 2009/09/02 13:28:03 reyk Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -753,20 +753,6 @@ print_rule(struct pf_rule *r, const char *anchor_call, int verbose)
else
printf(" on %s", r->ifname);
}
- if (r->rt) {
- if (r->rt == PF_ROUTETO)
- printf(" route-to");
- else if (r->rt == PF_REPLYTO)
- printf(" reply-to");
- else if (r->rt == PF_DUPTO)
- printf(" dup-to");
- else if (r->rt == PF_FASTROUTE)
- printf(" fastroute");
- if (r->rt != PF_FASTROUTE) {
- printf(" ");
- print_pool(&r->rdr, 0, 0, r->af, PF_PASS);
- }
- }
if (r->af) {
if (r->af == AF_INET)
printf(" inet");
@@ -1039,6 +1025,20 @@ print_rule(struct pf_rule *r, const char *anchor_call, int verbose)
print_pool(&r->rdr, r->rdr.proxy_port[0],
r->rdr.proxy_port[1], r->af, PF_RDR);
}
+ if (r->rt) {
+ if (r->rt == PF_ROUTETO)
+ printf(" route-to");
+ else if (r->rt == PF_REPLYTO)
+ printf(" reply-to");
+ else if (r->rt == PF_DUPTO)
+ printf(" dup-to");
+ else if (r->rt == PF_FASTROUTE)
+ printf(" fastroute");
+ if (r->rt != PF_FASTROUTE) {
+ printf(" ");
+ print_pool(&r->rdr, 0, 0, r->af, PF_PASS);
+ }
+ }
}
void
diff --git a/share/man/man5/pf.conf.5 b/share/man/man5/pf.conf.5
index 7fbac8c39f1..82f36d2ca9c 100644
--- a/share/man/man5/pf.conf.5
+++ b/share/man/man5/pf.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: pf.conf.5,v 1.449 2009/09/01 13:43:15 henning Exp $
+.\" $OpenBSD: pf.conf.5,v 1.450 2009/09/02 13:28:02 reyk Exp $
.\"
.\" Copyright (c) 2002, Daniel Hartmeier
.\" All rights reserved.
@@ -27,7 +27,7 @@
.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: September 1 2009 $
+.Dd $Mdocdate: September 2 2009 $
.Dt PF.CONF 5
.Os
.Sh NAME
@@ -2584,8 +2584,7 @@ option = "set" ( [ "timeout" ( timeout | "{" timeout-list "}" ) ] |
pf-rule = action [ ( "in" | "out" ) ]
[ "log" [ "(" logopts ")"] ] [ "quick" ]
- [ "on" ifspec ] [ "fastroute" | route ] [ af ]
- [ protospec ] hosts [ filteropts ]
+ [ "on" ifspec ] [ af ] [ protospec ] hosts [ filteropts ]
logopts = logopt [ [ "," ] logopts ]
logopt = "all" | "user" | "to" interface-name
@@ -2603,6 +2602,7 @@ filteropt = user | group | flags | icmp-type | icmp6-type |
[ portspec ] [ pooltype ] |
"nat-to" ( redirhost | "{" redirhost-list "}" )
[ portspec ] [ pooltype ] [ "static-port" ]
+ [ "fastroute" | route ]
scrubopts = scrubopt [ [ "," ] scrubopts ]
scrubopt = "no-df" | "min-ttl" number | "max-mss" number |