From owner-dev-commits-src-branches@freebsd.org Tue Jul 27 11:46:47 2021 Return-Path: Delivered-To: dev-commits-src-branches@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id C1CC965DED9; Tue, 27 Jul 2021 11:46:47 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4GYw4R4bYhz3s30; Tue, 27 Jul 2021 11:46:47 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 492D21BC1; Tue, 27 Jul 2021 11:46:47 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 16RBklMh067789; Tue, 27 Jul 2021 11:46:47 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 16RBklR9067788; Tue, 27 Jul 2021 11:46:47 GMT (envelope-from git) Date: Tue, 27 Jul 2021 11:46:47 GMT Message-Id: <202107271146.16RBklR9067788@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kristof Provost Subject: git: 720b82f8216d - stable/13 - pfctl: syncookie configuration MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kp X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 720b82f8216d7c1f6a06993923e63df86f294069 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-branches@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commits to the stable branches of the FreeBSD src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 27 Jul 2021 11:46:47 -0000 The branch stable/13 has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=720b82f8216d7c1f6a06993923e63df86f294069 commit 720b82f8216d7c1f6a06993923e63df86f294069 Author: Kristof Provost AuthorDate: 2021-05-26 11:41:34 +0000 Commit: Kristof Provost CommitDate: 2021-07-27 07:43:52 +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 (cherry picked from commit c69121c473d75abab55f9ade8e8138ac09c0942c) --- 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 acd90e280b53..19fb87323060 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 number icmptype icmp6type uid gid %type tos not yesno %type probability -%type no dir af fragcache optimizer +%type no dir af fragcache optimizer syncookie_val %type sourcetrack flush unaryop statelock %type action nataction natpasslog scrubaction %type 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; } @@ -5671,6 +5686,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 b4a1cde967bd..e3efd20d3822 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 *,