git: ff54f3762f0d - stable/12 - pf: Introduce nvlist variant of DIOCGETSTATUS

Kristof Provost kp at FreeBSD.org
Mon Sep 6 10:39:21 UTC 2021


The branch stable/12 has been updated by kp:

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

commit ff54f3762f0dfc40b079075a0dd44a84e5d9225e
Author:     Kristof Provost <kp at FreeBSD.org>
AuthorDate: 2021-08-16 19:55:27 +0000
Commit:     Kristof Provost <kp at FreeBSD.org>
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!!!
  */


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