Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 29 Apr 2024 14:36:50 GMT
From:      Kristof Provost <kp@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 5824df8d991c - main - pf: convert DIOCGETSTATUS to netlink
Message-ID:  <202404291436.43TEaoh6080646@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by kp:

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

commit 5824df8d991c32def616c51994161e60e5b78948
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2024-03-23 06:31:51 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2024-04-29 14:32:23 +0000

    pf: convert DIOCGETSTATUS to netlink
    
    Introduce pfctl_get_status_h() because we need the pfctl_handle. In this variant
    use netlink to obtain the information.
    
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
---
 contrib/pf/ftp-proxy/filter.c             |   2 +-
 contrib/pf/tftp-proxy/filter.c            |   2 +-
 lib/libpfctl/libpfctl.c                   | 147 ++++++++++++++++++++++++++++++
 lib/libpfctl/libpfctl.h                   |   1 +
 sbin/pfctl/pfctl.c                        |   4 +-
 sys/netlink/netlink_message_writer.h      |   6 ++
 sys/netlink/netlink_snl.h                 |  11 +++
 sys/netpfil/pf/pf_nl.c                    | 114 ++++++++++++++++++++++-
 sys/netpfil/pf/pf_nl.h                    |  29 ++++++
 usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c |  35 +++----
 10 files changed, 329 insertions(+), 22 deletions(-)

diff --git a/contrib/pf/ftp-proxy/filter.c b/contrib/pf/ftp-proxy/filter.c
index 3bad5feb4be4..7893be97f9b2 100644
--- a/contrib/pf/ftp-proxy/filter.c
+++ b/contrib/pf/ftp-proxy/filter.c
@@ -183,7 +183,7 @@ init_filter(const char *opt_qname, const char *opt_tagname, int opt_verbose)
 	pfh = pfctl_open(PF_DEVICE);
 	if (pfh == NULL)
 		err(1, "pfctl_open");
-	status = pfctl_get_status(pfctl_fd(pfh));
+	status = pfctl_get_status_h(pfh);
 	if (status == NULL)
 		err(1, "DIOCGETSTATUS");
 	if (!status->running)
diff --git a/contrib/pf/tftp-proxy/filter.c b/contrib/pf/tftp-proxy/filter.c
index b69247caf04f..1e6d54303996 100644
--- a/contrib/pf/tftp-proxy/filter.c
+++ b/contrib/pf/tftp-proxy/filter.c
@@ -188,7 +188,7 @@ init_filter(char *opt_qname, int opt_verbose)
 		syslog(LOG_ERR, "can't pfctl_open()");
 		exit(1);
 	}
-	status = pfctl_get_status(pfctl_fd(pfh));
+	status = pfctl_get_status_h(pfh);
 	if (status == NULL) {
 		syslog(LOG_ERR, "DIOCGETSTATUS");
 		exit(1);
diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
index 5b9500980996..6da3b6969107 100644
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -287,6 +287,153 @@ _pfctl_get_status_counters(const nvlist_t *nvl,
 	}
 }
 
