162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci *		SNMP MIB entries for the IP subsystem.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci *		Alan Cox <gw4pts@gw4pts.ampr.org>
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci *		We don't chose to implement SNMP in the kernel (this would
962306a36Sopenharmony_ci *		be silly as SNMP is a pain in the backside in places). We do
1062306a36Sopenharmony_ci *		however need to collect the MIB statistics and export them
1162306a36Sopenharmony_ci *		out of /proc (eventually)
1262306a36Sopenharmony_ci */
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#ifndef _SNMP_H
1562306a36Sopenharmony_ci#define _SNMP_H
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#include <linux/cache.h>
1862306a36Sopenharmony_ci#include <linux/snmp.h>
1962306a36Sopenharmony_ci#include <linux/smp.h>
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci/*
2262306a36Sopenharmony_ci * Mibs are stored in array of unsigned long.
2362306a36Sopenharmony_ci */
2462306a36Sopenharmony_ci/*
2562306a36Sopenharmony_ci * struct snmp_mib{}
2662306a36Sopenharmony_ci *  - list of entries for particular API (such as /proc/net/snmp)
2762306a36Sopenharmony_ci *  - name of entries.
2862306a36Sopenharmony_ci */
2962306a36Sopenharmony_cistruct snmp_mib {
3062306a36Sopenharmony_ci	const char *name;
3162306a36Sopenharmony_ci	int entry;
3262306a36Sopenharmony_ci};
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci#define SNMP_MIB_ITEM(_name,_entry)	{	\
3562306a36Sopenharmony_ci	.name = _name,				\
3662306a36Sopenharmony_ci	.entry = _entry,			\
3762306a36Sopenharmony_ci}
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci#define SNMP_MIB_SENTINEL {	\
4062306a36Sopenharmony_ci	.name = NULL,		\
4162306a36Sopenharmony_ci	.entry = 0,		\
4262306a36Sopenharmony_ci}
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci/*
4562306a36Sopenharmony_ci * We use unsigned longs for most mibs but u64 for ipstats.
4662306a36Sopenharmony_ci */
4762306a36Sopenharmony_ci#include <linux/u64_stats_sync.h>
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci/* IPstats */
5062306a36Sopenharmony_ci#define IPSTATS_MIB_MAX	__IPSTATS_MIB_MAX
5162306a36Sopenharmony_cistruct ipstats_mib {
5262306a36Sopenharmony_ci	/* mibs[] must be first field of struct ipstats_mib */
5362306a36Sopenharmony_ci	u64		mibs[IPSTATS_MIB_MAX];
5462306a36Sopenharmony_ci	struct u64_stats_sync syncp;
5562306a36Sopenharmony_ci};
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci/* ICMP */
5862306a36Sopenharmony_ci#define ICMP_MIB_MAX	__ICMP_MIB_MAX
5962306a36Sopenharmony_cistruct icmp_mib {
6062306a36Sopenharmony_ci	unsigned long	mibs[ICMP_MIB_MAX];
6162306a36Sopenharmony_ci};
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci#define ICMPMSG_MIB_MAX	__ICMPMSG_MIB_MAX
6462306a36Sopenharmony_cistruct icmpmsg_mib {
6562306a36Sopenharmony_ci	atomic_long_t	mibs[ICMPMSG_MIB_MAX];
6662306a36Sopenharmony_ci};
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci/* ICMP6 (IPv6-ICMP) */
6962306a36Sopenharmony_ci#define ICMP6_MIB_MAX	__ICMP6_MIB_MAX
7062306a36Sopenharmony_ci/* per network ns counters */
7162306a36Sopenharmony_cistruct icmpv6_mib {
7262306a36Sopenharmony_ci	unsigned long	mibs[ICMP6_MIB_MAX];
7362306a36Sopenharmony_ci};
7462306a36Sopenharmony_ci/* per device counters, (shared on all cpus) */
7562306a36Sopenharmony_cistruct icmpv6_mib_device {
7662306a36Sopenharmony_ci	atomic_long_t	mibs[ICMP6_MIB_MAX];
7762306a36Sopenharmony_ci};
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci#define ICMP6MSG_MIB_MAX  __ICMP6MSG_MIB_MAX
8062306a36Sopenharmony_ci/* per network ns counters */
8162306a36Sopenharmony_cistruct icmpv6msg_mib {
8262306a36Sopenharmony_ci	atomic_long_t	mibs[ICMP6MSG_MIB_MAX];
8362306a36Sopenharmony_ci};
8462306a36Sopenharmony_ci/* per device counters, (shared on all cpus) */
8562306a36Sopenharmony_cistruct icmpv6msg_mib_device {
8662306a36Sopenharmony_ci	atomic_long_t	mibs[ICMP6MSG_MIB_MAX];
8762306a36Sopenharmony_ci};
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci/* TCP */
9162306a36Sopenharmony_ci#define TCP_MIB_MAX	__TCP_MIB_MAX
9262306a36Sopenharmony_cistruct tcp_mib {
9362306a36Sopenharmony_ci	unsigned long	mibs[TCP_MIB_MAX];
9462306a36Sopenharmony_ci};
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci/* UDP */
9762306a36Sopenharmony_ci#define UDP_MIB_MAX	__UDP_MIB_MAX
9862306a36Sopenharmony_cistruct udp_mib {
9962306a36Sopenharmony_ci	unsigned long	mibs[UDP_MIB_MAX];
10062306a36Sopenharmony_ci};
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci/* Linux */
10362306a36Sopenharmony_ci#define LINUX_MIB_MAX	__LINUX_MIB_MAX
10462306a36Sopenharmony_cistruct linux_mib {
10562306a36Sopenharmony_ci	unsigned long	mibs[LINUX_MIB_MAX];
10662306a36Sopenharmony_ci};
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci/* Linux Xfrm */
10962306a36Sopenharmony_ci#define LINUX_MIB_XFRMMAX	__LINUX_MIB_XFRMMAX
11062306a36Sopenharmony_cistruct linux_xfrm_mib {
11162306a36Sopenharmony_ci	unsigned long	mibs[LINUX_MIB_XFRMMAX];
11262306a36Sopenharmony_ci};
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci/* Linux TLS */
11562306a36Sopenharmony_ci#define LINUX_MIB_TLSMAX	__LINUX_MIB_TLSMAX
11662306a36Sopenharmony_cistruct linux_tls_mib {
11762306a36Sopenharmony_ci	unsigned long	mibs[LINUX_MIB_TLSMAX];
11862306a36Sopenharmony_ci};
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci#define DEFINE_SNMP_STAT(type, name)	\
12162306a36Sopenharmony_ci	__typeof__(type) __percpu *name
12262306a36Sopenharmony_ci#define DEFINE_SNMP_STAT_ATOMIC(type, name)	\
12362306a36Sopenharmony_ci	__typeof__(type) *name
12462306a36Sopenharmony_ci#define DECLARE_SNMP_STAT(type, name)	\
12562306a36Sopenharmony_ci	extern __typeof__(type) __percpu *name
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci#define __SNMP_INC_STATS(mib, field)	\
12862306a36Sopenharmony_ci			__this_cpu_inc(mib->mibs[field])
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci#define SNMP_INC_STATS_ATOMIC_LONG(mib, field)	\
13162306a36Sopenharmony_ci			atomic_long_inc(&mib->mibs[field])
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci#define SNMP_INC_STATS(mib, field)	\
13462306a36Sopenharmony_ci			this_cpu_inc(mib->mibs[field])
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci#define SNMP_DEC_STATS(mib, field)	\
13762306a36Sopenharmony_ci			this_cpu_dec(mib->mibs[field])
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci#define __SNMP_ADD_STATS(mib, field, addend)	\
14062306a36Sopenharmony_ci			__this_cpu_add(mib->mibs[field], addend)
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci#define SNMP_ADD_STATS(mib, field, addend)	\
14362306a36Sopenharmony_ci			this_cpu_add(mib->mibs[field], addend)
14462306a36Sopenharmony_ci#define SNMP_UPD_PO_STATS(mib, basefield, addend)	\
14562306a36Sopenharmony_ci	do { \
14662306a36Sopenharmony_ci		__typeof__((mib->mibs) + 0) ptr = mib->mibs;	\
14762306a36Sopenharmony_ci		this_cpu_inc(ptr[basefield##PKTS]);		\
14862306a36Sopenharmony_ci		this_cpu_add(ptr[basefield##OCTETS], addend);	\
14962306a36Sopenharmony_ci	} while (0)
15062306a36Sopenharmony_ci#define __SNMP_UPD_PO_STATS(mib, basefield, addend)	\
15162306a36Sopenharmony_ci	do { \
15262306a36Sopenharmony_ci		__typeof__((mib->mibs) + 0) ptr = mib->mibs;	\
15362306a36Sopenharmony_ci		__this_cpu_inc(ptr[basefield##PKTS]);		\
15462306a36Sopenharmony_ci		__this_cpu_add(ptr[basefield##OCTETS], addend);	\
15562306a36Sopenharmony_ci	} while (0)
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci#if BITS_PER_LONG==32
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci#define __SNMP_ADD_STATS64(mib, field, addend) 				\
16162306a36Sopenharmony_ci	do {								\
16262306a36Sopenharmony_ci		__typeof__(*mib) *ptr = raw_cpu_ptr(mib);		\
16362306a36Sopenharmony_ci		u64_stats_update_begin(&ptr->syncp);			\
16462306a36Sopenharmony_ci		ptr->mibs[field] += addend;				\
16562306a36Sopenharmony_ci		u64_stats_update_end(&ptr->syncp);			\
16662306a36Sopenharmony_ci	} while (0)
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci#define SNMP_ADD_STATS64(mib, field, addend) 				\
16962306a36Sopenharmony_ci	do {								\
17062306a36Sopenharmony_ci		local_bh_disable();					\
17162306a36Sopenharmony_ci		__SNMP_ADD_STATS64(mib, field, addend);			\
17262306a36Sopenharmony_ci		local_bh_enable();				\
17362306a36Sopenharmony_ci	} while (0)
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci#define __SNMP_INC_STATS64(mib, field) SNMP_ADD_STATS64(mib, field, 1)
17662306a36Sopenharmony_ci#define SNMP_INC_STATS64(mib, field) SNMP_ADD_STATS64(mib, field, 1)
17762306a36Sopenharmony_ci#define __SNMP_UPD_PO_STATS64(mib, basefield, addend)			\
17862306a36Sopenharmony_ci	do {								\
17962306a36Sopenharmony_ci		__typeof__(*mib) *ptr;				\
18062306a36Sopenharmony_ci		ptr = raw_cpu_ptr((mib));				\
18162306a36Sopenharmony_ci		u64_stats_update_begin(&ptr->syncp);			\
18262306a36Sopenharmony_ci		ptr->mibs[basefield##PKTS]++;				\
18362306a36Sopenharmony_ci		ptr->mibs[basefield##OCTETS] += addend;			\
18462306a36Sopenharmony_ci		u64_stats_update_end(&ptr->syncp);			\
18562306a36Sopenharmony_ci	} while (0)
18662306a36Sopenharmony_ci#define SNMP_UPD_PO_STATS64(mib, basefield, addend)			\
18762306a36Sopenharmony_ci	do {								\
18862306a36Sopenharmony_ci		local_bh_disable();					\
18962306a36Sopenharmony_ci		__SNMP_UPD_PO_STATS64(mib, basefield, addend);		\
19062306a36Sopenharmony_ci		local_bh_enable();				\
19162306a36Sopenharmony_ci	} while (0)
19262306a36Sopenharmony_ci#else
19362306a36Sopenharmony_ci#define __SNMP_INC_STATS64(mib, field)		__SNMP_INC_STATS(mib, field)
19462306a36Sopenharmony_ci#define SNMP_INC_STATS64(mib, field)		SNMP_INC_STATS(mib, field)
19562306a36Sopenharmony_ci#define SNMP_DEC_STATS64(mib, field)		SNMP_DEC_STATS(mib, field)
19662306a36Sopenharmony_ci#define __SNMP_ADD_STATS64(mib, field, addend)	__SNMP_ADD_STATS(mib, field, addend)
19762306a36Sopenharmony_ci#define SNMP_ADD_STATS64(mib, field, addend)	SNMP_ADD_STATS(mib, field, addend)
19862306a36Sopenharmony_ci#define SNMP_UPD_PO_STATS64(mib, basefield, addend) SNMP_UPD_PO_STATS(mib, basefield, addend)
19962306a36Sopenharmony_ci#define __SNMP_UPD_PO_STATS64(mib, basefield, addend) __SNMP_UPD_PO_STATS(mib, basefield, addend)
20062306a36Sopenharmony_ci#endif
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci#endif
203