Download raw body.
pfctl: clear statistic for the address
tech@,
I'd like to propose a patch that adds to pfctl a way to clear statistics for
specified address from the table.
A usecase for this patch is explained here:
https://marc.info/?l=openbsd-bugs&m=173206758904599&w=2
Feedback? Ok?
Index: pfctl.8
===================================================================
RCS file: /home/cvs/src/sbin/pfctl/pfctl.8,v
diff -u -p -r1.183 pfctl.8
--- pfctl.8 18 Nov 2022 18:11:10 -0000 1.183
+++ pfctl.8 20 Nov 2024 11:07:01 -0000
@@ -517,8 +517,8 @@ Automatically create a persistent table
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.
+.It Fl T Cm zero Op Ar address ...
+Clear all the statistics of a table, or only for specified addresses.
.El
.Pp
For the
Index: pfctl.h
===================================================================
RCS file: /home/cvs/src/sbin/pfctl/pfctl.h,v
diff -u -p -r1.64 pfctl.h
--- pfctl.h 14 Jul 2024 19:51:08 -0000 1.64
+++ pfctl.h 20 Nov 2024 11:03:06 -0000
@@ -82,6 +82,7 @@ int pfr_del_tables(struct pfr_table *,
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);
Index: pfctl_radix.c
===================================================================
RCS file: /home/cvs/src/sbin/pfctl/pfctl_radix.c,v
diff -u -p -r1.39 pfctl_radix.c
--- pfctl_radix.c 14 Jul 2024 19:51:08 -0000 1.39
+++ pfctl_radix.c 20 Nov 2024 11:02:55 -0000
@@ -314,6 +314,29 @@ pfr_get_astats(struct pfr_table *tbl, st
}
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)
{
struct pfioc_table io;
Index: pfctl_table.c
===================================================================
RCS file: /home/cvs/src/sbin/pfctl/pfctl_table.c,v
diff -u -p -r1.90 pfctl_table.c
--- pfctl_table.c 19 Aug 2024 13:01:47 -0000 1.90
+++ pfctl_table.c 20 Nov 2024 10:57:20 -0000
@@ -346,9 +346,22 @@ pfctl_table(int argc, char *argv[], char
}
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);
--
wbr, Kirill
pfctl: clear statistic for the address