Date: Tue, 27 Jul 2021 11:46:46 GMT From: Kristof Provost <kp@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: 2987a3643be7 - stable/13 - pf: syncookie ioctl interface Message-ID: <202107271146.16RBkkrS067740@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=2987a3643be7d143c1ff22be3a7e4f485a7acc1f commit 2987a3643be7d143c1ff22be3a7e4f485a7acc1f Author: Kristof Provost <kp@FreeBSD.org> AuthorDate: 2021-05-26 08:18:19 +0000 Commit: Kristof Provost <kp@FreeBSD.org> CommitDate: 2021-07-27 07:42:52 +0000 pf: syncookie ioctl interface Kernel side implementation to allow switching between on and off modes, and allow this configuration to be retrieved. MFC after: 1 week Sponsored by: Modirum MDPay Differential Revision: https://reviews.freebsd.org/D31139 (cherry picked from commit 231e83d3422ff58fe94de8375a9532a1726056ed) --- sys/net/pfvar.h | 2 +- sys/netpfil/pf/pf_ioctl.c | 18 +++++++++ sys/netpfil/pf/pf_syncookies.c | 84 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 1 deletion(-) diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 50634f39a549..b4a788436147 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1572,6 +1572,7 @@ struct pf_idhash { struct mtx lock; }; +extern u_long pf_ioctl_maxcount; extern u_long pf_hashmask; extern u_long pf_srchashmask; #define PF_HASHSIZ (131072) @@ -1840,7 +1841,6 @@ void pf_send_tcp(const struct pf_krule *, sa_family_t, u_int16_t); void pf_syncookies_init(void); -int pf_syncookies_setmode(u_int8_t); int pf_get_syncookies(struct pfioc_nv *); int pf_set_syncookies(struct pfioc_nv *); int pf_synflood_check(struct pf_pdesc *); diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c index d5b33a48a57c..96eb31b00ffb 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -276,6 +276,14 @@ pflog_packet_t *pflog_packet_ptr = NULL; extern u_long pf_ioctl_maxcount; +#define ERROUT_FUNCTION(target, x) \ + do { \ + error = (x); \ + SDT_PROBE3(pf, ioctl, function, error, __func__, error, \ + __LINE__); \ + goto target; \ + } while (0) + static void pfattach_vnet(void) { @@ -2137,6 +2145,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td case DIOCOSFPGET: case DIOCGETSRCNODES: case DIOCCLRSRCNODES: + case DIOCGETSYNCOOKIES: case DIOCIGETIFACES: case DIOCGIFSPEEDV0: case DIOCGIFSPEEDV1: @@ -2184,6 +2193,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td case DIOCRTSTADDRS: case DIOCOSFPGET: case DIOCGETSRCNODES: + case DIOCGETSYNCOOKIES: case DIOCIGETIFACES: case DIOCGIFSPEEDV1: case DIOCGIFSPEEDV0: @@ -4539,6 +4549,14 @@ DIOCCHANGEADDR_error: error = pf_keepcounters((struct pfioc_nv *)addr); break; + case DIOCGETSYNCOOKIES: + error = pf_get_syncookies((struct pfioc_nv *)addr); + break; + + case DIOCSETSYNCOOKIES: + error = pf_set_syncookies((struct pfioc_nv *)addr); + break; + case DIOCSETHOSTID: { u_int32_t *hostid = (u_int32_t *)addr; diff --git a/sys/netpfil/pf/pf_syncookies.c b/sys/netpfil/pf/pf_syncookies.c index 0071bab0d7d5..d51f89fb47d4 100644 --- a/sys/netpfil/pf/pf_syncookies.c +++ b/sys/netpfil/pf/pf_syncookies.c @@ -110,6 +110,7 @@ struct pf_syncookie_status { VNET_DEFINE_STATIC(struct pf_syncookie_status, pf_syncookie_status); #define V_pf_syncookie_status VNET(pf_syncookie_status) +static int pf_syncookies_setmode(u_int8_t); void pf_syncookie_rotate(void *); void pf_syncookie_newkey(void); uint32_t pf_syncookie_mac(struct pf_pdesc *, union pf_syncookie, @@ -127,6 +128,89 @@ pf_syncookies_init(void) } int +pf_get_syncookies(struct pfioc_nv *nv) +{ + nvlist_t *nvl = NULL; + void *nvlpacked = NULL; + + nvl = nvlist_create(0); + if (nvl == NULL) + return (ENOMEM); + + nvlist_add_bool(nvl, "enabled", + V_pf_status.syncookies_mode != PF_SYNCOOKIES_NEVER); + nvlist_add_bool(nvl, "adaptive", false); + + nvlpacked = nvlist_pack(nvl, &nv->len); + if (nvlpacked == NULL) { + nvlist_destroy(nvl); + return (ENOMEM); + } + if (nv->size == 0) { + nvlist_destroy(nvl); + free(nvlpacked, M_TEMP); + return (0); + } else if (nv->size < nv->len) { + nvlist_destroy(nvl); + free(nvlpacked, M_TEMP); + return (ENOSPC); + } + + return (copyout(nvlpacked, nv->data, nv->len)); +} + +int +pf_set_syncookies(struct pfioc_nv *nv) +{ + nvlist_t *nvl = NULL; + void *nvlpacked = NULL; + int error; + bool enabled, adaptive; + + if (nv->len > pf_ioctl_maxcount) + return (ENOMEM); + + nvlpacked = malloc(nv->len, M_TEMP, M_WAITOK); + if (nvlpacked == NULL) + return (ENOMEM); + + error = copyin(nv->data, nvlpacked, nv->len); + if (error) { + free(nvlpacked, M_TEMP); + return (error); + } + + nvl = nvlist_unpack(nvlpacked, nv->len, 0); + if (nvl == NULL) { + free(nvlpacked, M_TEMP); + return (EBADMSG); + } + + if (! nvlist_exists_bool(nvl, "enabled") + || ! nvlist_exists_bool(nvl, "adaptive")) { + nvlist_destroy(nvl); + free(nvlpacked, M_TEMP); + return (EBADMSG); + } + + enabled = nvlist_get_bool(nvl, "enabled"); + adaptive = nvlist_get_bool(nvl, "adaptive"); + + if (adaptive) { + nvlist_destroy(nvl); + free(nvlpacked, M_TEMP); + return (ENOTSUP); + } + + PF_RULES_WLOCK(); + error = pf_syncookies_setmode(enabled ? + PF_SYNCOOKIES_ALWAYS : PF_SYNCOOKIES_NEVER); + PF_RULES_WUNLOCK(); + + return (error); +} + +static int pf_syncookies_setmode(u_int8_t mode) { if (mode > PF_SYNCOOKIES_MODE_MAX)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202107271146.16RBkkrS067740>