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