The branch main has been updated by kp:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=c69121c473d75abab55f9ade8e8138ac09c0942c

commit c69121c473d75abab55f9ade8e8138ac09c0942c
Author:     Kristof Provost <[email protected]>
AuthorDate: 2021-05-26 11:41:34 +0000
Commit:     Kristof Provost <[email protected]>
CommitDate: 2021-07-20 08:36:14 +0000

    pfctl: syncookie configuration
    
    pfctl and libpfctl code required to enable/disable the syncookie
    feature.
    
    MFC after:      1 week
    Sponsored by:   Modirum MDPay
    Differential Revision:  https://reviews.freebsd.org/D31140
---
 lib/libpfctl/libpfctl.c   | 57 +++++++++++++++++++++++++++++++++++++++++++++++
 lib/libpfctl/libpfctl.h   | 11 +++++++++
 sbin/pfctl/parse.y        | 20 +++++++++++++++--
 sbin/pfctl/pfctl.c        | 30 +++++++++++++++++++++++--
 sbin/pfctl/pfctl_parser.c |  7 +++++-
 sbin/pfctl/pfctl_parser.h |  3 ++-
 6 files changed, 122 insertions(+), 6 deletions(-)

diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
index 6421a2c752a8..ced130820d7d 100644
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -816,3 +816,60 @@ pfctl_kill_states(int dev, const struct pfctl_kill *kill, 
unsigned int *killed)
 {
        return (_pfctl_clear_states(dev, kill, killed, DIOCKILLSTATESNV));
 }
+
+int
+pfctl_set_syncookies(int dev, const struct pfctl_syncookies *s)
+{
+       struct pfioc_nv  nv;
+       nvlist_t        *nvl;
+       int              ret;
+
+       nvl = nvlist_create(0);
+
+       nvlist_add_bool(nvl, "enabled", s->mode != PFCTL_SYNCOOKIES_NEVER);
+       nvlist_add_bool(nvl, "adaptive", false); /* XXX TODO */
+
+       nv.data = nvlist_pack(nvl, &nv.len);
+       nv.size = nv.len;
+       nvlist_destroy(nvl);
+       nvl = NULL;
+
+       ret = ioctl(dev, DIOCSETSYNCOOKIES, &nv);
+
+       free(nv.data);
+       return (ret);
+}
+
+int
+pfctl_get_syncookies(int dev, struct pfctl_syncookies *s)
+{
+       struct pfioc_nv  nv;
+       nvlist_t        *nvl;
+       bool            enabled, adaptive;
+
+       bzero(s, sizeof(*s));
+
+       nv.data = malloc(128);
+       nv.len = nv.size = 128;
+
+       if (ioctl(dev, DIOCGETSYNCOOKIES, &nv)) {
+               free(nv.data);
+               return (errno);
+       }
+
+       nvl = nvlist_unpack(nv.data, nv.len, 0);
+       free(nv.data);
+       if (nvl == NULL) {
+               free(nv.data);
+               return (EIO);
+       }
+
+       enabled = nvlist_get_bool(nvl, "enabled");
+       adaptive = nvlist_get_bool(nvl, "adaptive");
+
+       s->mode = enabled ? PFCTL_SYNCOOKIES_ALWAYS : PFCTL_SYNCOOKIES_NEVER;
+
+       nvlist_destroy(nvl);
+
+       return (0);
+}
diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h
index 62866e17f904..d57241dd59fd 100644
--- a/lib/libpfctl/libpfctl.h
+++ b/lib/libpfctl/libpfctl.h
@@ -244,6 +244,15 @@ struct pfctl_states {
        size_t                  count;
 };
 
+enum pfctl_syncookies_mode {
+       PFCTL_SYNCOOKIES_NEVER,
+       PFCTL_SYNCOOKIES_ALWAYS
+};
+
+struct pfctl_syncookies {
+       enum pfctl_syncookies_mode      mode;
+};
+
 int    pfctl_get_rule(int dev, u_int32_t nr, u_int32_t ticket,
            const char *anchor, u_int32_t ruleset, struct pfctl_rule *rule,
            char *anchor_call);
