make the watermarks/thresholds for entering and leaving syncookie mode when
authorhenning <henning@openbsd.org>
Thu, 8 Feb 2018 09:15:46 +0000 (09:15 +0000)
committerhenning <henning@openbsd.org>
Thu, 8 Feb 2018 09:15:46 +0000 (09:15 +0000)
syncookies are set to adaptive tunable, ok claudio benno

sbin/pfctl/parse.y
sbin/pfctl/pfctl.c
sbin/pfctl/pfctl_parser.h
sys/net/pf_syncookies.c
sys/net/pfvar.h

index 6e20794..af2a9fe 100644 (file)
@@ -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) {
index 141c94f..93ca921 100644 (file)
@@ -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);
                }
index ef42d86..eefeb19 100644 (file)
@@ -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 *);
index 14becfb..63d15f1 100644 (file)
@@ -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);
 }
 
index 7ec2d91..fb24542 100644 (file)
@@ -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 {