+#define	_OUT(_field)	offsetof(struct pfctl_status_counter, _field)
+static const struct snl_attr_parser ap_counter[] = {
+	{ .type = PF_C_COUNTER, .off = _OUT(counter), .cb = snl_attr_get_uint64 },
+	{ .type = PF_C_NAME, .off = _OUT(name), .cb = snl_attr_get_string },
+	{ .type = PF_C_ID, .off = _OUT(id), .cb = snl_attr_get_uint32 },
+};
+SNL_DECLARE_ATTR_PARSER(counter_parser, ap_counter);
+#undef _OUT
+
+static bool
+snl_attr_get_counters(struct snl_state *ss, struct nlattr *nla,
+    const void *arg __unused, void *target)
+{
+	struct pfctl_status_counter counter = {};
+	struct pfctl_status_counter *c;
+	bool error;
+
+	error = snl_parse_header(ss, NLA_DATA(nla), NLA_DATA_LEN(nla), &counter_parser, &counter);
+	if (! error)
+		return (error);
+
+	c = malloc(sizeof(*c));
+	if (c == NULL)
+		return (false);
+
+	c->id = counter.id;
+	c->counter = counter.counter;
+	c->name = strdup(counter.name);
+
+	TAILQ_INSERT_TAIL((struct pfctl_status_counters *)target, c, entry);
+
+	return (error);
+}
+
+struct snl_uint64_array {
+	uint64_t *array;
+	size_t count;
+	size_t max;
+};
+static bool
+snl_attr_get_uint64_element(struct snl_state *ss, struct nlattr *nla,
+    const void *arg, void *target)
+{
+	bool error;
+	uint64_t value;
+	struct snl_uint64_array *t = (struct snl_uint64_array *)target;
+
+	if (t->count >= t->max)
+		return (false);
+
+	error = snl_attr_get_uint64(ss, nla, arg, &value);
+	if (! error)
+		return (error);
+
+	t->array[t->count++] = value;
+
+	return (true);
+}
+
+static const struct snl_attr_parser ap_array[] = {
+	{ .cb = snl_attr_get_uint64_element },
+};
+SNL_DECLARE_ATTR_PARSER(array_parser, ap_array);
+static bool
+snl_attr_get_uint64_array(struct snl_state *ss, struct nlattr *nla,
+    const void *arg, void *target)
+{
+	struct snl_uint64_array a = {
+		.array = target,
+		.count = 0,
+		.max = (size_t)arg,
+	};
+	bool error;
+
+	error = snl_parse_header(ss, NLA_DATA(nla), NLA_DATA_LEN(nla), &array_parser, &a);
+	if (! error)
+		return (error);
+
+	return (true);
+}
+
+#define	_OUT(_field)	offsetof(struct pfctl_status, _field)
+static const struct snl_attr_parser ap_getstatus[] = {
+	{ .type = PF_GS_IFNAME, .off = _OUT(ifname), .arg_u32 = IFNAMSIZ, .cb = snl_attr_copy_string },
+	{ .type = PF_GS_RUNNING, .off = _OUT(running), .cb = snl_attr_get_bool },
+	{ .type = PF_GS_SINCE, .off = _OUT(since), .cb = snl_attr_get_uint32 },
+	{ .type = PF_GS_DEBUG, .off = _OUT(debug), .cb = snl_attr_get_uint32 },
+	{ .type = PF_GS_HOSTID, .off = _OUT(hostid), .cb = snl_attr_get_uint32 },
+	{ .type = PF_GS_STATES, .off = _OUT(states), .cb = snl_attr_get_uint32 },
+	{ .type = PF_GS_SRC_NODES, .off = _OUT(src_nodes), .cb = snl_attr_get_uint32 },
+	{ .type = PF_GS_REASSEMBLE, .off = _OUT(reass), .cb = snl_attr_get_uint32 },
+	{ .type = PF_GS_SYNCOOKIES_ACTIVE, .off = _OUT(syncookies_active), .cb = snl_attr_get_uint32 },
+	{ .type = PF_GS_COUNTERS, .off = _OUT(counters), .cb = snl_attr_get_counters },
+	{ .type = PF_GS_LCOUNTERS, .off = _OUT(lcounters), .cb = snl_attr_get_counters },
+	{ .type = PF_GS_FCOUNTERS, .off = _OUT(fcounters), .cb = snl_attr_get_counters },
+	{ .type = PF_GS_SCOUNTERS, .off = _OUT(scounters), .cb = snl_attr_get_counters },
+	{ .type = PF_GS_CHKSUM, .off = _OUT(pf_chksum), .arg_u32 = PF_MD5_DIGEST_LENGTH, .cb = snl_attr_get_bytes },
+	{ .type = PF_GS_BCOUNTERS, .off = _OUT(bcounters), .arg_u32 = 2 * 2, .cb = snl_attr_get_uint64_array },
+	{ .type = PF_GS_PCOUNTERS, .off = _OUT(pcounters), .arg_u32 = 2 * 2 * 2, .cb = snl_attr_get_uint64_array },
+};
+static struct snl_field_parser fp_getstatus[] = {};
+SNL_DECLARE_PARSER(getstatus_parser, struct genlmsghdr, fp_getstatus, ap_getstatus);
+#undef _OUT
+
+struct pfctl_status *
+pfctl_get_status_h(struct pfctl_handle *h __unused)
+{
+	struct pfctl_status	*status;
+	struct snl_errmsg_data e = {};
+	struct nlmsghdr *hdr;
+	struct snl_writer nw;
+	uint32_t seq_id;
+	int family_id;
+
+	family_id = snl_get_genl_family(&h->ss, PFNL_FAMILY_NAME);
+	if (family_id == 0)
+		return (NULL);
+
+	snl_init_writer(&h->ss, &nw);
+	hdr = snl_create_genl_msg_request(&nw, family_id, PFNL_CMD_GET_STATUS);
+	hdr->nlmsg_flags |= NLM_F_DUMP;
+
+	hdr = snl_finalize_msg(&nw);
+	if (hdr == NULL) {
+		return (NULL);
+	}
+
+	seq_id = hdr->nlmsg_seq;
+	if (! snl_send_message(&h->ss, hdr))
+		return (NULL);
+
+	status = calloc(1, sizeof(*status));
+	if (status == NULL)
+		return (NULL);
+	TAILQ_INIT(&status->counters);
+	TAILQ_INIT(&status->lcounters);
+	TAILQ_INIT(&status->fcounters);
+	TAILQ_INIT(&status->scounters);
+
+	while ((hdr = snl_read_reply_multi(&h->ss, seq_id, &e)) != NULL) {
+		if (! snl_parse_nlmsg(&h->ss, hdr, &getstatus_parser, status))
+			continue;
+	}
+
+	return (status);
+}
+
 struct pfctl_status *
 pfctl_get_status(int dev)
 {
diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h
index a290fa45501a..2937a36a8a47 100644
--- a/lib/libpfctl/libpfctl.h
+++ b/lib/libpfctl/libpfctl.h
@@ -393,6 +393,7 @@ void	pfctl_close(struct pfctl_handle *);
 int	pfctl_fd(struct pfctl_handle *);
 
 int	pfctl_startstop(struct pfctl_handle *h, int start);
+struct pfctl_status* pfctl_get_status_h(struct pfctl_handle *h);
 struct pfctl_status* pfctl_get_status(int dev);
 uint64_t pfctl_status_counter(struct pfctl_status *status, int id);
 uint64_t pfctl_status_lcounter(struct pfctl_status *status, int id);
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index 8d59871701f8..17901b04a130 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -1578,7 +1578,7 @@ pfctl_show_status(int dev, int opts)
 	struct pfctl_status	*status;
 	struct pfctl_syncookies	cookies;
 
-	if ((status = pfctl_get_status(dev)) == NULL) {
+	if ((status = pfctl_get_status_h(pfh)) == NULL) {
 		warn("DIOCGETSTATUS");
 		return (-1);
 	}
@@ -1600,7 +1600,7 @@ pfctl_show_running(int dev)
 	struct pfctl_status *status;
 	int running;
 
-	if ((status = pfctl_get_status(dev)) == NULL) {
+	if ((status = pfctl_get_status_h(pfh)) == NULL) {
 		warn("DIOCGETSTATUS");
 		return (-1);
 	}
diff --git a/sys/netlink/netlink_message_writer.h b/sys/netlink/netlink_message_writer.h
index 28f3fb78018c..cb771cf93e53 100644
--- a/sys/netlink/netlink_message_writer.h
+++ b/sys/netlink/netlink_message_writer.h
@@ -225,6 +225,12 @@ nlattr_add_raw(struct nl_writer *nw, const struct nlattr *nla_src)
 	return (nlattr_add(nw, nla_src->nla_type, attr_len, (const void *)(nla_src + 1)));
 }
 
+static inline bool
+nlattr_add_bool(struct nl_writer *nw, int attrtype, bool value)
+{
+	return (nlattr_add(nw, attrtype, sizeof(bool), &value));
+}
+
 static inline bool
 nlattr_add_u8(struct nl_writer *nw, int attrtype, uint8_t value)
 {
diff --git a/sys/netlink/netlink_snl.h b/sys/netlink/netlink_snl.h
index 6553a391a8f5..7550800bb0f7 100644
--- a/sys/netlink/netlink_snl.h
+++ b/sys/netlink/netlink_snl.h
@@ -537,6 +537,17 @@ snl_attr_get_bytes(struct snl_state *ss __unused, struct nlattr *nla, const void
 	return (true);
 }
 
+static inline bool
+snl_attr_get_bool(struct snl_state *ss __unused, struct nlattr *nla,
+    const void *arg __unused, void *target)
+{
+	if (NLA_DATA_LEN(nla) == sizeof(bool)) {
+		*((bool *)target) = *((const bool *)NLA_DATA_CONST(nla));
+		return (true);
+	}
+	return (false);
+}
+
 static inline bool
 snl_attr_get_uint8(struct snl_state *ss __unused, struct nlattr *nla,
     const void *arg __unused, void *target)
diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c
index 5f33e49b4a2e..307e1ca1689d 100644
--- a/sys/netpfil/pf/pf_nl.c
+++ b/sys/netpfil/pf/pf_nl.c
@@ -1109,6 +1109,111 @@ pf_handle_set_statusif(struct nlmsghdr *hdr, struct nl_pstate *npt)
 	return (0);
 }
 
+static bool
+nlattr_add_counters(struct nl_writer *nw, int attr, size_t number, char **names,
+    counter_u64_t *counters)
+{
+	for (int i = 0; i < number; i++) {
+		int off = nlattr_add_nested(nw, attr);
+		nlattr_add_u32(nw, PF_C_ID, i);
+		nlattr_add_string(nw, PF_C_NAME, names[i]);
+		nlattr_add_u64(nw, PF_C_COUNTER, counter_u64_fetch(counters[i]));
+		nlattr_set_len(nw, off);
+	}
+
+	return (true);
+}
+
+static bool
+nlattr_add_fcounters(struct nl_writer *nw, int attr, size_t number, char **names,
+    struct pf_counter_u64 *counters)
+{
+	for (int i = 0; i < number; i++) {
+		int off = nlattr_add_nested(nw, attr);
+		nlattr_add_u32(nw, PF_C_ID, i);
+		nlattr_add_string(nw, PF_C_NAME, names[i]);
+		nlattr_add_u64(nw, PF_C_COUNTER, pf_counter_u64_fetch(&counters[i]));
+		nlattr_set_len(nw, off);
+	}
+
+	return (true);
+}
+
+static bool
+nlattr_add_u64_array(struct nl_writer *nw, int attr, size_t number, uint64_t *array)
+{
+	int off = nlattr_add_nested(nw, attr);
+
+	for (size_t i = 0; i < number; i++)
+		nlattr_add_u64(nw, 0, array[i]);
+
+	nlattr_set_len(nw, off);
+
+	return (true);
+}
+
+static int
+pf_handle_get_status(struct nlmsghdr *hdr, struct nl_pstate *npt)
+{
+	struct pf_status s;
+	struct nl_writer *nw = npt->nw;
+	struct genlmsghdr *ghdr_new;
+	char *pf_reasons[PFRES_MAX+1] = PFRES_NAMES;
+	char *pf_lcounter[KLCNT_MAX+1] = KLCNT_NAMES;
+	char *pf_fcounter[FCNT_MAX+1] = FCNT_NAMES;
+	int error;
+
+	PF_RULES_RLOCK_TRACKER;
+
+	if (!nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr)))
+		return (ENOMEM);
+
+	ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr);
+	ghdr_new->cmd = PFNL_CMD_GET_STATUS;
+	ghdr_new->version = 0;
+	ghdr_new->reserved = 0;
+
+	PF_RULES_RLOCK();
+
+	nlattr_add_string(nw, PF_GS_IFNAME, V_pf_status.ifname);
+	nlattr_add_bool(nw, PF_GS_RUNNING, V_pf_status.running);
+	nlattr_add_u32(nw, PF_GS_SINCE, V_pf_status.since);
+	nlattr_add_u32(nw, PF_GS_DEBUG, V_pf_status.debug);
+	nlattr_add_u32(nw, PF_GS_HOSTID, ntohl(V_pf_status.hostid));
+	nlattr_add_u32(nw, PF_GS_STATES, V_pf_status.states);
+	nlattr_add_u32(nw, PF_GS_SRC_NODES, V_pf_status.src_nodes);
+	nlattr_add_u32(nw, PF_GS_REASSEMBLE, V_pf_status.reass);
+	nlattr_add_u32(nw, PF_GS_SYNCOOKIES_ACTIVE, V_pf_status.syncookies_active);
+
+	nlattr_add_counters(nw, PF_GS_COUNTERS, PFRES_MAX, pf_reasons,
+	    V_pf_status.counters);
+	nlattr_add_counters(nw, PF_GS_LCOUNTERS, KLCNT_MAX, pf_lcounter,
+	    V_pf_status.lcounters);
+	nlattr_add_fcounters(nw, PF_GS_FCOUNTERS, FCNT_MAX, pf_fcounter,
+	    V_pf_status.fcounters);
+	nlattr_add_counters(nw, PF_GS_SCOUNTERS, SCNT_MAX, pf_fcounter,
+	    V_pf_status.scounters);
+
+	pfi_update_status(V_pf_status.ifname, &s);
+	nlattr_add_u64_array(nw, PF_GS_BCOUNTERS, 2 * 2, (uint64_t *)s.bcounters);
+	nlattr_add_u64_array(nw, PF_GS_PCOUNTERS, 2 * 2 * 2, (uint64_t *)s.pcounters);
+
+	nlattr_add(nw, PF_GS_CHKSUM, PF_MD5_DIGEST_LENGTH, V_pf_status.pf_chksum);
+
+	PF_RULES_RUNLOCK();
+
+	if (!nlmsg_end(nw)) {
+		error = ENOMEM;
+		goto out;
+	}
+
+	return (0);
+
+out:
+	nlmsg_abort(nw);
+	return (error);
+}
+
 static const struct nlhdr_parser *all_parsers[] = {
 	&state_parser,
 	&addrule_parser,
@@ -1189,7 +1294,14 @@ static const struct genl_cmd pf_cmds[] = {
 		.cmd_cb = pf_handle_set_statusif,
 		.cmd_flags = GENL_CMD_CAP_DO | GENL_CMD_CAP_HASPOL,
 		.cmd_priv = PRIV_NETINET_PF,
-	}
+	},
+	{
+		.cmd_num = PFNL_CMD_GET_STATUS,
+		.cmd_name = "GETSTATUS",
+		.cmd_cb = pf_handle_get_status,
+		.cmd_flags = GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
+		.cmd_priv = PRIV_NETINET_PF,
+	},
 };
 
 void