@@ -260,5 +269,7 @@ int pfctl_clear_states(int dev, const struct pfctl_kill 
*kill,
            unsigned int *killed);
 int    pfctl_kill_states(int dev, const struct pfctl_kill *kill,
            unsigned int *killed);
+int    pfctl_set_syncookies(int dev, const struct pfctl_syncookies *s);
+int    pfctl_get_syncookies(int dev, struct pfctl_syncookies *s);
 
 #endif
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 74744794370f..dbfe299cf34f 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -464,7 +464,7 @@ int parseport(char *, struct range *r, int);
 %token REASSEMBLE FRAGDROP FRAGCROP ANCHOR NATANCHOR RDRANCHOR BINATANCHOR
 %token SET OPTIMIZATION TIMEOUT LIMIT LOGINTERFACE BLOCKPOLICY FAILPOLICY
 %token RANDOMID REQUIREORDER SYNPROXY FINGERPRINTS NOSYNC DEBUG SKIP HOSTID
-%token ANTISPOOF FOR INCLUDE KEEPCOUNTERS
+%token ANTISPOOF FOR INCLUDE KEEPCOUNTERS SYNCOOKIES
 %token BITMASK RANDOM SOURCEHASH ROUNDROBIN STATICPORT PROBABILITY MAPEPORTSET
 %token ALTQ CBQ CODEL PRIQ HFSC FAIRQ BANDWIDTH TBRSIZE LINKSHARE REALTIME
 %token UPPERLIMIT QUEUE PRIORITY QLIMIT HOGS BUCKETS RTABLE TARGET INTERVAL
@@ -480,7 +480,7 @@ int parseport(char *, struct range *r, int);
 %type  <v.number>              number icmptype icmp6type uid gid
 %type  <v.number>              tos not yesno
 %type  <v.probability>         probability
-%type  <v.i>                   no dir af fragcache optimizer
+%type  <v.i>                   no dir af fragcache optimizer syncookie_val
 %type  <v.i>                   sourcetrack flush unaryop statelock
 %type  <v.b>                   action nataction natpasslog scrubaction
 %type  <v.b>                   flags flag blockspec prio
@@ -725,6 +725,21 @@ option             : SET OPTIMIZATION STRING               
{
                | SET KEEPCOUNTERS {
                        pf->keep_counters = true;
                }
+               | SET SYNCOOKIES syncookie_val {
+                       pf->syncookies = $3;
+               }
+               ;
+
+syncookie_val  : STRING        {
+                       if (!strcmp($1, "never"))
+                               $$ = PFCTL_SYNCOOKIES_NEVER;
+                       else if (!strcmp($1, "always"))
+                               $$ = PFCTL_SYNCOOKIES_ALWAYS;
+                       else {
+                               yyerror("illegal value for syncookies");
+                               YYERROR;
+                       }
+               }
                ;
 
 stringall      : STRING        { $$ = $1; }
@@ -5673,6 +5688,7 @@ lookup(char *s)
                { "state-policy",       STATEPOLICY},
                { "static-port",        STATICPORT},
                { "sticky-address",     STICKYADDRESS},
+               { "syncookies",         SYNCOOKIES},
                { "synproxy",           SYNPROXY},
                { "table",              TABLE},
                { "tag",                TAG},
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index 14b7f3a01657..6c689edf7c43 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -93,6 +93,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 *, u_int32_t);
+int     pfctl_load_syncookies(struct pfctl *, u_int8_t);
 int     pfctl_get_pool(int, struct pfctl_pool *, u_int32_t, u_int32_t, int,
            char *);
 void    pfctl_print_rule_counters(struct pfctl_rule *, int);
