diff options
author | Henning Brauer <henning@cvs.openbsd.org> | 2017-11-13 11:30:12 +0000 |
---|---|---|
committer | Henning Brauer <henning@cvs.openbsd.org> | 2017-11-13 11:30:12 +0000 |
commit | da34c0e0269decb017a680092e02d33530b4e0a5 (patch) | |
tree | 44842a7d58c38dfae36b72fab509fe77f624b088 /sbin | |
parent | 564d693f1d76ac81f1703fee00bbbdc93fbda60b (diff) |
add a generic packet rate matching filter. allows things like
pass in proto icmp max-pkt-rate 100/10
all packets matching the rule in the direction the state was created are
taken into consideration (typically: requests, but not replies).
Just like with the other max-*, the rule stops matching if the maximum is
reached, so in typical scenarios the default block rule would kick in then.
with input from Holger Mikolon
ok mikeb
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/pfctl/parse.y | 27 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_parser.c | 5 |
2 files changed, 29 insertions, 3 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y index 694e3d729b0..c170e60d2a0 100644 --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.663 2017/08/11 22:30:38 benno Exp $ */ +/* $OpenBSD: parse.y,v 1.664 2017/11/13 11:30:11 henning Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -282,6 +282,11 @@ struct filter_opts { sa_family_t af; struct pf_poolhashkey *key; } route; + + struct { + u_int32_t limit; + u_int32_t seconds; + } pktrate; } filter_opts; struct antispoof_opts { @@ -472,7 +477,7 @@ int parseport(char *, struct range *r, int); %token QUEUE PRIORITY QLIMIT RTABLE RDOMAIN MINIMUM BURST PARENT %token LOAD RULESET_OPTIMIZATION RTABLE RDOMAIN PRIO ONCE DEFAULT %token STICKYADDRESS MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE -%token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH SLOPPY PFLOW +%token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH SLOPPY PFLOW MAXPKTRATE %token TAGGED TAG IFBOUND FLOATING STATEPOLICY STATEDEFAULTS ROUTE %token DIVERTTO DIVERTREPLY DIVERTPACKET NATTO AFTO RDRTO RECEIVEDON NE LE GE %token <v.string> STRING @@ -835,6 +840,8 @@ anchorrule : ANCHOR anchorname dir quick interface af proto fromto r.af = $6; r.prob = $9.prob; r.rtableid = $9.rtableid; + r.pktrate.limit = $9.pktrate.limit; + r.pktrate.seconds = $9.pktrate.seconds; if ($9.tag) if (strlcpy(r.tagname, $9.tag, @@ -1618,6 +1625,8 @@ pfrule : action dir logquick interface af proto fromto } r.tos = $8.tos; + r.pktrate.limit = $8.pktrate.limit; + r.pktrate.seconds = $8.pktrate.seconds; r.keep_state = $8.keep.action; o = $8.keep.options; @@ -2184,6 +2193,19 @@ filter_opt : USER uids { | ONCE { filter_opts.marker |= FOM_ONCE; } + | MAXPKTRATE NUMBER '/' NUMBER { + if ($2 < 0 || $2 > UINT_MAX || + $4 < 0 || $4 > UINT_MAX) { + yyerror("only positive values permitted"); + YYERROR; + } + if (filter_opts.pktrate.limit) { + yyerror("cannot respecify max-pkt-rate"); + YYERROR; + } + filter_opts.pktrate.limit = $2; + filter_opts.pktrate.seconds = $4; + } | filter_sets ; @@ -5055,6 +5077,7 @@ lookup(char *s) { "matches", MATCHES}, { "max", MAXIMUM}, { "max-mss", MAXMSS}, + { "max-pkt-rate", MAXPKTRATE}, { "max-src-conn", MAXSRCCONN}, { "max-src-conn-rate", MAXSRCCONNRATE}, { "max-src-nodes", MAXSRCNODES}, diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c index f62b9ab6128..5963b6bdffd 100644 --- a/sbin/pfctl/pfctl_parser.c +++ b/sbin/pfctl/pfctl_parser.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_parser.c,v 1.316 2017/08/14 15:53:04 henning Exp $ */ +/* $OpenBSD: pfctl_parser.c,v 1.317 2017/11/13 11:30:11 henning Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -862,6 +862,9 @@ print_rule(struct pf_rule *r, const char *anchor_call, int opts) printf(" tos 0x%2.2x", r->tos); if (r->prio) printf(" prio %u", r->prio == PF_PRIO_ZERO ? 0 : r->prio); + if (r->pktrate.limit) + printf(" max-pkt-rate %u/%u", r->pktrate.limit, + r->pktrate.seconds); if (r->scrub_flags & PFSTATE_SETMASK || r->qname[0]) { char *comma = ""; |