diff options
author | dlg <dlg@openbsd.org> | 2018-12-11 22:08:57 +0000 |
---|---|---|
committer | dlg <dlg@openbsd.org> | 2018-12-11 22:08:57 +0000 |
commit | 5cf301f03442516757a4c40addc8e70524aa39bd (patch) | |
tree | 9ac769fb91aedaf7fbbd74ad7abaf06095187eee /sys/net/if.c | |
parent | the world is not ready for dnssec enabled by default (diff) | |
download | wireguard-openbsd-5cf301f03442516757a4c40addc8e70524aa39bd.tar.xz wireguard-openbsd-5cf301f03442516757a4c40addc8e70524aa39bd.zip |
add optional per-cpu counters for interface stats.
these exist so interfaces that want to do mpsafe work outside the
ifq machinery have a place to allocate and update stats in. the
generic ioctl handling for getting stats to userland knows how to
roll the new per cpu stats into the rest before export.
ok visa@
Diffstat (limited to 'sys/net/if.c')
-rw-r--r-- | sys/net/if.c | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/sys/net/if.c b/sys/net/if.c index 0d1c51d0ad8..864bc23d833 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.568 2018/11/29 00:11:49 dlg Exp $ */ +/* $OpenBSD: if.c,v 1.569 2018/12/11 22:08:57 dlg Exp $ */ /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */ /* @@ -84,6 +84,7 @@ #include <sys/domain.h> #include <sys/task.h> #include <sys/atomic.h> +#include <sys/percpu.h> #include <sys/proc.h> #include <dev/rndvar.h> @@ -1103,6 +1104,9 @@ if_detach(struct ifnet *ifp) splx(s); NET_UNLOCK(); + if (ifp->if_counters != NULL) + if_counters_free(ifp); + for (i = 0; i < ifp->if_nifqs; i++) ifq_destroy(ifp->if_ifqs[i]); if (ifp->if_ifqs != ifp->if_snd.ifq_ifqs) { @@ -2362,12 +2366,48 @@ ifconf(caddr_t data) } void +if_counters_alloc(struct ifnet *ifp) +{ + KASSERT(ifp->if_counters == NULL); + + ifp->if_counters = counters_alloc(ifc_ncounters); +} + +void +if_counters_free(struct ifnet *ifp) +{ + KASSERT(ifp->if_counters != NULL); + + counters_free(ifp->if_counters, ifc_ncounters); + ifp->if_counters = NULL; +} + +void if_getdata(struct ifnet *ifp, struct if_data *data) { unsigned int i; *data = ifp->if_data; + if (ifp->if_counters != NULL) { + uint64_t counters[ifc_ncounters]; + + counters_read(ifp->if_counters, counters, nitems(counters)); + + data->ifi_ipackets += counters[ifc_ipackets]; + data->ifi_ierrors += counters[ifc_ierrors]; + data->ifi_opackets += counters[ifc_opackets]; + data->ifi_oerrors += counters[ifc_oerrors]; + data->ifi_collisions += counters[ifc_collisions]; + data->ifi_ibytes += counters[ifc_ibytes]; + data->ifi_obytes += counters[ifc_obytes]; + data->ifi_imcasts += counters[ifc_imcasts]; + data->ifi_omcasts += counters[ifc_omcasts]; + data->ifi_iqdrops += counters[ifc_iqdrops]; + data->ifi_oqdrops += counters[ifc_oqdrops]; + data->ifi_noproto += counters[ifc_noproto]; + } + for (i = 0; i < ifp->if_nifqs; i++) { struct ifqueue *ifq = ifp->if_ifqs[i]; |