snmp.h 5.9 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*
 *
 *		SNMP MIB entries for the IP subsystem.
 *		
 *		Alan Cox <gw4pts@gw4pts.ampr.org>
 *
 *		We don't chose to implement SNMP in the kernel (this would
 *		be silly as SNMP is a pain in the backside in places). We do
 *		however need to collect the MIB statistics and export them
 *		out of /proc (eventually)
 *
 *		This program is free software; you can redistribute it and/or
 *		modify it under the terms of the GNU General Public License
 *		as published by the Free Software Foundation; either version
 *		2 of the License, or (at your option) any later version.
 *
 */
 
#ifndef _SNMP_H
#define _SNMP_H

#include <linux/cache.h>
#include <linux/snmp.h>
24
#include <linux/smp.h>
L
Linus Torvalds 已提交
25 26 27 28 29 30 31 32 33 34

/*
 * Mibs are stored in array of unsigned long.
 */
/*
 * struct snmp_mib{}
 *  - list of entries for particular API (such as /proc/net/snmp)
 *  - name of entries.
 */
struct snmp_mib {
A
Alexey Dobriyan 已提交
35
	const char *name;
L
Linus Torvalds 已提交
36 37 38 39 40 41 42 43 44 45 46 47 48 49
	int entry;
};

#define SNMP_MIB_ITEM(_name,_entry)	{	\
	.name = _name,				\
	.entry = _entry,			\
}

#define SNMP_MIB_SENTINEL {	\
	.name = NULL,		\
	.entry = 0,		\
}

/*
50
 * We use unsigned longs for most mibs but u64 for ipstats.
L
Linus Torvalds 已提交
51
 */
52
#include <linux/u64_stats_sync.h>
L
Linus Torvalds 已提交
53 54 55 56

/* IPstats */
#define IPSTATS_MIB_MAX	__IPSTATS_MIB_MAX
struct ipstats_mib {
57 58 59
	/* mibs[] must be first field of struct ipstats_mib */
	u64		mibs[IPSTATS_MIB_MAX];
	struct u64_stats_sync syncp;
E
Eric Dumazet 已提交
60
};
L
Linus Torvalds 已提交
61 62

/* ICMP */
63
#define ICMP_MIB_MAX	__ICMP_MIB_MAX
L
Linus Torvalds 已提交
64 65
struct icmp_mib {
	unsigned long	mibs[ICMP_MIB_MAX];
E
Eric Dumazet 已提交
66
};
L
Linus Torvalds 已提交
67

68 69 70
#define ICMPMSG_MIB_MAX	__ICMPMSG_MIB_MAX
struct icmpmsg_mib {
	unsigned long	mibs[ICMPMSG_MIB_MAX];
E
Eric Dumazet 已提交
71
};
72

L
Linus Torvalds 已提交
73 74
/* ICMP6 (IPv6-ICMP) */
#define ICMP6_MIB_MAX	__ICMP6_MIB_MAX
75
/* per network ns counters */
L
Linus Torvalds 已提交
76 77
struct icmpv6_mib {
	unsigned long	mibs[ICMP6_MIB_MAX];
E
Eric Dumazet 已提交
78
};
79 80 81 82
/* per device counters, (shared on all cpus) */
struct icmpv6_mib_device {
	atomic_long_t	mibs[ICMP6_MIB_MAX];
};
L
Linus Torvalds 已提交
83

84
#define ICMP6MSG_MIB_MAX  __ICMP6MSG_MIB_MAX
85
/* per network ns counters */
86 87
struct icmpv6msg_mib {
	unsigned long	mibs[ICMP6MSG_MIB_MAX];
E
Eric Dumazet 已提交
88
};
89 90 91 92
/* per device counters, (shared on all cpus) */
struct icmpv6msg_mib_device {
	atomic_long_t	mibs[ICMP6MSG_MIB_MAX];
};
93 94


