The branch stable/12 has been updated by kp:

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

commit ff54f3762f0dfc40b079075a0dd44a84e5d9225e
Author:     Kristof Provost <[email protected]>
AuthorDate: 2021-08-16 19:55:27 +0000
Commit:     Kristof Provost <[email protected]>
CommitDate: 2021-09-06 08:06:34 +0000

    pf: Introduce nvlist variant of DIOCGETSTATUS
    
    Make it possible to extend the GETSTATUS call (e.g. when we want to add
    new counters, such as for syncookie support) by introducing an
    nvlist-based alternative.
    
    MFC after:      1 week
    Sponsored by:   Modirum MDPay
    Differential Revision:  https://reviews.freebsd.org/D31694
    
    (cherry picked from commit 2b10cf85f8684f822511d7b9377e256ab623abbc)
---
 sys/net/pfvar.h           |   1 +
 sys/netpfil/pf/pf.h       |   9 ++++
 sys/netpfil/pf/pf_ioctl.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 143 insertions(+)

diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 624456149162..0b1e3f3a27a2 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1665,6 +1665,7 @@ struct pfioc_iface {
 #define DIOCGETSTATENV _IOWR('D', 19, struct pfioc_nv)
 #define DIOCSETSTATUSIF _IOWR('D', 20, struct pfioc_if)
 #define DIOCGETSTATUS  _IOWR('D', 21, struct pf_status)
+#define DIOCGETSTATUSNV        _IOWR('D', 21, struct pfioc_nv)
 #define DIOCCLRSTATUS  _IO  ('D', 22)
 #define DIOCNATLOOK    _IOWR('D', 23, struct pfioc_natlook)
 #define DIOCSETDEBUG   _IOWR('D', 24, u_int32_t)
diff --git a/sys/netpfil/pf/pf.h b/sys/netpfil/pf/pf.h
index e030f1e59de0..319cd8164d8d 100644
--- a/sys/netpfil/pf/pf.h
+++ b/sys/netpfil/pf/pf.h
@@ -179,6 +179,15 @@ enum       { PF_ADDR_ADDRMASK, PF_ADDR_NOROUTE, 
PF_ADDR_DYNIFTL,
 #define FCNT_STATE_REMOVALS    2
 #define FCNT_MAX               3
 
+#ifdef _KERNEL
+#define FCNT_NAMES { \
+       "searches", \
+       "inserts", \
+       "removals", \
+       NULL \
+}
+#endif
+
 /* src_node operation counters */
 #define SCNT_SRC_NODE_SEARCH   0
 #define SCNT_SRC_NODE_INSERT   1
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
index 4f1786b36a30..c1cb8e0435de 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -209,6 +209,7 @@ static int           pf_killstates_row(struct 
pf_kstate_kill *,
 static int              pf_killstates_nv(struct pfioc_nv *);
 static int              pf_clearstates_nv(struct pfioc_nv *);
 static int              pf_getstate(struct pfioc_nv *);
+static int              pf_getstatus(struct pfioc_nv *);
 static int              pf_clear_tables(void);
 static void             pf_clear_srcnodes(struct pf_ksrc_node *);
 static void             pf_kill_srcnodes(struct pfioc_src_node_kill *);
@@ -2149,6 +2150,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int 
flags, struct thread *td
                case DIOCGETSTATENV:
                case DIOCSETSTATUSIF:
                case DIOCGETSTATUS:
+               case DIOCGETSTATUSNV:
                case DIOCCLRSTATUS:
                case DIOCNATLOOK:
                case DIOCSETDEBUG:
@@ -2206,6 +2208,7 @@ pfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int 
flags, struct thread *td
                case DIOCGETSTATE:
                case DIOCGETSTATENV:
                case DIOCGETSTATUS:
+               case DIOCGETSTATUSNV:
                case DIOCGETSTATES:
                case DIOCGETSTATESV2:
                case DIOCGETTIMEOUT:
@@ -3074,6 +3077,11 @@ DIOCGETSTATESV2_full:
                break;
        }
 
+       case DIOCGETSTATUSNV: {
+               error = pf_getstatus((struct pfioc_nv *)addr);
+               break;
+       }
+
        case DIOCSETSTATUSIF: {
                struct pfioc_if *pi = (struct pfioc_if *)addr;
 
@@ -4902,6 +4910,131 @@ pf_tbladdr_copyout(struct pf_addr_wrap *aw)
                kt->pfrkt_cnt : -1;
 }
 
+static int
+pf_add_status_counters(nvlist_t *nvl, const char *name, counter_u64_t 
*counters,
+    size_t number, char **names)
+{
+       nvlist_t        *nvc;
+
+       nvc = nvlist_create(0);
+       if (nvc == NULL)
+               return (ENOMEM);
+
+       for (int i = 0; i < number; i++) {
+               nvlist_append_number_array(nvc, "counters",
+                   counter_u64_fetch(counters[i]));
+               nvlist_append_string_array(nvc, "names",
+                   names[i]);
+               nvlist_append_number_array(nvc, "ids",
+                   i);
+       }
+       nvlist_add_nvlist(nvl, name, nvc);
+       nvlist_destroy(nvc);
+
+       return (0);
+}
+
+static int
+pf_getstatus(struct pfioc_nv *nv)
+{
+       nvlist_t        *nvl = NULL, *nvc = NULL;
+       void            *nvlpacked = NULL;
+       int              error;
+       struct pf_status s;
+       char *pf_reasons[PFRES_MAX+1] = PFRES_NAMES;
+       char *pf_lcounter[LCNT_MAX+1] = LCNT_NAMES;
+       char *pf_fcounter[FCNT_MAX+1] = FCNT_NAMES;
+       PF_RULES_RLOCK_TRACKER;
+
+#define ERROUT(x)      ERROUT_FUNCTION(errout, x)
+
+       PF_RULES_RLOCK();
+
+       nvl = nvlist_create(0);
+       if (nvl == NULL)
+               ERROUT(ENOMEM);
+
+       nvlist_add_bool(nvl, "running", V_pf_status.running);
+       nvlist_add_number(nvl, "since", V_pf_status.since);
+       nvlist_add_number(nvl, "debug", V_pf_status.debug);
+       nvlist_add_number(nvl, "hostid", V_pf_status.hostid);
+       nvlist_add_number(nvl, "states", V_pf_status.states);
+       nvlist_add_number(nvl, "src_nodes", V_pf_status.src_nodes);
+
+       /* counters */
+       error = pf_add_status_counters(nvl, "counters", V_pf_status.counters,
+           PFRES_MAX, pf_reasons);
+       if (error != 0)
+               ERROUT(error);
+
+       /* lcounters */
+       error = pf_add_status_counters(nvl, "lcounters", V_pf_status.lcounters,
+           LCNT_MAX, pf_lcounter);
+       if (error != 0)
+               ERROUT(error);
+
+       /* fcounters */
+       nvc = nvlist_create(0);
+       if (nvc == NULL)
+               ERROUT(ENOMEM);
+
+       for (int i = 0; i < FCNT_MAX; i++) {
+               nvlist_append_number_array(nvc, "counters",
+                   pf_counter_u64_fetch(&V_pf_status.fcounters[i]));
+               nvlist_append_string_array(nvc, "names",
+                   pf_fcounter[i]);
+               nvlist_append_number_array(nvc, "ids",
+                   i);
+       }
+       nvlist_add_nvlist(nvl, "fcounters", nvc);
+       nvlist_destroy(nvc);
+       nvc = NULL;
+
+       /* scounters */
+       error = pf_add_status_counters(nvl, "scounters", V_pf_status.scounters,
+           SCNT_MAX, pf_fcounter);
+       if (error != 0)
+               ERROUT(error);
+
+       nvlist_add_string(nvl, "ifname", V_pf_status.ifname);
+       nvlist_add_binary(nvl, "chksum", V_pf_status.pf_chksum,
+           PF_MD5_DIGEST_LENGTH);
+
+       pfi_update_status(V_pf_status.ifname, &s);
+
+       /* pcounters / bcounters */
+       for (int i = 0; i < 2; i++) {
+               for (int j = 0; j < 2; j++) {
+                       for (int k = 0; k < 2; k++) {
+                               nvlist_append_number_array(nvl, "pcounters",
+                                   s.pcounters[i][j][k]);
+                       }
+                       nvlist_append_number_array(nvl, "bcounters",
+                           s.bcounters[i][j]);
+               }
+       }
+
+       nvlpacked = nvlist_pack(nvl, &nv->len);
+       if (nvlpacked == NULL)
+               ERROUT(ENOMEM);
+
+       if (nv->size == 0)
+               ERROUT(0);
+       else if (nv->size < nv->len)
+               ERROUT(ENOSPC);
+
+       error = copyout(nvlpacked, nv->data, nv->len);
+
+#undef ERROUT
+errout:
+       PF_RULES_RUNLOCK();
+       free(nvlpacked, M_NVLIST);
+       nvlist_destroy(nvc);
+       nvlist_destroy(nvl);
+
+       return (error);
+}
+
 /*
  * XXX - Check for version missmatch!!!
  */
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to