git: 720b82f8216d - stable/13 - pfctl: syncookie configuration
Kristof Provost
kp at FreeBSD.org
Tue Jul 27 11:46:47 UTC 2021
The branch stable/13 has been updated by kp:
URL: https://cgit.FreeBSD.org/src/commit/?id=720b82f8216d7c1f6a06993923e63df86f294069
commit 720b82f8216d7c1f6a06993923e63df86f294069
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-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 <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; }
@@ -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 *,
More information about the dev-commits-src-all
mailing list