git: c69121c473d7 - main - pfctl: syncookie configuration

Kristof Provost kp at FreeBSD.org
Tue Jul 20 08:36:57 UTC 2021


The branch main has been updated by kp:

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

commit c69121c473d75abab55f9ade8e8138ac09c0942c
Author:     Kristof Provost <kp at FreeBSD.org>
AuthorDate: 2021-05-26 11:41:34 +0000
Commit:     Kristof Provost <kp at FreeBSD.org>
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 *,


More information about the dev-commits-src-all mailing list