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