git: b3a68a2ec3f1 - main - pf: convert DIOCRCLRTSTATS to netlink
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 26 Mar 2025 22:56:54 UTC
The branch main has been updated by kp:
URL: https://cgit.FreeBSD.org/src/commit/?id=b3a68a2ec3f132183cadbdf86967ab912938a74e
commit b3a68a2ec3f132183cadbdf86967ab912938a74e
Author: Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2025-03-22 05:54:39 +0000
Commit: Kristof Provost <kp@FreeBSD.org>
CommitDate: 2025-03-26 22:54:36 +0000
pf: convert DIOCRCLRTSTATS to netlink
Sponsored by: Rubicon Communications, LLC ("Netgate")
---
lib/libpfctl/libpfctl.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
lib/libpfctl/libpfctl.h | 2 ++
sbin/pfctl/pfctl.h | 1 -
sbin/pfctl/pfctl_radix.c | 23 -----------------------
sbin/pfctl/pfctl_table.c | 2 +-
sys/netpfil/pf/pf_nl.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
sys/netpfil/pf/pf_nl.h | 2 ++
7 files changed, 95 insertions(+), 25 deletions(-)
diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
index e1cae22e2f3e..d84a66063647 100644
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -3279,3 +3279,48 @@ pfctl_get_tstats(struct pfctl_handle *h, const struct pfr_table *filter,
return (e.error);
}
+static struct snl_attr_parser ap_tstats_clr[] = {
+ { .type = PF_TS_NZERO, .off = 0, .cb = snl_attr_get_uint64 },
+};
+SNL_DECLARE_PARSER(tstats_clr_parser, struct genlmsghdr, snl_f_p_empty, ap_tstats_clr);
+
+int
+pfctl_clear_tstats(struct pfctl_handle *h, const struct pfr_table *filter,
+ int *nzero, int flags)
+{
+ struct snl_writer nw;
+ struct snl_errmsg_data e = {};
+ struct nlmsghdr *hdr;
+ uint64_t zero;
+ uint32_t seq_id;
+ int family_id;
+
+ family_id = snl_get_genl_family(&h->ss, PFNL_FAMILY_NAME);
+ if (family_id == 0)
+ return (ENOTSUP);
+
+ snl_init_writer(&h->ss, &nw);
+ hdr = snl_create_genl_msg_request(&nw, family_id, PFNL_CMD_CLR_TSTATS);
+
+ snl_add_msg_attr_string(&nw, PF_T_ANCHOR, filter->pfrt_anchor);
+ snl_add_msg_attr_string(&nw, PF_T_NAME, filter->pfrt_name);
+ snl_add_msg_attr_u32(&nw, PF_T_TABLE_FLAGS, filter->pfrt_flags);
+ snl_add_msg_attr_u32(&nw, PF_T_FLAGS, flags);
+
+ if ((hdr = snl_finalize_msg(&nw)) == NULL)
+ return (ENXIO);
+
+ seq_id = hdr->nlmsg_seq;
+
+ if (!snl_send_message(&h->ss, hdr))
+ return (ENXIO);
+
+ while ((hdr = snl_read_reply_multi(&h->ss, seq_id, &e)) != NULL) {
+ if (!snl_parse_nlmsg(&h->ss, hdr, &tstats_clr_parser, &zero))
+ continue;
+ if (nzero)
+ *nzero = (uint32_t)zero;
+ }
+
+ return (e.error);
+}
diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h
index c1c1da66746b..d8a7d1b6ebc4 100644
--- a/lib/libpfctl/libpfctl.h
+++ b/lib/libpfctl/libpfctl.h
@@ -554,5 +554,7 @@ int pfctl_del_table(struct pfctl_handle *h, struct pfr_table *table,
typedef int (*pfctl_get_tstats_fn)(const struct pfr_tstats *t, void *arg);
int pfctl_get_tstats(struct pfctl_handle *h, const struct pfr_table *filter,
pfctl_get_tstats_fn fn, void *arg);
+int pfctl_clear_tstats(struct pfctl_handle *h, const struct pfr_table *filter,
+ int *nzero, int flags);
#endif
diff --git a/sbin/pfctl/pfctl.h b/sbin/pfctl/pfctl.h
index ffd37cf023a6..468328e12f38 100644
--- a/sbin/pfctl/pfctl.h
+++ b/sbin/pfctl/pfctl.h
@@ -60,7 +60,6 @@ int pfr_add_table(struct pfr_table *, int *, int);
int pfr_del_table(struct pfr_table *, int *, int);
int pfr_get_tables(struct pfr_table *, struct pfr_table *, int *, int);
int pfr_get_tstats(struct pfr_table *, struct pfr_tstats *, int *, int);
-int pfr_clr_tstats(struct pfr_table *, int, int *, int);
int pfr_clr_astats(struct pfr_table *, struct pfr_addr *, int, int *, int);
int pfr_clr_addrs(struct pfr_table *, int *, int);
int pfr_add_addrs(struct pfr_table *, struct pfr_addr *, int, int *, int);
diff --git a/sbin/pfctl/pfctl_radix.c b/sbin/pfctl/pfctl_radix.c
index 3b0cc615e5a2..1d1918e29f44 100644
--- a/sbin/pfctl/pfctl_radix.c
+++ b/sbin/pfctl/pfctl_radix.c
@@ -234,29 +234,6 @@ pfr_clr_astats(struct pfr_table *tbl, struct pfr_addr *addr, int size,
return (0);
}
-int
-pfr_clr_tstats(struct pfr_table *tbl, int size, int *nzero, int flags)
-{
- struct pfioc_table io;
-
- if (size < 0 || (size && !tbl)) {
- errno = EINVAL;
- return (-1);
- }
- bzero(&io, sizeof io);
- io.pfrio_flags = flags;
- io.pfrio_buffer = tbl;
- io.pfrio_esize = sizeof(*tbl);
- io.pfrio_size = size;
- if (ioctl(dev, DIOCRCLRTSTATS, &io)) {
- pfr_report_error(tbl, &io, "clear tstats from");
- return (-1);
- }
- if (nzero)
- *nzero = io.pfrio_nzero;
- return (0);
-}
-
int
pfr_tst_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
int *nmatch, int flags)
diff --git a/sbin/pfctl/pfctl_table.c b/sbin/pfctl/pfctl_table.c
index 57f7354b0172..834f74811ea2 100644
--- a/sbin/pfctl/pfctl_table.c
+++ b/sbin/pfctl/pfctl_table.c
@@ -396,7 +396,7 @@ pfctl_table(int argc, char *argv[], char *tname, const char *command,
opts & PF_OPT_USEDNS);
} else if (!strcmp(command, "zero")) {
flags |= PFR_FLAG_ADDRSTOO;
- RVTEST(pfr_clr_tstats(&table, 1, &nzero, flags));
+ RVTEST(pfctl_clear_tstats(pfh, &table, &nzero, flags));
xprintf(opts, "%d table/stats cleared", nzero);
} else
warnx("pfctl_table: unknown command '%s'", command);
diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c
index f34bb71839b3..3a5ae2f233b4 100644
--- a/sys/netpfil/pf/pf_nl.c
+++ b/sys/netpfil/pf/pf_nl.c
@@ -2035,6 +2035,44 @@ pf_handle_get_tstats(struct nlmsghdr *hdr, struct nl_pstate *npt)
return (error);
}
+static int
+pf_handle_clear_tstats(struct nlmsghdr *hdr, struct nl_pstate *npt)
+{
+ struct pfioc_table attrs = { 0 };
+ struct nl_writer *nw = npt->nw;
+ struct genlmsghdr *ghdr_new;
+ int error;
+ int nzero;
+
+ PF_RULES_RLOCK_TRACKER;
+
+ error = nl_parse_nlmsg(hdr, &table_parser, npt, &attrs);
+ if (error != 0)
+ return (error);
+
+ PF_TABLE_STATS_LOCK();
+ PF_RULES_RLOCK();
+ error = pfr_clr_tstats(&attrs.pfrio_table, 1,
+ &nzero, attrs.pfrio_flags | PFR_FLAG_USERIOCTL);
+ PF_RULES_RUNLOCK();
+ PF_TABLE_STATS_UNLOCK();
+
+ if (!nlmsg_reply(nw, hdr, sizeof(struct genlmsghdr)))
+ return (ENOMEM);
+
+ ghdr_new = nlmsg_reserve_object(nw, struct genlmsghdr);
+ ghdr_new->cmd = PFNL_CMD_CLR_TSTATS;
+ ghdr_new->version = 0;
+ ghdr_new->reserved = 0;
+
+ nlattr_add_u64(nw, PF_TS_NZERO, nzero);
+
+ if (! nlmsg_end(nw))
+ error = ENOMEM;
+
+ return (error);
+}
+
static const struct nlhdr_parser *all_parsers[] = {
&state_parser,
&addrule_parser,
@@ -2257,6 +2295,13 @@ static const struct genl_cmd pf_cmds[] = {
.cmd_flags = GENL_CMD_CAP_DUMP | GENL_CMD_CAP_HASPOL,
.cmd_priv = PRIV_NETINET_PF,
},
+ {
+ .cmd_num = PFNL_CMD_CLR_TSTATS,
+ .cmd_name = "CLR_TSTATS",
+ .cmd_cb = pf_handle_clear_tstats,
+ .cmd_flags = GENL_CMD_CAP_DO | 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 ed01d3427fc4..55cc9c991b18 100644
--- a/sys/netpfil/pf/pf_nl.h
+++ b/sys/netpfil/pf/pf_nl.h
@@ -65,6 +65,7 @@ enum {
PFNL_CMD_ADD_TABLE = 27,
PFNL_CMD_DEL_TABLE = 28,
PFNL_CMD_GET_TSTATS = 29,
+ PFNL_CMD_CLR_TSTATS = 30,
__PFNL_CMD_MAX,
};
#define PFNL_CMD_MAX (__PFNL_CMD_MAX -1)
@@ -453,6 +454,7 @@ enum pf_tstats_t {
PF_TS_TZERO = 6, /* u64 */
PF_TS_CNT = 7, /* u64 */
PF_TS_REFCNT = 8, /* u64 array */
+ PF_TS_NZERO = 9, /* u64 */
};
#ifdef _KERNEL