summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sbin/pfctl/parse.y41
-rw-r--r--sbin/pfctl/pfctl.c62
-rw-r--r--sbin/pfctl/pfctl_parser.h7
-rw-r--r--sys/net/pf_syncookies.c6
-rw-r--r--sys/net/pfvar.h5
5 files changed, 98 insertions, 23 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 6e20794156e..af2a9fedb4c 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.669 2018/02/06 23:47:47 henning Exp $ */
+/* $OpenBSD: parse.y,v 1.670 2018/02/08 09:15:46 henning Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -342,6 +342,7 @@ struct table_opts {
struct node_hfsc_opts hfsc_opts;
struct node_state_opt *keep_state_defaults = NULL;
+struct pfctl_watermarks syncookie_opts;
int disallow_table(struct node_host *, const char *);
int disallow_urpf_failed(struct node_host *, const char *);
@@ -449,6 +450,7 @@ typedef struct {
struct table_opts table_opts;
struct pool_opts pool_opts;
struct node_hfsc_opts hfsc_opts;
+ struct pfctl_watermarks *watermarks;
} v;
int lineno;
} YYSTYPE;
@@ -527,6 +529,7 @@ int parseport(char *, struct range *r, int);
%type <v.scrub_opts> scrub_opts scrub_opt scrub_opts_l
%type <v.table_opts> table_opts table_opt table_opts_l
%type <v.pool_opts> pool_opts pool_opt pool_opts_l
+%type <v.watermarks> syncookie_opts
%%
ruleset : /* empty */
@@ -686,8 +689,8 @@ option : SET REASSEMBLE yesno optnodf {
}
keep_state_defaults = $3;
}
- | SET SYNCOOKIES syncookie_val {
- if (pfctl_set_syncookies(pf, $3)) {
+ | SET SYNCOOKIES syncookie_val syncookie_opts {
+ if (pfctl_set_syncookies(pf, $3, $4)) {
yyerror("error setting syncookies");
YYERROR;
}
@@ -708,6 +711,38 @@ syncookie_val : STRING {
}
;
+syncookie_opts : /* empty */ { $$ = NULL; }
+ | {
+ memset(&syncookie_opts, 0, sizeof(syncookie_opts));
+ } '(' syncookie_opt_l ')' { $$ = &syncookie_opts; }
+ ;
+
+syncookie_opt_l : syncookie_opt_l comma syncookie_opt
+ | syncookie_opt
+ ;
+
+syncookie_opt : STRING STRING {
+ double val;
+ char *cp;
+
+ val = strtod($2, &cp);
+ if (cp == NULL || strcmp(cp, "%"))
+ YYERROR;
+ if (val <= 0 || val > 100) {
+ yyerror("illegal percentage value");
+ YYERROR;
+ }
+ if (!strcmp($1, "start")) {
+ syncookie_opts.hi = val;
+ } else if (!strcmp($1, "end")) {
+ syncookie_opts.lo = val;
+ } else {
+ yyerror("illegal syncookie option");
+ YYERROR;
+ }
+ }
+ ;
+
stringall : STRING { $$ = $1; }
| ALL {
if (($$ = strdup("all")) == NULL) {
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index 141c94fbf94..93ca9215bf0 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl.c,v 1.353 2018/02/08 02:26:39 henning Exp $ */
+/* $OpenBSD: pfctl.c,v 1.354 2018/02/08 09:15:46 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -1752,6 +1752,9 @@ pfctl_init_options(struct pfctl *pf)
pf->limit[PF_LIMIT_STATES] = PFSTATE_HIWAT;
+ pf->syncookieswat[0] = PF_SYNCOOKIES_LOWATPCT;
+ pf->syncookieswat[1] = PF_SYNCOOKIES_HIWATPCT;
+
mib[0] = CTL_KERN;
mib[1] = KERN_MAXCLUSTERS;
size = sizeof(mcl);
@@ -1801,15 +1804,6 @@ pfctl_load_options(struct pfctl *pf)
pf->timeout_set[PFTM_ADAPTIVE_END] = 1;
}
- /*
- * if the states limit has been set adjust the synflood detection
- * hiwat and lowat. Eventually they should be tunables.
- */
- if (pf->limit_set[PF_LIMIT_STATES])
- if (pfctl_set_synflwats(pf, pf->limit[PF_LIMIT_STATES] / 8,
- pf->limit[PF_LIMIT_STATES] / 4))
- error = 1;
-
/* load timeouts */
for (i = 0; i < PFTM_MAX; i++)
if (pfctl_load_timeout(pf, i, pf->timeout[i]))
@@ -1834,6 +1828,23 @@ pfctl_load_options(struct pfctl *pf)
/* load syncookies settings */
if (pf->syncookies_set && pfctl_load_syncookies(pf, pf->syncookies))
error = 1;
+ if (pf->syncookieswat_set) {
+ struct pfioc_limit pl;
+ unsigned curlim;
+
+ if (pf->limit_set[PF_LIMIT_STATES])
+ curlim = pf->limit[PF_LIMIT_STATES];
+ else {
+ memset(&pl, 0, sizeof(pl));
+ pl.index = pf_limits[PF_LIMIT_STATES].index;
+ if (ioctl(dev, DIOCGETLIMIT, &pl))
+ err(1, "DIOCGETLIMIT");
+ curlim = pl.limit;
+ }
+ if (pfctl_set_synflwats(pf, curlim * pf->syncookieswat[0]/100,
+ curlim * pf->syncookieswat[1]/100))
+ error = 1;
+ }
return (error);
}
@@ -1958,16 +1969,39 @@ pfctl_set_reassembly(struct pfctl *pf, int on, int nodf)
}
int
-pfctl_set_syncookies(struct pfctl *pf, u_int8_t val)
+pfctl_set_syncookies(struct pfctl *pf, u_int8_t val, struct pfctl_watermarks *w)
{
+ if (val != PF_SYNCOOKIES_ADAPTIVE && w != NULL) {
+ warnx("syncookies start/end only apply to adaptive");
+ return (1);
+ }
+ if (val == PF_SYNCOOKIES_ADAPTIVE && w != NULL) {
+ if (!w->hi)
+ w->hi = PF_SYNCOOKIES_HIWATPCT;
+ if (!w->lo)
+ w->lo = w->hi / 2;
+ if (w->lo >= w->hi) {
+ warnx("start must be higher than end");
+ return (1);
+ }
+ pf->syncookieswat[0] = w->lo;
+ pf->syncookieswat[1] = w->hi;
+ pf->syncookieswat_set = 1;
+ }
+
if (pf->opts & PF_OPT_VERBOSE) {
if (val == PF_SYNCOOKIES_NEVER)
printf("set syncookies never\n");
else if (val == PF_SYNCOOKIES_ALWAYS)
printf("set syncookies always\n");
- else if (val == PF_SYNCOOKIES_ADAPTIVE)
- printf("set syncookies adaptive\n");
- else { /* cannot happen */
+ else if (val == PF_SYNCOOKIES_ADAPTIVE) {
+ if (pf->syncookieswat_set)
+ printf("set syncookies adaptive (start %u%%, "
+ "end %u%%)\n", pf->syncookieswat[1],
+ pf->syncookieswat[0]);
+ else
+ printf("set syncookies adaptive\n");
+ } else { /* cannot happen */
warnx("king bula ate all syncookies");
return (1);
}
diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h
index ef42d864c24..eefeb19e6b4 100644
--- a/sbin/pfctl/pfctl_parser.h
+++ b/sbin/pfctl/pfctl_parser.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_parser.h,v 1.109 2018/02/08 02:26:39 henning Exp $ */
+/* $OpenBSD: pfctl_parser.h,v 1.110 2018/02/08 09:15:46 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -92,6 +92,7 @@ struct pfctl {
u_int32_t hostid;
u_int32_t reassemble;
u_int8_t syncookies;
+ u_int8_t syncookieswat[2]; /* lowat, hiwat */
char *ifname;
u_int8_t timeout_set[PFTM_MAX];
@@ -101,6 +102,7 @@ struct pfctl {
u_int8_t ifname_set;
u_int8_t reass_set;
u_int8_t syncookies_set;
+ u_int8_t syncookieswat_set;
};
struct node_if {
@@ -221,7 +223,8 @@ 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_syncookies(struct pfctl *, u_int8_t);
+int pfctl_set_syncookies(struct pfctl *, u_int8_t,
+ struct pfctl_watermarks *);
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 *);
diff --git a/sys/net/pf_syncookies.c b/sys/net/pf_syncookies.c
index 14becfb2b30..63d15f12bc2 100644
--- a/sys/net/pf_syncookies.c
+++ b/sys/net/pf_syncookies.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_syncookies.c,v 1.4 2018/02/08 02:25:44 henning Exp $ */
+/* $OpenBSD: pf_syncookies.c,v 1.5 2018/02/08 09:15:46 henning Exp $ */
/* Copyright (c) 2016,2017 Henning Brauer <henning@openbsd.org>
* Copyright (c) 2016 Alexandr Nedvedicky <sashan@openbsd.org>
@@ -132,8 +132,8 @@ pf_syncookies_init(void)
{
timeout_set(&pf_syncookie_status.keytimeout,
pf_syncookie_rotate, NULL);
- pf_syncookie_status.hiwat = PFSTATE_HIWAT/4;
- pf_syncookie_status.lowat = PFSTATE_HIWAT/8;
+ pf_syncookie_status.hiwat = PFSTATE_HIWAT * PF_SYNCOOKIES_HIWATPCT/100;
+ pf_syncookie_status.lowat = PFSTATE_HIWAT * PF_SYNCOOKIES_LOWATPCT/100;
pf_syncookies_setmode(PF_SYNCOOKIES_NEVER);
}
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 7ec2d91da41..fb245426ef4 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfvar.h,v 1.473 2018/02/08 02:25:44 henning Exp $ */
+/* $OpenBSD: pfvar.h,v 1.474 2018/02/08 09:15:46 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -1326,6 +1326,9 @@ struct pf_status {
#define PF_SYNCOOKIES_ADAPTIVE 2
#define PF_SYNCOOKIES_MODE_MAX PF_SYNCOOKIES_ADAPTIVE
+#define PF_SYNCOOKIES_HIWATPCT 25
+#define PF_SYNCOOKIES_LOWATPCT PF_SYNCOOKIES_HIWATPCT/2
+
#define PF_PRIO_ZERO 0xff /* match "prio 0" packets */
struct pf_queue_bwspec {