diff --git a/sys/netpfil/pf/pf_nl.h b/sys/netpfil/pf/pf_nl.h
index c44e331722b7..e486e9781b2e 100644
--- a/sys/netpfil/pf/pf_nl.h
+++ b/sys/netpfil/pf/pf_nl.h
@@ -46,6 +46,7 @@ enum {
 	PFNL_CMD_CLRSTATES = 8,
 	PFNL_CMD_KILLSTATES = 9,
 	PFNL_CMD_SET_STATUSIF = 10,
+	PFNL_CMD_GET_STATUS = 11,
 	__PFNL_CMD_MAX,
 };
 #define PFNL_CMD_MAX (__PFNL_CMD_MAX -1)
@@ -286,6 +287,34 @@ enum pf_set_statusif_types_t {
 	PF_SS_UNSPEC,
 	PF_SS_IFNAME		= 1, /* string */
 };
+
+enum pf_counter_types_t {
+	PF_C_UNSPEC,
+	PF_C_COUNTER		= 1, /* u64 */
+	PF_C_NAME		= 2, /* string */
+	PF_C_ID			= 3, /* u32 */
+};
+
+enum pf_get_status_types_t {
+	PF_GS_UNSPEC,
+	PF_GS_IFNAME		= 1, /* string */
+	PF_GS_RUNNING		= 2, /* bool */
+	PF_GS_SINCE		= 3, /* u32 */
+	PF_GS_DEBUG		= 4, /* u32 */
+	PF_GS_HOSTID		= 5, /* u32 */
+	PF_GS_STATES		= 6, /* u32 */
+	PF_GS_SRC_NODES		= 7, /* u32 */
+	PF_GS_REASSEMBLE	= 8, /* u32 */
+	PF_GS_SYNCOOKIES_ACTIVE	= 9, /* bool */
+	PF_GS_COUNTERS		= 10, /* nested, */
+	PF_GS_LCOUNTERS		= 11, /* nested, */
+	PF_GS_FCOUNTERS		= 12, /* nested, */
+	PF_GS_SCOUNTERS		= 13, /* nested, */
+	PF_GS_CHKSUM		= 14, /* byte array */
+	PF_GS_PCOUNTERS		= 15, /* u64 array */
+	PF_GS_BCOUNTERS		= 16, /* u64 array */
+};
+
 #ifdef _KERNEL
 
 void	pf_nl_register(void);
