diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c --- a/sbin/pfctl/pfctl.c +++ b/sbin/pfctl/pfctl.c @@ -98,7 +98,7 @@ char *); void pfctl_print_eth_rule_counters(struct pfctl_eth_rule *, int); void pfctl_print_rule_counters(struct pfctl_rule *, int); -int pfctl_show_eth_rules(int, int); +int pfctl_show_eth_rules(int, int, enum pfctl_show); int pfctl_show_rules(int, char *, int, enum pfctl_show, char *, int); int pfctl_show_nat(int, int, char *); int pfctl_show_src_nodes(int, int); @@ -1052,7 +1052,7 @@ } int -pfctl_show_eth_rules(int dev, int opts) +pfctl_show_eth_rules(int dev, int opts, enum pfctl_show format) { struct pfctl_eth_rules_info info; struct pfctl_eth_rule rule; @@ -1063,8 +1063,8 @@ return (-1); } for (int nr = 0; nr < info.nr; nr++) { - if (pfctl_get_eth_rule(dev, nr, info.ticket, &rule, false) - != 0) { + if (pfctl_get_eth_rule(dev, nr, info.ticket, &rule, + opts & PF_OPT_CLRRULECTRS) != 0) { warn("DIOCGETETHRULE"); return (-1); } @@ -2640,13 +2640,13 @@ pfctl_show_limits(dev, opts); break; case 'e': - pfctl_show_eth_rules(dev, opts); + pfctl_show_eth_rules(dev, opts, 0); break; case 'a': opts |= PF_OPT_SHOWALL; pfctl_load_fingerprints(dev, opts); - pfctl_show_eth_rules(dev, opts); + pfctl_show_eth_rules(dev, opts, 0); pfctl_show_nat(dev, opts, anchorname); pfctl_show_rules(dev, path, opts, 0, anchorname, 0); @@ -2673,9 +2673,11 @@ } } - if ((opts & PF_OPT_CLRRULECTRS) && showopt == NULL) + if ((opts & PF_OPT_CLRRULECTRS) && showopt == NULL) { + pfctl_show_eth_rules(dev, opts, PFCTL_SHOW_NOTHING); pfctl_show_rules(dev, path, opts, PFCTL_SHOW_NOTHING, anchorname, 0); + } if (clearopt != NULL) { if (anchorname[0] == '_' || strstr(anchorname, "/_") != NULL) diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -2555,6 +2555,7 @@ void *nvlpacked = NULL; struct pf_keth_rule *rule = NULL; u_int32_t ticket, nr; + bool clear = false; #define ERROUT(x) do { error = (x); goto DIOCGETETHRULE_error; } while (0) @@ -2571,6 +2572,12 @@ ERROUT(EBADMSG); ticket = nvlist_get_number(nvl, "ticket"); + if (nvlist_exists_bool(nvl, "clear")) + clear = nvlist_get_bool(nvl, "clear"); + + if (clear && !(flags & FWRITE)) + ERROUT(EACCES); + if (! nvlist_exists_number(nvl, "nr")) ERROUT(EBADMSG); nr = nvlist_get_number(nvl, "nr"); @@ -2612,6 +2619,13 @@ ERROUT(ENOSPC); error = copyout(nvlpacked, nv->data, nv->len); + if (error == 0 && clear) { + counter_u64_zero(rule->evaluations); + for (int i = 0; i < 2; i++) { + counter_u64_zero(rule->packets[i]); + counter_u64_zero(rule->bytes[i]); + } + } #undef ERROUT DIOCGETETHRULE_error: