From 3aa061d11d8ebbf2e861b4c820df34c3d6024b1e Mon Sep 17 00:00:00 2001 From: kirill Date: Wed, 20 Nov 2024 13:57:30 +0000 Subject: pfctl: clear statistic for specified addresses OK: bluhm@ --- sbin/pfctl/pfctl.8 | 6 +++--- sbin/pfctl/pfctl.h | 3 ++- sbin/pfctl/pfctl_radix.c | 25 ++++++++++++++++++++++++- sbin/pfctl/pfctl_table.c | 19 ++++++++++++++++--- 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/sbin/pfctl/pfctl.8 b/sbin/pfctl/pfctl.8 index 3f152f4c0dc..649a6f3ff03 100644 --- a/sbin/pfctl/pfctl.8 +++ b/sbin/pfctl/pfctl.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: pfctl.8,v 1.183 2022/11/18 18:11:10 kn Exp $ +.\" $OpenBSD: pfctl.8,v 1.184 2024/11/20 13:57:29 kirill Exp $ .\" .\" Copyright (c) 2001 Kjell Wooding. All rights reserved. .\" @@ -24,7 +24,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: November 18 2022 $ +.Dd $Mdocdate: November 20 2024 $ .Dt PFCTL 8 .Os .Sh NAME @@ -518,7 +518,7 @@ Show the content (addresses) of a table. .It Fl T Cm test Test if the given addresses match a table. .It Fl T Cm zero -Clear all the statistics of a table. +Clear all the statistics of a table, or only for specified addresses. .El .Pp For the diff --git a/sbin/pfctl/pfctl.h b/sbin/pfctl/pfctl.h index b424192c155..cf4ac9000a0 100644 --- a/sbin/pfctl/pfctl.h +++ b/sbin/pfctl/pfctl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl.h,v 1.64 2024/07/14 19:51:08 sashan Exp $ */ +/* $OpenBSD: pfctl.h,v 1.65 2024/11/20 13:57:29 kirill Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -82,6 +82,7 @@ int pfr_del_tables(struct pfr_table *, int, 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); int pfr_del_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 cd5bf72c010..ec1ffdcd8a5 100644 --- a/sbin/pfctl/pfctl_radix.c +++ b/sbin/pfctl/pfctl_radix.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_radix.c,v 1.39 2024/07/14 19:51:08 sashan Exp $ */ +/* $OpenBSD: pfctl_radix.c,v 1.40 2024/11/20 13:57:29 kirill Exp $ */ /* * Copyright (c) 2002 Cedric Berger @@ -313,6 +313,29 @@ pfr_get_astats(struct pfr_table *tbl, struct pfr_astats *addr, int *size, return (0); } +int +pfr_clr_astats(struct pfr_table *tbl, struct pfr_addr *addr, int size, + int *nzero, int flags) +{ + struct pfioc_table io; + + if (size < 0 || (size && !tbl) || addr == NULL) { + errno = EINVAL; + return (-1); + } + bzero(&io, sizeof io); + io.pfrio_flags = flags; + io.pfrio_table = *tbl; + io.pfrio_buffer = addr; + io.pfrio_esize = sizeof(*addr); + io.pfrio_size = size; + if (ioctl(dev, DIOCRCLRASTATS, &io) == -1) + return (-1); + if (nzero) + *nzero = io.pfrio_nzero; + return (0); +} + int pfr_clr_tstats(struct pfr_table *tbl, int size, int *nzero, int flags) { diff --git a/sbin/pfctl/pfctl_table.c b/sbin/pfctl/pfctl_table.c index a0a4c52a1a5..e460adf5f23 100644 --- a/sbin/pfctl/pfctl_table.c +++ b/sbin/pfctl/pfctl_table.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_table.c,v 1.90 2024/08/19 13:01:47 jsg Exp $ */ +/* $OpenBSD: pfctl_table.c,v 1.91 2024/11/20 13:57:29 kirill Exp $ */ /* * Copyright (c) 2002 Cedric Berger @@ -346,9 +346,22 @@ pfctl_table(int argc, char *argv[], char *tname, const char *command, } if (nmatch < b.pfrb_size) rv = 2; + } else if (!strcmp(command, "zero") && (argc || file != NULL)) { + b.pfrb_type = PFRB_ADDRS; + if (load_addr(&b, argc, argv, file, 0, opts)) + goto _error; + if (opts & PF_OPT_VERBOSE) + flags |= PFR_FLAG_FEEDBACK; + RVTEST(pfr_clr_astats(&table, b.pfrb_caddr, b.pfrb_size, + &nzero, flags)); + xprintf(opts, "%d/%d addresses cleared", nzero, b.pfrb_size); + if (opts & PF_OPT_VERBOSE) + PFRB_FOREACH(a, &b) + if (opts & PF_OPT_VERBOSE2 || + a->pfra_fback != PFR_FB_NONE) + print_addrx(a, NULL, + opts & PF_OPT_USEDNS); } else if (!strcmp(command, "zero")) { - if (argc || file != NULL) - usage(); flags |= PFR_FLAG_ADDRSTOO; RVTEST(pfr_clr_tstats(&table, 1, &nzero, flags)); xprintf(opts, "%d table/stats cleared", nzero); -- cgit v1.2.3