The branch main has been updated by kp:

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

commit b3a68a2ec3f132183cadbdf86967ab912938a74e
Author:     Kristof Provost <k...@freebsd.org>
AuthorDate: 2025-03-22 05:54:39 +0000
Commit:     Kristof Provost <k...@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

Reply via email to