xref: /netbsd-src/sys/net/net_stats.c (revision b578a8edb05a42ec854bcb5ba6648341cd9ea956)
1*b578a8edSthorpej /*	$NetBSD: net_stats.c,v 1.6 2020/02/07 12:35:33 thorpej Exp $	*/
234908fe5Sthorpej 
334908fe5Sthorpej /*-
434908fe5Sthorpej  * Copyright (c) 2008 The NetBSD Foundation, Inc.
534908fe5Sthorpej  * All rights reserved.
634908fe5Sthorpej  *
734908fe5Sthorpej  * This code is derived from software contributed to The NetBSD Foundation
834908fe5Sthorpej  * by Jason R. Thorpe.
934908fe5Sthorpej  *
1034908fe5Sthorpej  * Redistribution and use in source and binary forms, with or without
1134908fe5Sthorpej  * modification, are permitted provided that the following conditions
1234908fe5Sthorpej  * are met:
1334908fe5Sthorpej  * 1. Redistributions of source code must retain the above copyright
1434908fe5Sthorpej  *    notice, this list of conditions and the following disclaimer.
1534908fe5Sthorpej  * 2. Redistributions in binary form must reproduce the above copyright
1634908fe5Sthorpej  *    notice, this list of conditions and the following disclaimer in the
1734908fe5Sthorpej  *    documentation and/or other materials provided with the distribution.
1834908fe5Sthorpej  *
1934908fe5Sthorpej  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2034908fe5Sthorpej  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2134908fe5Sthorpej  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2234908fe5Sthorpej  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2334908fe5Sthorpej  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2434908fe5Sthorpej  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2534908fe5Sthorpej  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2634908fe5Sthorpej  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2734908fe5Sthorpej  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2834908fe5Sthorpej  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2934908fe5Sthorpej  * POSSIBILITY OF SUCH DAMAGE.
3034908fe5Sthorpej  */
3134908fe5Sthorpej 
3234908fe5Sthorpej #include <sys/cdefs.h>
33*b578a8edSthorpej __KERNEL_RCSID(0, "$NetBSD: net_stats.c,v 1.6 2020/02/07 12:35:33 thorpej Exp $");
3434908fe5Sthorpej 
3534908fe5Sthorpej #include <sys/types.h>
3634908fe5Sthorpej #include <sys/systm.h>
3734908fe5Sthorpej #include <sys/sysctl.h>
38b129a80cSthorpej #include <sys/kmem.h>
39*b578a8edSthorpej #include <sys/xcall.h>
4034908fe5Sthorpej 
4134908fe5Sthorpej #include <net/net_stats.h>
4234908fe5Sthorpej 
43b129a80cSthorpej typedef struct {
44b129a80cSthorpej 	uint64_t	*ctx_counters;	/* pointer to collated counter array */
45b129a80cSthorpej 	u_int		 ctx_ncounters;	/* number of counters in array */
46b129a80cSthorpej } netstat_sysctl_context;
47b129a80cSthorpej 
4834908fe5Sthorpej /*
4934908fe5Sthorpej  * netstat_convert_to_user_cb --
5034908fe5Sthorpej  *	Internal routine used as a call-back for percpu data enumeration.
5134908fe5Sthorpej  */
5234908fe5Sthorpej static void
netstat_convert_to_user_cb(void * v1,void * v2,struct cpu_info * ci)5334908fe5Sthorpej netstat_convert_to_user_cb(void *v1, void *v2, struct cpu_info *ci)
5434908fe5Sthorpej {
5534908fe5Sthorpej 	const uint64_t *local_counters = v1;
5634908fe5Sthorpej 	netstat_sysctl_context *ctx = v2;
5734908fe5Sthorpej 	u_int i;
5834908fe5Sthorpej 
5934908fe5Sthorpej 	for (i = 0; i < ctx->ctx_ncounters; i++)
6034908fe5Sthorpej 		ctx->ctx_counters[i] += local_counters[i];
6134908fe5Sthorpej }
6234908fe5Sthorpej 
6334908fe5Sthorpej /*
6434908fe5Sthorpej  * netstat_sysctl --
6534908fe5Sthorpej  *	Common routine for collating and reporting network statistics
6634908fe5Sthorpej  *	that are gathered per-CPU.  Statistics counters are assumed
6734908fe5Sthorpej  *	to be arrays of uint64_t's.
6834908fe5Sthorpej  */
6934908fe5Sthorpej int
netstat_sysctl(percpu_t * stat,u_int ncounters,SYSCTLFN_ARGS)70b129a80cSthorpej netstat_sysctl(percpu_t *stat, u_int ncounters, SYSCTLFN_ARGS)
7134908fe5Sthorpej {
72b129a80cSthorpej 	netstat_sysctl_context ctx;
7334908fe5Sthorpej 	struct sysctlnode node;
74b129a80cSthorpej 	uint64_t *counters;
75b129a80cSthorpej 	size_t countersize;
76b129a80cSthorpej 	int rv;
7734908fe5Sthorpej 
78b129a80cSthorpej 	countersize = sizeof(uint64_t) * ncounters;
79b129a80cSthorpej 
80b129a80cSthorpej 	counters = kmem_zalloc(countersize, KM_SLEEP);
81b129a80cSthorpej 	ctx.ctx_counters = counters;
82b129a80cSthorpej 	ctx.ctx_ncounters = ncounters;
83b129a80cSthorpej 
84*b578a8edSthorpej 	percpu_foreach_xcall(stat, XC_HIGHPRI_IPL(IPL_SOFTNET),
85*b578a8edSthorpej 	    netstat_convert_to_user_cb, &ctx);
86b129a80cSthorpej 
8734908fe5Sthorpej 	node = *rnode;
88b129a80cSthorpej 	node.sysctl_data = counters;
89b129a80cSthorpej 	node.sysctl_size = countersize;
90b129a80cSthorpej 	rv = sysctl_lookup(SYSCTLFN_CALL(&node));
91b129a80cSthorpej 
92b129a80cSthorpej 	kmem_free(counters, countersize);
93b129a80cSthorpej 
94b129a80cSthorpej 	return (rv);
9534908fe5Sthorpej }
96