18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * SNMP MIB entries for the IP subsystem. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Alan Cox <gw4pts@gw4pts.ampr.org> 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * We don't chose to implement SNMP in the kernel (this would 98c2ecf20Sopenharmony_ci * be silly as SNMP is a pain in the backside in places). We do 108c2ecf20Sopenharmony_ci * however need to collect the MIB statistics and export them 118c2ecf20Sopenharmony_ci * out of /proc (eventually) 128c2ecf20Sopenharmony_ci */ 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#ifndef _SNMP_H 158c2ecf20Sopenharmony_ci#define _SNMP_H 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#include <linux/cache.h> 188c2ecf20Sopenharmony_ci#include <linux/snmp.h> 198c2ecf20Sopenharmony_ci#include <linux/smp.h> 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci/* 228c2ecf20Sopenharmony_ci * Mibs are stored in array of unsigned long. 238c2ecf20Sopenharmony_ci */ 248c2ecf20Sopenharmony_ci/* 258c2ecf20Sopenharmony_ci * struct snmp_mib{} 268c2ecf20Sopenharmony_ci * - list of entries for particular API (such as /proc/net/snmp) 278c2ecf20Sopenharmony_ci * - name of entries. 288c2ecf20Sopenharmony_ci */ 298c2ecf20Sopenharmony_cistruct snmp_mib { 308c2ecf20Sopenharmony_ci const char *name; 318c2ecf20Sopenharmony_ci int entry; 328c2ecf20Sopenharmony_ci}; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci#define SNMP_MIB_ITEM(_name,_entry) { \ 358c2ecf20Sopenharmony_ci .name = _name, \ 368c2ecf20Sopenharmony_ci .entry = _entry, \ 378c2ecf20Sopenharmony_ci} 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci#define SNMP_MIB_SENTINEL { \ 408c2ecf20Sopenharmony_ci .name = NULL, \ 418c2ecf20Sopenharmony_ci .entry = 0, \ 428c2ecf20Sopenharmony_ci} 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci/* 458c2ecf20Sopenharmony_ci * We use unsigned longs for most mibs but u64 for ipstats. 468c2ecf20Sopenharmony_ci */ 478c2ecf20Sopenharmony_ci#include <linux/u64_stats_sync.h> 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci/* IPstats */ 508c2ecf20Sopenharmony_ci#define IPSTATS_MIB_MAX __IPSTATS_MIB_MAX 518c2ecf20Sopenharmony_cistruct ipstats_mib { 528c2ecf20Sopenharmony_ci /* mibs[] must be first field of struct ipstats_mib */ 538c2ecf20Sopenharmony_ci u64 mibs[IPSTATS_MIB_MAX]; 548c2ecf20Sopenharmony_ci struct u64_stats_sync syncp; 558c2ecf20Sopenharmony_ci}; 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci/* ICMP */ 588c2ecf20Sopenharmony_ci#define ICMP_MIB_MAX __ICMP_MIB_MAX 598c2ecf20Sopenharmony_cistruct icmp_mib { 608c2ecf20Sopenharmony_ci unsigned long mibs[ICMP_MIB_MAX]; 618c2ecf20Sopenharmony_ci}; 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci#define ICMPMSG_MIB_MAX __ICMPMSG_MIB_MAX 648c2ecf20Sopenharmony_cistruct icmpmsg_mib { 658c2ecf20Sopenharmony_ci atomic_long_t mibs[ICMPMSG_MIB_MAX]; 668c2ecf20Sopenharmony_ci}; 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci/* ICMP6 (IPv6-ICMP) */ 698c2ecf20Sopenharmony_ci#define ICMP6_MIB_MAX __ICMP6_MIB_MAX 708c2ecf20Sopenharmony_ci/* per network ns counters */ 718c2ecf20Sopenharmony_cistruct icmpv6_mib { 728c2ecf20Sopenharmony_ci unsigned long mibs[ICMP6_MIB_MAX]; 738c2ecf20Sopenharmony_ci}; 748c2ecf20Sopenharmony_ci/* per device counters, (shared on all cpus) */ 758c2ecf20Sopenharmony_cistruct icmpv6_mib_device { 768c2ecf20Sopenharmony_ci atomic_long_t mibs[ICMP6_MIB_MAX]; 778c2ecf20Sopenharmony_ci}; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci#define ICMP6MSG_MIB_MAX __ICMP6MSG_MIB_MAX 808c2ecf20Sopenharmony_ci/* per network ns counters */ 818c2ecf20Sopenharmony_cistruct icmpv6msg_mib { 828c2ecf20Sopenharmony_ci atomic_long_t mibs[ICMP6MSG_MIB_MAX]; 838c2ecf20Sopenharmony_ci}; 848c2ecf20Sopenharmony_ci/* per device counters, (shared on all cpus) */ 858c2ecf20Sopenharmony_cistruct icmpv6msg_mib_device { 868c2ecf20Sopenharmony_ci atomic_long_t mibs[ICMP6MSG_MIB_MAX]; 878c2ecf20Sopenharmony_ci}; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci/* TCP */ 918c2ecf20Sopenharmony_ci#define TCP_MIB_MAX __TCP_MIB_MAX 928c2ecf20Sopenharmony_cistruct tcp_mib { 938c2ecf20Sopenharmony_ci unsigned long mibs[TCP_MIB_MAX]; 948c2ecf20Sopenharmony_ci}; 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci/* UDP */ 978c2ecf20Sopenharmony_ci#define UDP_MIB_MAX __UDP_MIB_MAX 988c2ecf20Sopenharmony_cistruct udp_mib { 998c2ecf20Sopenharmony_ci unsigned long mibs[UDP_MIB_MAX]; 1008c2ecf20Sopenharmony_ci}; 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci/* Linux */ 1038c2ecf20Sopenharmony_ci#define LINUX_MIB_MAX __LINUX_MIB_MAX 1048c2ecf20Sopenharmony_cistruct linux_mib { 1058c2ecf20Sopenharmony_ci unsigned long mibs[LINUX_MIB_MAX]; 1068c2ecf20Sopenharmony_ci}; 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci/* Linux Xfrm */ 1098c2ecf20Sopenharmony_ci#define LINUX_MIB_XFRMMAX __LINUX_MIB_XFRMMAX 1108c2ecf20Sopenharmony_cistruct linux_xfrm_mib { 1118c2ecf20Sopenharmony_ci unsigned long mibs[LINUX_MIB_XFRMMAX]; 1128c2ecf20Sopenharmony_ci}; 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci/* Linux TLS */ 1158c2ecf20Sopenharmony_ci#define LINUX_MIB_TLSMAX __LINUX_MIB_TLSMAX 1168c2ecf20Sopenharmony_cistruct linux_tls_mib { 1178c2ecf20Sopenharmony_ci unsigned long mibs[LINUX_MIB_TLSMAX]; 1188c2ecf20Sopenharmony_ci}; 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci#define DEFINE_SNMP_STAT(type, name) \ 1218c2ecf20Sopenharmony_ci __typeof__(type) __percpu *name 1228c2ecf20Sopenharmony_ci#define DEFINE_SNMP_STAT_ATOMIC(type, name) \ 1238c2ecf20Sopenharmony_ci __typeof__(type) *name 1248c2ecf20Sopenharmony_ci#define DECLARE_SNMP_STAT(type, name) \ 1258c2ecf20Sopenharmony_ci extern __typeof__(type) __percpu *name 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci#define __SNMP_INC_STATS(mib, field) \ 1288c2ecf20Sopenharmony_ci __this_cpu_inc(mib->mibs[field]) 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci#define SNMP_INC_STATS_ATOMIC_LONG(mib, field) \ 1318c2ecf20Sopenharmony_ci atomic_long_inc(&mib->mibs[field]) 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci#define SNMP_INC_STATS(mib, field) \ 1348c2ecf20Sopenharmony_ci this_cpu_inc(mib->mibs[field]) 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci#define SNMP_DEC_STATS(mib, field) \ 1378c2ecf20Sopenharmony_ci this_cpu_dec(mib->mibs[field]) 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci#define __SNMP_ADD_STATS(mib, field, addend) \ 1408c2ecf20Sopenharmony_ci __this_cpu_add(mib->mibs[field], addend) 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci#define SNMP_ADD_STATS(mib, field, addend) \ 1438c2ecf20Sopenharmony_ci this_cpu_add(mib->mibs[field], addend) 1448c2ecf20Sopenharmony_ci#define SNMP_UPD_PO_STATS(mib, basefield, addend) \ 1458c2ecf20Sopenharmony_ci do { \ 1468c2ecf20Sopenharmony_ci __typeof__((mib->mibs) + 0) ptr = mib->mibs; \ 1478c2ecf20Sopenharmony_ci this_cpu_inc(ptr[basefield##PKTS]); \ 1488c2ecf20Sopenharmony_ci this_cpu_add(ptr[basefield##OCTETS], addend); \ 1498c2ecf20Sopenharmony_ci } while (0) 1508c2ecf20Sopenharmony_ci#define __SNMP_UPD_PO_STATS(mib, basefield, addend) \ 1518c2ecf20Sopenharmony_ci do { \ 1528c2ecf20Sopenharmony_ci __typeof__((mib->mibs) + 0) ptr = mib->mibs; \ 1538c2ecf20Sopenharmony_ci __this_cpu_inc(ptr[basefield##PKTS]); \ 1548c2ecf20Sopenharmony_ci __this_cpu_add(ptr[basefield##OCTETS], addend); \ 1558c2ecf20Sopenharmony_ci } while (0) 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci#if BITS_PER_LONG==32 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci#define __SNMP_ADD_STATS64(mib, field, addend) \ 1618c2ecf20Sopenharmony_ci do { \ 1628c2ecf20Sopenharmony_ci __typeof__(*mib) *ptr = raw_cpu_ptr(mib); \ 1638c2ecf20Sopenharmony_ci u64_stats_update_begin(&ptr->syncp); \ 1648c2ecf20Sopenharmony_ci ptr->mibs[field] += addend; \ 1658c2ecf20Sopenharmony_ci u64_stats_update_end(&ptr->syncp); \ 1668c2ecf20Sopenharmony_ci } while (0) 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci#define SNMP_ADD_STATS64(mib, field, addend) \ 1698c2ecf20Sopenharmony_ci do { \ 1708c2ecf20Sopenharmony_ci local_bh_disable(); \ 1718c2ecf20Sopenharmony_ci __SNMP_ADD_STATS64(mib, field, addend); \ 1728c2ecf20Sopenharmony_ci local_bh_enable(); \ 1738c2ecf20Sopenharmony_ci } while (0) 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci#define __SNMP_INC_STATS64(mib, field) SNMP_ADD_STATS64(mib, field, 1) 1768c2ecf20Sopenharmony_ci#define SNMP_INC_STATS64(mib, field) SNMP_ADD_STATS64(mib, field, 1) 1778c2ecf20Sopenharmony_ci#define __SNMP_UPD_PO_STATS64(mib, basefield, addend) \ 1788c2ecf20Sopenharmony_ci do { \ 1798c2ecf20Sopenharmony_ci __typeof__(*mib) *ptr; \ 1808c2ecf20Sopenharmony_ci ptr = raw_cpu_ptr((mib)); \ 1818c2ecf20Sopenharmony_ci u64_stats_update_begin(&ptr->syncp); \ 1828c2ecf20Sopenharmony_ci ptr->mibs[basefield##PKTS]++; \ 1838c2ecf20Sopenharmony_ci ptr->mibs[basefield##OCTETS] += addend; \ 1848c2ecf20Sopenharmony_ci u64_stats_update_end(&ptr->syncp); \ 1858c2ecf20Sopenharmony_ci } while (0) 1868c2ecf20Sopenharmony_ci#define SNMP_UPD_PO_STATS64(mib, basefield, addend) \ 1878c2ecf20Sopenharmony_ci do { \ 1888c2ecf20Sopenharmony_ci local_bh_disable(); \ 1898c2ecf20Sopenharmony_ci __SNMP_UPD_PO_STATS64(mib, basefield, addend); \ 1908c2ecf20Sopenharmony_ci local_bh_enable(); \ 1918c2ecf20Sopenharmony_ci } while (0) 1928c2ecf20Sopenharmony_ci#else 1938c2ecf20Sopenharmony_ci#define __SNMP_INC_STATS64(mib, field) __SNMP_INC_STATS(mib, field) 1948c2ecf20Sopenharmony_ci#define SNMP_INC_STATS64(mib, field) SNMP_INC_STATS(mib, field) 1958c2ecf20Sopenharmony_ci#define SNMP_DEC_STATS64(mib, field) SNMP_DEC_STATS(mib, field) 1968c2ecf20Sopenharmony_ci#define __SNMP_ADD_STATS64(mib, field, addend) __SNMP_ADD_STATS(mib, field, addend) 1978c2ecf20Sopenharmony_ci#define SNMP_ADD_STATS64(mib, field, addend) SNMP_ADD_STATS(mib, field, addend) 1988c2ecf20Sopenharmony_ci#define SNMP_UPD_PO_STATS64(mib, basefield, addend) SNMP_UPD_PO_STATS(mib, basefield, addend) 1998c2ecf20Sopenharmony_ci#define __SNMP_UPD_PO_STATS64(mib, basefield, addend) __SNMP_UPD_PO_STATS(mib, basefield, addend) 2008c2ecf20Sopenharmony_ci#endif 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ci#endif 203