L
Linus Torvalds 已提交
95 96 97 98
/* TCP */
#define TCP_MIB_MAX	__TCP_MIB_MAX
struct tcp_mib {
	unsigned long	mibs[TCP_MIB_MAX];
E
Eric Dumazet 已提交
99
};
L
Linus Torvalds 已提交
100 101 102 103 104

/* UDP */
#define UDP_MIB_MAX	__UDP_MIB_MAX
struct udp_mib {
	unsigned long	mibs[UDP_MIB_MAX];
E
Eric Dumazet 已提交
105
};
L
Linus Torvalds 已提交
106 107 108 109 110 111 112

/* Linux */
#define LINUX_MIB_MAX	__LINUX_MIB_MAX
struct linux_mib {
	unsigned long	mibs[LINUX_MIB_MAX];
};

113 114 115 116 117
/* Linux Xfrm */
#define LINUX_MIB_XFRMMAX	__LINUX_MIB_XFRMMAX
struct linux_xfrm_mib {
	unsigned long	mibs[LINUX_MIB_XFRMMAX];
};
L
Linus Torvalds 已提交
118

E
Eric Dumazet 已提交
119 120
#define SNMP_ARRAY_SZ 1

L
Linus Torvalds 已提交
121
#define DEFINE_SNMP_STAT(type, name)	\
E
Eric Dumazet 已提交
122
	__typeof__(type) __percpu *name[SNMP_ARRAY_SZ]
123 124
#define DEFINE_SNMP_STAT_ATOMIC(type, name)	\
	__typeof__(type) *name
L
Linus Torvalds 已提交
125
#define DECLARE_SNMP_STAT(type, name)	\
E
Eric Dumazet 已提交
126
	extern __typeof__(type) __percpu *name[SNMP_ARRAY_SZ]
L
Linus Torvalds 已提交
127

128 129
#define SNMP_INC_STATS_BH(mib, field)	\
			__this_cpu_inc(mib[0]->mibs[field])
E
Eric Dumazet 已提交
130

131
#define SNMP_INC_STATS_USER(mib, field)	\
E
Eric Dumazet 已提交
132 133
			irqsafe_cpu_inc(mib[0]->mibs[field])

134 135
#define SNMP_INC_STATS_ATOMIC_LONG(mib, field)	\
			atomic_long_inc(&mib->mibs[field])
E
Eric Dumazet 已提交
136

137
#define SNMP_INC_STATS(mib, field)	\
E
Eric Dumazet 已提交
138 139
			irqsafe_cpu_inc(mib[0]->mibs[field])

140
#define SNMP_DEC_STATS(mib, field)	\
E
Eric Dumazet 已提交
141 142
			irqsafe_cpu_dec(mib[0]->mibs[field])

143 144
#define SNMP_ADD_STATS_BH(mib, field, addend)	\
			__this_cpu_add(mib[0]->mibs[field], addend)
E
Eric Dumazet 已提交
145

146
#define SNMP_ADD_STATS_USER(mib, field, addend)	\
E
Eric Dumazet 已提交
147 148
			irqsafe_cpu_add(mib[0]->mibs[field], addend)

149
#define SNMP_ADD_STATS(mib, field, addend)	\
E
Eric Dumazet 已提交
150
			irqsafe_cpu_add(mib[0]->mibs[field], addend)
151 152 153 154
/*
 * Use "__typeof__(*mib[0]) *ptr" instead of "__typeof__(mib[0]) ptr"
 * to make @ptr a non-percpu pointer.
 */
