12874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */ 21da177e4SLinus Torvalds /* 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * SNMP MIB entries for the IP subsystem. 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * Alan Cox <gw4pts@gw4pts.ampr.org> 71da177e4SLinus Torvalds * 81da177e4SLinus Torvalds * We don't chose to implement SNMP in the kernel (this would 91da177e4SLinus Torvalds * be silly as SNMP is a pain in the backside in places). We do 101da177e4SLinus Torvalds * however need to collect the MIB statistics and export them 111da177e4SLinus Torvalds * out of /proc (eventually) 121da177e4SLinus Torvalds */ 131da177e4SLinus Torvalds 141da177e4SLinus Torvalds #ifndef _SNMP_H 151da177e4SLinus Torvalds #define _SNMP_H 161da177e4SLinus Torvalds 171da177e4SLinus Torvalds #include <linux/cache.h> 181da177e4SLinus Torvalds #include <linux/snmp.h> 19d647b36aSHerbert Xu #include <linux/smp.h> 201da177e4SLinus Torvalds 211da177e4SLinus Torvalds /* 221da177e4SLinus Torvalds * Mibs are stored in array of unsigned long. 231da177e4SLinus Torvalds */ 241da177e4SLinus Torvalds /* 251da177e4SLinus Torvalds * struct snmp_mib{} 261da177e4SLinus Torvalds * - list of entries for particular API (such as /proc/net/snmp) 271da177e4SLinus Torvalds * - name of entries. 281da177e4SLinus Torvalds */ 291da177e4SLinus Torvalds struct snmp_mib { 305833929cSAlexey Dobriyan const char *name; 311da177e4SLinus Torvalds int entry; 321da177e4SLinus Torvalds }; 331da177e4SLinus Torvalds 341da177e4SLinus Torvalds #define SNMP_MIB_ITEM(_name,_entry) { \ 351da177e4SLinus Torvalds .name = _name, \ 361da177e4SLinus Torvalds .entry = _entry, \ 371da177e4SLinus Torvalds } 381da177e4SLinus Torvalds 391da177e4SLinus Torvalds #define SNMP_MIB_SENTINEL { \ 401da177e4SLinus Torvalds .name = NULL, \ 411da177e4SLinus Torvalds .entry = 0, \ 421da177e4SLinus Torvalds } 431da177e4SLinus Torvalds 441da177e4SLinus Torvalds /* 454ce3c183SEric Dumazet * We use unsigned longs for most mibs but u64 for ipstats. 461da177e4SLinus Torvalds */ 474ce3c183SEric Dumazet #include <linux/u64_stats_sync.h> 481da177e4SLinus Torvalds 491da177e4SLinus Torvalds /* IPstats */ 501da177e4SLinus Torvalds #define IPSTATS_MIB_MAX __IPSTATS_MIB_MAX 511da177e4SLinus Torvalds struct ipstats_mib { 524ce3c183SEric Dumazet /* mibs[] must be first field of struct ipstats_mib */ 534ce3c183SEric Dumazet u64 mibs[IPSTATS_MIB_MAX]; 544ce3c183SEric Dumazet struct u64_stats_sync syncp; 55ec733b15SEric Dumazet }; 561da177e4SLinus Torvalds 571da177e4SLinus Torvalds /* ICMP */ 58a9527a3bSShan Wei #define ICMP_MIB_MAX __ICMP_MIB_MAX 591da177e4SLinus Torvalds struct icmp_mib { 601da177e4SLinus Torvalds unsigned long mibs[ICMP_MIB_MAX]; 61ec733b15SEric Dumazet }; 621da177e4SLinus Torvalds 6396793b48SDavid L Stevens #define ICMPMSG_MIB_MAX __ICMPMSG_MIB_MAX 6496793b48SDavid L Stevens struct icmpmsg_mib { 65acb32ba3SEric Dumazet atomic_long_t mibs[ICMPMSG_MIB_MAX]; 66ec733b15SEric Dumazet }; 6796793b48SDavid L Stevens 681da177e4SLinus Torvalds /* ICMP6 (IPv6-ICMP) */ 691da177e4SLinus Torvalds #define ICMP6_MIB_MAX __ICMP6_MIB_MAX 70be281e55SEric Dumazet /* per network ns counters */ 711da177e4SLinus Torvalds struct icmpv6_mib { 721da177e4SLinus Torvalds unsigned long mibs[ICMP6_MIB_MAX]; 73ec733b15SEric Dumazet }; 74be281e55SEric Dumazet /* per device counters, (shared on all cpus) */ 75be281e55SEric Dumazet struct icmpv6_mib_device { 76be281e55SEric Dumazet atomic_long_t mibs[ICMP6_MIB_MAX]; 77be281e55SEric Dumazet }; 781da177e4SLinus Torvalds 7914878f75SDavid L Stevens #define ICMP6MSG_MIB_MAX __ICMP6MSG_MIB_MAX 80be281e55SEric Dumazet /* per network ns counters */ 8114878f75SDavid L Stevens struct icmpv6msg_mib { 822a24444fSEric Dumazet atomic_long_t mibs[ICMP6MSG_MIB_MAX]; 83ec733b15SEric Dumazet }; 84be281e55SEric Dumazet /* per device counters, (shared on all cpus) */ 85be281e55SEric Dumazet struct icmpv6msg_mib_device { 86be281e55SEric Dumazet atomic_long_t mibs[ICMP6MSG_MIB_MAX]; 87be281e55SEric Dumazet }; 8814878f75SDavid L Stevens 8914878f75SDavid L Stevens 901da177e4SLinus Torvalds /* TCP */ 911da177e4SLinus Torvalds #define TCP_MIB_MAX __TCP_MIB_MAX 921da177e4SLinus Torvalds struct tcp_mib { 931da177e4SLinus Torvalds unsigned long mibs[TCP_MIB_MAX]; 94ec733b15SEric Dumazet }; 951da177e4SLinus Torvalds 961da177e4SLinus Torvalds /* UDP */ 971da177e4SLinus Torvalds #define UDP_MIB_MAX __UDP_MIB_MAX 981da177e4SLinus Torvalds struct udp_mib { 991da177e4SLinus Torvalds unsigned long mibs[UDP_MIB_MAX]; 100ec733b15SEric Dumazet }; 1011da177e4SLinus Torvalds 1021da177e4SLinus Torvalds /* Linux */ 1031da177e4SLinus Torvalds #define LINUX_MIB_MAX __LINUX_MIB_MAX 1041da177e4SLinus Torvalds struct linux_mib { 1051da177e4SLinus Torvalds unsigned long mibs[LINUX_MIB_MAX]; 1061da177e4SLinus Torvalds }; 1071da177e4SLinus Torvalds 108558f82efSMasahide NAKAMURA /* Linux Xfrm */ 109558f82efSMasahide NAKAMURA #define LINUX_MIB_XFRMMAX __LINUX_MIB_XFRMMAX 110558f82efSMasahide NAKAMURA struct linux_xfrm_mib { 111558f82efSMasahide NAKAMURA unsigned long mibs[LINUX_MIB_XFRMMAX]; 112558f82efSMasahide NAKAMURA }; 1131da177e4SLinus Torvalds 114*d26b698dSJakub Kicinski /* Linux TLS */ 115*d26b698dSJakub Kicinski #define LINUX_MIB_TLSMAX __LINUX_MIB_TLSMAX 116*d26b698dSJakub Kicinski struct linux_tls_mib { 117*d26b698dSJakub Kicinski unsigned long mibs[LINUX_MIB_TLSMAX]; 118*d26b698dSJakub Kicinski }; 119*d26b698dSJakub Kicinski 1201da177e4SLinus Torvalds #define DEFINE_SNMP_STAT(type, name) \ 121698365faSWANG Cong __typeof__(type) __percpu *name 122be281e55SEric Dumazet #define DEFINE_SNMP_STAT_ATOMIC(type, name) \ 123be281e55SEric Dumazet __typeof__(type) *name 1241da177e4SLinus Torvalds #define DECLARE_SNMP_STAT(type, name) \ 125698365faSWANG Cong extern __typeof__(type) __percpu *name 1261da177e4SLinus Torvalds 12713415e46SEric Dumazet #define __SNMP_INC_STATS(mib, field) \ 128698365faSWANG Cong __this_cpu_inc(mib->mibs[field]) 1298f0ea0feSEric Dumazet 130be281e55SEric Dumazet #define SNMP_INC_STATS_ATOMIC_LONG(mib, field) \ 131be281e55SEric Dumazet atomic_long_inc(&mib->mibs[field]) 1328f0ea0feSEric Dumazet 1331da177e4SLinus Torvalds #define SNMP_INC_STATS(mib, field) \ 134698365faSWANG Cong this_cpu_inc(mib->mibs[field]) 1358f0ea0feSEric Dumazet 1361da177e4SLinus Torvalds #define SNMP_DEC_STATS(mib, field) \ 137698365faSWANG Cong this_cpu_dec(mib->mibs[field]) 1388f0ea0feSEric Dumazet 13913415e46SEric Dumazet #define __SNMP_ADD_STATS(mib, field, addend) \ 140698365faSWANG Cong __this_cpu_add(mib->mibs[field], addend) 1418f0ea0feSEric Dumazet 142aa2ea058STom Herbert #define SNMP_ADD_STATS(mib, field, addend) \ 143698365faSWANG Cong this_cpu_add(mib->mibs[field], addend) 144edf391ffSNeil Horman #define SNMP_UPD_PO_STATS(mib, basefield, addend) \ 145edf391ffSNeil Horman do { \ 14654003f11SSabrina Dubroca __typeof__((mib->mibs) + 0) ptr = mib->mibs; \ 147d25398dfSEric Dumazet this_cpu_inc(ptr[basefield##PKTS]); \ 148d25398dfSEric Dumazet this_cpu_add(ptr[basefield##OCTETS], addend); \ 149edf391ffSNeil Horman } while (0) 15013415e46SEric Dumazet #define __SNMP_UPD_PO_STATS(mib, basefield, addend) \ 151edf391ffSNeil Horman do { \ 15254003f11SSabrina Dubroca __typeof__((mib->mibs) + 0) ptr = mib->mibs; \ 153d25398dfSEric Dumazet __this_cpu_inc(ptr[basefield##PKTS]); \ 154d25398dfSEric Dumazet __this_cpu_add(ptr[basefield##OCTETS], addend); \ 155edf391ffSNeil Horman } while (0) 1564ce3c183SEric Dumazet 1574ce3c183SEric Dumazet 1584ce3c183SEric Dumazet #if BITS_PER_LONG==32 1594ce3c183SEric Dumazet 16013415e46SEric Dumazet #define __SNMP_ADD_STATS64(mib, field, addend) \ 1614ce3c183SEric Dumazet do { \ 162903ceff7SChristoph Lameter __typeof__(*mib) *ptr = raw_cpu_ptr(mib); \ 1634ce3c183SEric Dumazet u64_stats_update_begin(&ptr->syncp); \ 1644ce3c183SEric Dumazet ptr->mibs[field] += addend; \ 1654ce3c183SEric Dumazet u64_stats_update_end(&ptr->syncp); \ 1664ce3c183SEric Dumazet } while (0) 1678f0ea0feSEric Dumazet 1686aef70a8SEric Dumazet #define SNMP_ADD_STATS64(mib, field, addend) \ 1694ce3c183SEric Dumazet do { \ 170ba7863f4SEric Dumazet local_bh_disable(); \ 17113415e46SEric Dumazet __SNMP_ADD_STATS64(mib, field, addend); \ 172ba7863f4SEric Dumazet local_bh_enable(); \ 1734ce3c183SEric Dumazet } while (0) 1748f0ea0feSEric Dumazet 17513415e46SEric Dumazet #define __SNMP_INC_STATS64(mib, field) SNMP_ADD_STATS64(mib, field, 1) 1764ce3c183SEric Dumazet #define SNMP_INC_STATS64(mib, field) SNMP_ADD_STATS64(mib, field, 1) 17713415e46SEric Dumazet #define __SNMP_UPD_PO_STATS64(mib, basefield, addend) \ 1784ce3c183SEric Dumazet do { \ 179698365faSWANG Cong __typeof__(*mib) *ptr; \ 180903ceff7SChristoph Lameter ptr = raw_cpu_ptr((mib)); \ 1814ce3c183SEric Dumazet u64_stats_update_begin(&ptr->syncp); \ 1824ce3c183SEric Dumazet ptr->mibs[basefield##PKTS]++; \ 1834ce3c183SEric Dumazet ptr->mibs[basefield##OCTETS] += addend; \ 1844ce3c183SEric Dumazet u64_stats_update_end(&ptr->syncp); \ 1854ce3c183SEric Dumazet } while (0) 1868f0ea0feSEric Dumazet #define SNMP_UPD_PO_STATS64(mib, basefield, addend) \ 1878f0ea0feSEric Dumazet do { \ 188ba7863f4SEric Dumazet local_bh_disable(); \ 18913415e46SEric Dumazet __SNMP_UPD_PO_STATS64(mib, basefield, addend); \ 190ba7863f4SEric Dumazet local_bh_enable(); \ 1918f0ea0feSEric Dumazet } while (0) 1924ce3c183SEric Dumazet #else 19313415e46SEric Dumazet #define __SNMP_INC_STATS64(mib, field) __SNMP_INC_STATS(mib, field) 1944ce3c183SEric Dumazet #define SNMP_INC_STATS64(mib, field) SNMP_INC_STATS(mib, field) 1954ce3c183SEric Dumazet #define SNMP_DEC_STATS64(mib, field) SNMP_DEC_STATS(mib, field) 19613415e46SEric Dumazet #define __SNMP_ADD_STATS64(mib, field, addend) __SNMP_ADD_STATS(mib, field, addend) 1974ce3c183SEric Dumazet #define SNMP_ADD_STATS64(mib, field, addend) SNMP_ADD_STATS(mib, field, addend) 1984ce3c183SEric Dumazet #define SNMP_UPD_PO_STATS64(mib, basefield, addend) SNMP_UPD_PO_STATS(mib, basefield, addend) 19913415e46SEric Dumazet #define __SNMP_UPD_PO_STATS64(mib, basefield, addend) __SNMP_UPD_PO_STATS(mib, basefield, addend) 2004ce3c183SEric Dumazet #endif 2014ce3c183SEric Dumazet 2021da177e4SLinus Torvalds #endif 203