From 0e37f3e196c6cb887be0de58c315aa1358caa363 Mon Sep 17 00:00:00 2001 From: "Christian S.J. Peron" Date: Fri, 19 Jun 2009 20:31:44 +0000 Subject: [PATCH] Implement the -z (zero counters) option for the various bpf counters. Add necessary changes to the kernel for this (basically introduce a bpf_zero_counters() function). As well, update the man page. MFC after: 1 month Discussed with: rwatson --- sys/net/bpf.c | 46 ++++++++++++++++++++++++++++++++++++++- usr.bin/netstat/bpf.c | 9 +++++++- usr.bin/netstat/netstat.1 | 1 + 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/sys/net/bpf.c b/sys/net/bpf.c index a89135f32ab..5a2ab19160e 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -2032,6 +2032,35 @@ bpf_drvinit(void *unused) } +/* + * Zero out the various packet counters associated with all of the bpf + * descriptors. At some point, we will probably want to get a bit more + * granular and allow the user to specify descriptors to be zeroed. + */ +static void +bpf_zero_counters(void) +{ + struct bpf_if *bp; + struct bpf_d *bd; + + mtx_lock(&bpf_mtx); + LIST_FOREACH(bp, &bpf_iflist, bif_next) { + BPFIF_LOCK(bp); + LIST_FOREACH(bd, &bp->bif_dlist, bd_next) { + BPFD_LOCK(bd); + bd->bd_rcount = 0; + bd->bd_dcount = 0; + bd->bd_fcount = 0; + bd->bd_wcount = 0; + bd->bd_wfcount = 0; + bd->bd_zcopy = 0; + BPFD_UNLOCK(bd); + } + BPFIF_UNLOCK(bp); + } + mtx_unlock(&bpf_mtx); +} + static void bpfstats_fill_xbpf(struct xbpf_d *d, struct bpf_d *bd) { @@ -2066,7 +2095,7 @@ bpfstats_fill_xbpf(struct xbpf_d *d, struct bpf_d *bd) static int bpf_stats_sysctl(SYSCTL_HANDLER_ARGS) { - struct xbpf_d *xbdbuf, *xbd; + struct xbpf_d *xbdbuf, *xbd, zerostats; int index, error; struct bpf_if *bp; struct bpf_d *bd; @@ -2080,6 +2109,21 @@ bpf_stats_sysctl(SYSCTL_HANDLER_ARGS) error = priv_check(req->td, PRIV_NET_BPF); if (error) return (error); + /* + * Check to see if the user is requesting that the counters be + * zeroed out. Explicitly check that the supplied data is zeroed, + * as we aren't allowing the user to set the counters currently. + */ + if (req->newptr != NULL) { + if (req->newlen != sizeof(zerostats)) + return (EINVAL); + bzero(&zerostats, sizeof(zerostats)); + xbd = req->newptr; + if (bcmp(xbd, &zerostats, sizeof(*xbd)) != 0) + return (EINVAL); + bpf_zero_counters(); + return (0); + } if (req->oldptr == NULL) return (SYSCTL_OUT(req, 0, bpf_bpfd_cnt * sizeof(*xbd))); if (bpf_bpfd_cnt == 0) diff --git a/usr.bin/netstat/bpf.c b/usr.bin/netstat/bpf.c index 4455d04d618..2ffeacbc7de 100644 --- a/usr.bin/netstat/bpf.c +++ b/usr.bin/netstat/bpf.c @@ -91,10 +91,17 @@ bpf_flags(struct xbpf_d *bd, char *flagbuf) void bpf_stats(char *ifname) { - struct xbpf_d *d, *bd; + struct xbpf_d *d, *bd, zerostat; char *pname, flagbuf[12]; size_t size; + if (zflag) { + bzero(&zerostat, sizeof(zerostat)); + if (sysctlbyname("net.bpf.stats", NULL, NULL, + &zerostat, sizeof(zerostat)) < 0) + warn("failed to zero bpf counters"); + return; + } if (sysctlbyname("net.bpf.stats", NULL, &size, NULL, 0) < 0) { warn("net.bpf.stats"); diff --git a/usr.bin/netstat/netstat.1 b/usr.bin/netstat/netstat.1 index f78b29f06a1..71af7aa53fa 100644 --- a/usr.bin/netstat/netstat.1 +++ b/usr.bin/netstat/netstat.1 @@ -198,6 +198,7 @@ The network manages a private pool of memory buffers. .Bk -words .Nm .Fl B +.Op Fl z .Op Fl I Ar interface .Ek .Xc