The branch main has been updated by kp:

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

commit 231e83d3422ff58fe94de8375a9532a1726056ed
Author:     Kristof Provost <k...@freebsd.org>
AuthorDate: 2021-05-26 08:18:19 +0000
Commit:     Kristof Provost <k...@freebsd.org>
CommitDate: 2021-07-20 08:36:13 +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
---
 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 767c47999940..35f906a8cbb2 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 f98895da3e77..a9f5b2c18041 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -275,6 +275,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)
 {
@@ -2136,6 +2144,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:
@@ -2183,6 +2192,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:
@@ -4538,6 +4548,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)
_______________________________________________
dev-commits-src-main@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-main
To unsubscribe, send any mail to "dev-commits-src-main-unsubscr...@freebsd.org"

Reply via email to