@@ -1307,15 +1308,20 @@ pfctl_show_states(int dev, const char *iface, int opts)
 int
 pfctl_show_status(int dev, int opts)
 {
-       struct pf_status status;
+       struct pf_status        status;
+       struct pfctl_syncookies cookies;
 
        if (ioctl(dev, DIOCGETSTATUS, &status)) {
                warn("DIOCGETSTATUS");
                return (-1);
        }
+       if (pfctl_get_syncookies(dev, &cookies)) {
+               warn("DIOCGETSYNCOOKIES");
+               return (-1);
+       }
        if (opts & PF_OPT_SHOWALL)
                pfctl_print_title("INFO:");
-       print_status(&status, opts);
+       print_status(&status, &cookies, opts);
        return (0);
 }
 
@@ -1861,6 +1867,10 @@ pfctl_load_options(struct pfctl *pf)
        if (pfctl_set_keepcounters(pf->dev, pf->keep_counters))
                error = 1;
 
+       /* load syncookies settings */
+       if (pfctl_load_syncookies(pf, pf->syncookies))
+               error = 1;
+
        return (error);
 }
 
@@ -2047,6 +2057,22 @@ pfctl_load_hostid(struct pfctl *pf, u_int32_t hostid)
        return (0);
 }
 
+int
+pfctl_load_syncookies(struct pfctl *pf, u_int8_t val)
+{
+       struct pfctl_syncookies cookies;
+
+       bzero(&cookies, sizeof(cookies));
+
+       cookies.mode = val ? PFCTL_SYNCOOKIES_ALWAYS : PFCTL_SYNCOOKIES_NEVER;
+
+       if (pfctl_set_syncookies(dev, &cookies)) {
+               warnx("DIOCSETSYNCOOKIES");
+               return (1);
+       }
+       return (0);
+}
+
 int
 pfctl_set_debug(struct pfctl *pf, char *d)
 {
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
index 62d4b42bd416..8991073ec693 100644
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -497,7 +497,7 @@ const char  * const pf_fcounters[FCNT_MAX+1] = FCNT_NAMES;
 const char     * const pf_scounters[FCNT_MAX+1] = FCNT_NAMES;
 
 void
-print_status(struct pf_status *s, int opts)
+print_status(struct pf_status *s, struct pfctl_syncookies *cookies, int opts)
 {
        char                    statline[80], *running;
        time_t                  runtime;
@@ -627,6 +627,11 @@ print_status(struct pf_status *s, int opts)
                        else
                                printf("%14s\n", "");
                }
+
+               printf("Syncookies\n");
+               printf("  %-25s %s\n", "mode",
+                   cookies->mode == PFCTL_SYNCOOKIES_NEVER ?
+                   "never" : "always");
        }
 }
 
diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h
index 5353900b380a..0c64238ecefa 100644
--- a/sbin/pfctl/pfctl_parser.h
+++ b/sbin/pfctl/pfctl_parser.h
@@ -100,6 +100,7 @@ struct pfctl {
        u_int32_t        hostid;
        char            *ifname;
        bool             keep_counters;
+       u_int8_t         syncookies;
 
        u_int8_t         timeout_set[PFTM_MAX];
        u_int8_t         limit_set[PF_LIMIT_MAX];
@@ -278,7 +279,7 @@ void        print_pool(struct pfctl_pool *, u_int16_t, 
u_int16_t, sa_family_t, int);
 void   print_src_node(struct pf_src_node *, int);
 void   print_rule(struct pfctl_rule *, const char *, int, int);
 void   print_tabledef(const char *, int, int, struct node_tinithead *);
-void   print_status(struct pf_status *, int);
+void   print_status(struct pf_status *, struct pfctl_syncookies *, int);
 void   print_running(struct pf_status *);
 
 int    eval_pfaltq(struct pfctl *, struct pf_altq *, struct node_queue_bw *,
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to