git: d1d99d7575da - stable/13 - libpfctl: Implement DIOCGETSTATUS wrappers

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


The branch stable/13 has been updated by kp:

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

commit d1d99d7575dac949030a065c952651514c8bf50f
Author:     Kristof Provost <kp at FreeBSD.org>
AuthorDate: 2021-08-26 15:06:15 +0000
Commit:     Kristof Provost <kp at FreeBSD.org>
CommitDate: 2021-09-06 08:06:33 +0000

    libpfctl: Implement DIOCGETSTATUS wrappers
    
    MFC after:      1 week
    Sponsored by:   Modirum MDPay
    Differential Revision:  https://reviews.freebsd.org/D31696
    
    (cherry picked from commit 46fb68b1de49c8d235024374b71c1249af9e62ef)
---
 lib/libpfctl/libpfctl.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++
 lib/libpfctl/libpfctl.h |  30 +++++++++++++
 2 files changed, 145 insertions(+)

diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
index 7e6bc1b14a2a..3d52502f9ba8 100644
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -121,6 +121,121 @@ pf_nvuint_64_array(const nvlist_t *nvl, const char *name, size_t maxelems,
 		*nelems = elems;
 }
 
+static void
+_pfctl_get_status_counters(const nvlist_t *nvl,
+    struct pfctl_status_counters *counters)
+{
+	const uint64_t		*ids, *counts;
+	const char *const	*names;
+	size_t id_len, counter_len, names_len;
+
+	ids = nvlist_get_number_array(nvl, "ids", &id_len);
+	counts = nvlist_get_number_array(nvl, "counters", &counter_len);
+	names = nvlist_get_string_array(nvl, "names", &names_len);
+	assert(id_len == counter_len);
+	assert(counter_len == names_len);
+
+	TAILQ_INIT(counters);
+
+	for (size_t i = 0; i < id_len; i++) {
+		struct pfctl_status_counter *c;
+
+		c = malloc(sizeof(*c));
+
+		c->id = ids[i];
+		c->counter = counts[i];
+		c->name = strdup(names[i]);
+
+		TAILQ_INSERT_TAIL(counters, c, entry);
+	}
+}
+
+struct pfctl_status *
+pfctl_get_status(int dev)
+{
+	struct pfioc_nv	 nv;
+	struct pfctl_status	*status;
+	nvlist_t	*nvl;
+	size_t		 len;
+	const void	*chksum;
+
+	status = calloc(1, sizeof(*status));
+	if (status == NULL)
+		return (NULL);
+
+	nv.data = malloc(4096);
+	nv.len = nv.size = 4096;
+
+	if (ioctl(dev, DIOCGETSTATUSNV, &nv)) {
+		free(nv.data);
+		free(status);
+		return (NULL);
+	}
+
+	nvl = nvlist_unpack(nv.data, nv.len, 0);
+	free(nv.data);
+	if (nvl == NULL) {
+		free(status);
+		return (NULL);
+	}
+
+	status->running = nvlist_get_bool(nvl, "running");
+	status->since = nvlist_get_number(nvl, "since");
+	status->debug = nvlist_get_number(nvl, "debug");
+	status->hostid = nvlist_get_number(nvl, "hostid");
+	status->states = nvlist_get_number(nvl, "states");
+	status->src_nodes = nvlist_get_number(nvl, "src_nodes");
+
+	strlcpy(status->ifname, nvlist_get_string(nvl, "ifname"),
+	    IFNAMSIZ);
+	chksum = nvlist_get_binary(nvl, "chksum", &len);
+	assert(len == PF_MD5_DIGEST_LENGTH);
+	memcpy(status->pf_chksum, chksum, len);
+
+	_pfctl_get_status_counters(nvlist_get_nvlist(nvl, "counters"),
+	    &status->counters);
+	_pfctl_get_status_counters(nvlist_get_nvlist(nvl, "lcounters"),
+	    &status->lcounters);
+	_pfctl_get_status_counters(nvlist_get_nvlist(nvl, "fcounters"),
+	    &status->fcounters);
+	_pfctl_get_status_counters(nvlist_get_nvlist(nvl, "scounters"),
+	    &status->scounters);
+
+	pf_nvuint_64_array(nvl, "pcounters", 2 * 2 * 3,
+	    (uint64_t *)status->pcounters, NULL);
+	pf_nvuint_64_array(nvl, "bcounters", 2 * 2,
+	    (uint64_t *)status->bcounters, NULL);
+
+	nvlist_destroy(nvl);
+
+	return (status);
+}
+
+void
+pfctl_free_status(struct pfctl_status *status)
+{
+	struct pfctl_status_counter *c, *tmp;
+
+	TAILQ_FOREACH_SAFE(c, &status->counters, entry, tmp) {
+		free(c->name);
+		free(c);
+	}
+	TAILQ_FOREACH_SAFE(c, &status->lcounters, entry, tmp) {
+		free(c->name);
+		free(c);
+	}
+	TAILQ_FOREACH_SAFE(c, &status->fcounters, entry, tmp) {
+		free(c->name);
+		free(c);
+	}
+	TAILQ_FOREACH_SAFE(c, &status->scounters, entry, tmp) {
+		free(c->name);
+		free(c);
+	}
+
+	free(status);
+}
+
 static void
 pfctl_nv_add_addr(nvlist_t *nvparent, const char *name,
     const struct pf_addr *addr)
diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h
index d57241dd59fd..70de7627f0a6 100644
--- a/lib/libpfctl/libpfctl.h
+++ b/lib/libpfctl/libpfctl.h
@@ -38,6 +38,33 @@
 
 struct pfctl_anchor;
 
+struct pfctl_status_counter {
+	uint64_t	 id;
+	uint64_t	 counter;
+	char		*name;
+
+	TAILQ_ENTRY(pfctl_status_counter) entry;
+};
+TAILQ_HEAD(pfctl_status_counters, pfctl_status_counter);
+
+struct pfctl_status {
+	bool		running;
+	uint32_t	since;
+	uint32_t	debug;
+	uint32_t	hostid;
+	uint64_t	states;
+	uint64_t	src_nodes;
+	char		ifname[IFNAMSIZ];
+	uint8_t		pf_chksum[PF_MD5_DIGEST_LENGTH];
+
+	struct pfctl_status_counters	 counters;
+	struct pfctl_status_counters	 lcounters;
+	struct pfctl_status_counters	 fcounters;
+	struct pfctl_status_counters	 scounters;
+	uint64_t	pcounters[2][2][3];
+	uint64_t	bcounters[2][2];
+};
+
 struct pfctl_pool {
 	struct pf_palist	 list;
 	struct pf_pooladdr	*cur;
@@ -253,6 +280,9 @@ struct pfctl_syncookies {
 	enum pfctl_syncookies_mode	mode;
 };
 
+struct pfctl_status* pfctl_get_status(int dev);
+void	pfctl_free_status(struct pfctl_status *status);
+
 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);


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