155 156
#define SNMP_UPD_PO_STATS(mib, basefield, addend)	\
	do { \
E
Eric Dumazet 已提交
157 158
		irqsafe_cpu_inc(mib[0]->mibs[basefield##PKTS]);		\
		irqsafe_cpu_add(mib[0]->mibs[basefield##OCTETS], addend);	\
159 160 161
	} while (0)
#define SNMP_UPD_PO_STATS_BH(mib, basefield, addend)	\
	do { \
E
Eric Dumazet 已提交
162 163
		__this_cpu_inc(mib[0]->mibs[basefield##PKTS]);		\
		__this_cpu_add(mib[0]->mibs[basefield##OCTETS], addend);	\
164
	} while (0)
165 166 167 168 169 170 171 172 173 174 175


#if BITS_PER_LONG==32

#define SNMP_ADD_STATS64_BH(mib, field, addend) 			\
	do {								\
		__typeof__(*mib[0]) *ptr = __this_cpu_ptr((mib)[0]);	\
		u64_stats_update_begin(&ptr->syncp);			\
		ptr->mibs[field] += addend;				\
		u64_stats_update_end(&ptr->syncp);			\
	} while (0)
E
Eric Dumazet 已提交
176

177 178
#define SNMP_ADD_STATS64_USER(mib, field, addend) 			\
	do {								\
E
Eric Dumazet 已提交
179 180 181
		local_bh_disable();					\
		SNMP_ADD_STATS64_BH(mib, field, addend);		\
		local_bh_enable();					\
182
	} while (0)
E
Eric Dumazet 已提交
183

184
#define SNMP_ADD_STATS64(mib, field, addend)				\
E
Eric Dumazet 已提交
185 186
		SNMP_ADD_STATS64_USER(mib, field, addend)

187 188 189 190 191 192
#define SNMP_INC_STATS64_BH(mib, field) SNMP_ADD_STATS64_BH(mib, field, 1)
#define SNMP_INC_STATS64_USER(mib, field) SNMP_ADD_STATS64_USER(mib, field, 1)
#define SNMP_INC_STATS64(mib, field) SNMP_ADD_STATS64(mib, field, 1)
#define SNMP_UPD_PO_STATS64_BH(mib, basefield, addend)			\
	do {								\
		__typeof__(*mib[0]) *ptr;				\
193
		ptr = __this_cpu_ptr((mib)[0]);				\
194 195 196 197 198
		u64_stats_update_begin(&ptr->syncp);			\
		ptr->mibs[basefield##PKTS]++;				\
		ptr->mibs[basefield##OCTETS] += addend;			\
		u64_stats_update_end(&ptr->syncp);			\
	} while (0)
E
Eric Dumazet 已提交
199 200 201 202 203 204
#define SNMP_UPD_PO_STATS64(mib, basefield, addend)			\
	do {								\
		local_bh_disable();					\
		SNMP_UPD_PO_STATS64_BH(mib, basefield, addend);		\
		local_bh_enable();					\
	} while (0)
205 206 207 208 209 210 211 212 213 214 215 216
#else
#define SNMP_INC_STATS64_BH(mib, field)		SNMP_INC_STATS_BH(mib, field)
#define SNMP_INC_STATS64_USER(mib, field)	SNMP_INC_STATS_USER(mib, field)
#define SNMP_INC_STATS64(mib, field)		SNMP_INC_STATS(mib, field)
#define SNMP_DEC_STATS64(mib, field)		SNMP_DEC_STATS(mib, field)
#define SNMP_ADD_STATS64_BH(mib, field, addend) SNMP_ADD_STATS_BH(mib, field, addend)
#define SNMP_ADD_STATS64_USER(mib, field, addend) SNMP_ADD_STATS_USER(mib, field, addend)
#define SNMP_ADD_STATS64(mib, field, addend)	SNMP_ADD_STATS(mib, field, addend)
#define SNMP_UPD_PO_STATS64(mib, basefield, addend) SNMP_UPD_PO_STATS(mib, basefield, addend)
#define SNMP_UPD_PO_STATS64_BH(mib, basefield, addend) SNMP_UPD_PO_STATS_BH(mib, basefield, addend)
#endif

L
Linus Torvalds 已提交
217
#endif