diff --git a/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c b/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c
index bb064dd549d2..e618683845be 100644
--- a/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c
+++ b/usr.sbin/bsnmpd/modules/snmp_pf/pf_snmp.c
@@ -50,7 +50,7 @@
 
 struct lmodule *module;
 
-static int dev = -1;
+static struct pfctl_handle *pfh;
 static int started;
 static uint64_t pf_tick;
 
@@ -341,7 +341,7 @@ pf_limits(struct snmp_context __unused *ctx, struct snmp_value *val,
 				return (SNMP_ERR_NOSUCHNAME);
 		}
 
-		if (ioctl(dev, DIOCGETLIMIT, &pl)) {
+		if (ioctl(pfctl_fd(pfh), DIOCGETLIMIT, &pl)) {
 			syslog(LOG_ERR, "pf_limits(): ioctl(): %s",
 			    strerror(errno));
 			return (SNMP_ERR_GENERR);
@@ -431,7 +431,7 @@ pf_timeouts(struct snmp_context __unused *ctx, struct snmp_value *val,
 				return (SNMP_ERR_NOSUCHNAME);
 		}
 
-		if (ioctl(dev, DIOCGETTIMEOUT, &pt)) {
+		if (ioctl(pfctl_fd(pfh), DIOCGETTIMEOUT, &pt)) {
 			syslog(LOG_ERR, "pf_timeouts(): ioctl(): %s",
 			    strerror(errno));
 			return (SNMP_ERR_GENERR);
@@ -1174,7 +1174,7 @@ pfi_refresh(void)
 		io.pfiio_size = numifs;
 		io.pfiio_buffer = p;
 
-		if (ioctl(dev, DIOCIGETIFACES, &io)) {
+		if (ioctl(pfctl_fd(pfh), DIOCIGETIFACES, &io)) {
 			syslog(LOG_ERR, "pfi_refresh(): ioctl(): %s",
 			    strerror(errno));
 			goto err2;
@@ -1231,7 +1231,7 @@ pfq_refresh(void)
 
 	bzero(&pa, sizeof(pa));
 	pa.version = PFIOC_ALTQ_VERSION;
-	if (ioctl(dev, DIOCGETALTQS, &pa)) {
+	if (ioctl(pfctl_fd(pfh), DIOCGETALTQS, &pa)) {
 		syslog(LOG_ERR, "pfq_refresh: ioctl(DIOCGETALTQS): %s",
 		    strerror(errno));
 		return (-1);
@@ -1251,7 +1251,7 @@ pfq_refresh(void)
 		pa.ticket = ticket;
 		pa.nr = i;
 
-		if (ioctl(dev, DIOCGETALTQ, &pa)) {
+		if (ioctl(pfctl_fd(pfh), DIOCGETALTQ, &pa)) {
 			syslog(LOG_ERR, "pfq_refresh(): "
 			    "ioctl(DIOCGETALTQ): %s",
 			    strerror(errno));
@@ -1287,7 +1287,7 @@ pfs_refresh(void)
 		return (0);
 
 	pfctl_free_status(pfs);
-	pfs = pfctl_get_status(dev);
+	pfs = pfctl_get_status_h(pfh);
 
 	if (pfs == NULL) {
 		syslog(LOG_ERR, "pfs_refresh(): ioctl(): %s",
@@ -1329,7 +1329,7 @@ pft_refresh(void)
 		io.pfrio_size = numtbls;
 		io.pfrio_buffer = t;
 
-		if (ioctl(dev, DIOCRGETTSTATS, &io)) {
+		if (ioctl(pfctl_fd(pfh), DIOCRGETTSTATS, &io)) {
 			syslog(LOG_ERR, "pft_refresh(): ioctl(): %s",
 			    strerror(errno));
 			goto err2;
@@ -1396,7 +1396,7 @@ pfa_table_addrs(u_int sidx, struct pfr_table *pt)
 		io.pfrio_buffer = t;
 		io.pfrio_esize = sizeof(struct pfr_astats);
 
-		if (ioctl(dev, DIOCRGETASTATS, &io)) {
+		if (ioctl(pfctl_fd(pfh), DIOCRGETASTATS, &io)) {
 			syslog(LOG_ERR, "pfa_table_addrs(): ioctl() on %s: %s",
 			    pt->pfrt_name, strerror(errno));
 			numaddrs = -1;
@@ -1464,7 +1464,7 @@ pfa_refresh(void)
 		io.pfrio_size = numtbls;
 		io.pfrio_buffer = pt;
 
-		if (ioctl(dev, DIOCRGETTABLES, &io)) {
+		if (ioctl(pfctl_fd(pfh), DIOCRGETTABLES, &io)) {
 			syslog(LOG_ERR, "pfa_refresh(): ioctl(): %s",
 			    strerror(errno));
 			goto err2;
@@ -1519,14 +1519,14 @@ pfl_scan_ruleset(const char *path)
 	struct pfl_entry *e;
 	u_int32_t nr, i;
 
-	if (pfctl_get_rules_info(dev, &rules, PF_PASS, path)) {
+	if (pfctl_get_rules_info(pfctl_fd(pfh), &rules, PF_PASS, path)) {
 		syslog(LOG_ERR, "pfl_scan_ruleset: ioctl(DIOCGETRULES): %s",
 		    strerror(errno));
 		goto err;
 	}
 
 	for (nr = rules.nr, i = 0; i < nr; i++) {
-		if (pfctl_get_rule(dev, i, rules.ticket, path,
+		if (pfctl_get_rule(pfctl_fd(pfh), i, rules.ticket, path,
 		    PF_PASS, &rule, anchor_call)) {
 			syslog(LOG_ERR, "pfl_scan_ruleset: ioctl(DIOCGETRULE):"
 			    " %s", strerror(errno));
@@ -1572,7 +1572,7 @@ pfl_walk_rulesets(const char *path)
 
 	bzero(&prs, sizeof(prs));
 	strlcpy(prs.path, path, sizeof(prs.path));
-	if (ioctl(dev, DIOCGETRULESETS, &prs)) {
+	if (ioctl(pfctl_fd(pfh), DIOCGETRULESETS, &prs)) {
 		syslog(LOG_ERR, "pfl_walk_rulesets: ioctl(DIOCGETRULESETS): %s",
 		    strerror(errno));
 		goto err;
@@ -1580,7 +1580,7 @@ pfl_walk_rulesets(const char *path)
 
 	for (nr = prs.nr, i = 0; i < nr; i++) {
 		prs.nr = i;
-		if (ioctl(dev, DIOCGETRULESET, &prs)) {
+		if (ioctl(pfctl_fd(pfh), DIOCGETRULESET, &prs)) {
 			syslog(LOG_ERR, "pfl_walk_rulesets: ioctl(DIOCGETRULESET):"
 			    " %s", strerror(errno));
 			goto err;
@@ -1671,13 +1671,13 @@ pf_init(struct lmodule *mod, int __unused argc, char __unused *argv[])
 {
 	module = mod;
 
-	if ((dev = open("/dev/pf", O_RDONLY)) == -1) {
+	if ((pfh = pfctl_open(PF_DEVICE)) == NULL) {
 		syslog(LOG_ERR, "pf_init(): open(): %s\n",
 		    strerror(errno));
 		return (-1);
 	}
 
-	if ((altq_enabled = altq_is_enabled(dev)) == -1) {
+	if ((altq_enabled = altq_is_enabled(pfctl_fd(pfh))) == -1) {
 		syslog(LOG_ERR, "pf_init(): altq test failed");
 		return (-1);
 	}
@@ -1756,7 +1756,8 @@ pf_fini(void)
 	pfctl_free_status(pfs);
 	pfs = NULL;
 
-	close(dev);
+	pfctl_close(pfh);
+
 	return (0);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202404291436.43TEaoh6080646>