proc.c 19.5 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 24 25 26 27 28 29 30 31 32 33 34
/*
 * INET		An implementation of the TCP/IP protocol suite for the LINUX
 *		operating system.  INET is implemented using the  BSD Socket
 *		interface as the means of communication with the user level.
 *
 *		This file implements the various access functions for the
 *		PROC file system.  It is mainly used for debugging and
 *		statistics.
 *
 * Authors:	Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
 *		Gerald J. Heim, <heim@peanuts.informatik.uni-tuebingen.de>
 *		Fred Baumgarten, <dc6iq@insu1.etec.uni-karlsruhe.de>
 *		Erik Schoenfelder, <schoenfr@ibr.cs.tu-bs.de>
 *
 * Fixes:
 *		Alan Cox	:	UDP sockets show the rxqueue/txqueue
 *					using hint flag for the netinfo.
 *	Pauline Middelink	:	identd support
 *		Alan Cox	:	Make /proc safer.
 *	Erik Schoenfelder	:	/proc/net/snmp
 *		Alan Cox	:	Handle dead sockets properly.
 *	Gerhard Koerting	:	Show both timers
 *		Alan Cox	:	Allow inode to be NULL (kernel socket)
 *	Andi Kleen		:	Add support for open_requests and
 *					split functions for more readibility.
 *	Andi Kleen		:	Add support for /proc/net/netstat
 *	Arnaldo C. Melo		:	Convert to seq_file
 *
 *		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.
 */
#include <linux/types.h>
35
#include <net/net_namespace.h>
L
Linus Torvalds 已提交
36 37 38 39
#include <net/icmp.h>
#include <net/protocol.h>
#include <net/tcp.h>
#include <net/udp.h>
40
#include <net/udplite.h>
H
Herbert Xu 已提交
41
#include <linux/bottom_half.h>
42
#include <linux/inetdevice.h>
L
Linus Torvalds 已提交
43 44
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
45
#include <linux/export.h>
L
Linus Torvalds 已提交
46 47 48 49 50 51 52 53
#include <net/sock.h>
#include <net/raw.h>

/*
 *	Report socket allocation statistics [mea@utu.fi]
 */
static int sockstat_seq_show(struct seq_file *seq, void *v)
{
54
	struct net *net = seq->private;
H
Herbert Xu 已提交
55 56 57
	int orphans, sockets;

	local_bh_disable();
58
	orphans = percpu_counter_sum_positive(&tcp_orphan_count);
59
	sockets = proto_sockets_allocated_sum_positive(&tcp_prot);
H
Herbert Xu 已提交
60
	local_bh_enable();
61

L
Linus Torvalds 已提交
62
	socket_seq_show(seq);
E
Eric Dumazet 已提交
63
	seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %ld\n",
H
Herbert Xu 已提交
64 65
		   sock_prot_inuse_get(net, &tcp_prot), orphans,
		   tcp_death_row.tw_count, sockets,
66
		   proto_memory_allocated(&tcp_prot));
E
Eric Dumazet 已提交
67
	seq_printf(seq, "UDP: inuse %d mem %ld\n",
68
		   sock_prot_inuse_get(net, &udp_prot),
69
		   proto_memory_allocated(&udp_prot));
70
	seq_printf(seq, "UDPLITE: inuse %d\n",
71
		   sock_prot_inuse_get(net, &udplite_prot));
72
	seq_printf(seq, "RAW: inuse %d\n",
73
		   sock_prot_inuse_get(net, &raw_prot));
74
	seq_printf(seq,  "FRAG: inuse %d memory %d\n",
75
			ip_frag_nqueues(net), ip_frag_mem(net));
L
Linus Torvalds 已提交
76 77 78 79 80
	return 0;
}

static int sockstat_seq_open(struct inode *inode, struct file *file)
{
81
	return single_open_net(inode, file, sockstat_seq_show);
82 83
}

84
static const struct file_operations sockstat_seq_fops = {
L
Linus Torvalds 已提交
85 86 87 88
	.owner	 = THIS_MODULE,
	.open	 = sockstat_seq_open,
	.read	 = seq_read,
	.llseek	 = seq_lseek,
89
	.release = single_release_net,
L
Linus Torvalds 已提交
90 91 92
};

/* snmp items */
93
static const struct snmp_mib snmp4_ipstats_list[] = {
94
	SNMP_MIB_ITEM("InReceives", IPSTATS_MIB_INPKTS),
L
Linus Torvalds 已提交
95 96 97 98 99 100
	SNMP_MIB_ITEM("InHdrErrors", IPSTATS_MIB_INHDRERRORS),
	SNMP_MIB_ITEM("InAddrErrors", IPSTATS_MIB_INADDRERRORS),
	SNMP_MIB_ITEM("ForwDatagrams", IPSTATS_MIB_OUTFORWDATAGRAMS),
	SNMP_MIB_ITEM("InUnknownProtos", IPSTATS_MIB_INUNKNOWNPROTOS),
	SNMP_MIB_ITEM("InDiscards", IPSTATS_MIB_INDISCARDS),
	SNMP_MIB_ITEM("InDelivers", IPSTATS_MIB_INDELIVERS),
101
	SNMP_MIB_ITEM("OutRequests", IPSTATS_MIB_OUTPKTS),
L
Linus Torvalds 已提交
102 103 104 105 106 107 108 109 110 111 112 113
	SNMP_MIB_ITEM("OutDiscards", IPSTATS_MIB_OUTDISCARDS),
	SNMP_MIB_ITEM("OutNoRoutes", IPSTATS_MIB_OUTNOROUTES),
	SNMP_MIB_ITEM("ReasmTimeout", IPSTATS_MIB_REASMTIMEOUT),
	SNMP_MIB_ITEM("ReasmReqds", IPSTATS_MIB_REASMREQDS),
	SNMP_MIB_ITEM("ReasmOKs", IPSTATS_MIB_REASMOKS),
	SNMP_MIB_ITEM("ReasmFails", IPSTATS_MIB_REASMFAILS),
	SNMP_MIB_ITEM("FragOKs", IPSTATS_MIB_FRAGOKS),
	SNMP_MIB_ITEM("FragFails", IPSTATS_MIB_FRAGFAILS),
	SNMP_MIB_ITEM("FragCreates", IPSTATS_MIB_FRAGCREATES),
	SNMP_MIB_SENTINEL
};

114
/* Following items are displayed in /proc/net/netstat */
115 116 117 118 119 120 121
static const struct snmp_mib snmp4_ipextstats_list[] = {
	SNMP_MIB_ITEM("InNoRoutes", IPSTATS_MIB_INNOROUTES),
	SNMP_MIB_ITEM("InTruncatedPkts", IPSTATS_MIB_INTRUNCATEDPKTS),
	SNMP_MIB_ITEM("InMcastPkts", IPSTATS_MIB_INMCASTPKTS),
	SNMP_MIB_ITEM("OutMcastPkts", IPSTATS_MIB_OUTMCASTPKTS),
	SNMP_MIB_ITEM("InBcastPkts", IPSTATS_MIB_INBCASTPKTS),
	SNMP_MIB_ITEM("OutBcastPkts", IPSTATS_MIB_OUTBCASTPKTS),
122 123 124 125 126 127
	SNMP_MIB_ITEM("InOctets", IPSTATS_MIB_INOCTETS),
	SNMP_MIB_ITEM("OutOctets", IPSTATS_MIB_OUTOCTETS),
	SNMP_MIB_ITEM("InMcastOctets", IPSTATS_MIB_INMCASTOCTETS),
	SNMP_MIB_ITEM("OutMcastOctets", IPSTATS_MIB_OUTMCASTOCTETS),
	SNMP_MIB_ITEM("InBcastOctets", IPSTATS_MIB_INBCASTOCTETS),
	SNMP_MIB_ITEM("OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS),
128
	/* Non RFC4293 fields */
129
	SNMP_MIB_ITEM("InCsumErrors", IPSTATS_MIB_CSUMERRORS),
130 131 132 133
	SNMP_MIB_ITEM("InNoECTPkts", IPSTATS_MIB_NOECTPKTS),
	SNMP_MIB_ITEM("InECT1Pkts", IPSTATS_MIB_ECT1PKTS),
	SNMP_MIB_ITEM("InECT0Pkts", IPSTATS_MIB_ECT0PKTS),
	SNMP_MIB_ITEM("InCEPkts", IPSTATS_MIB_CEPKTS),
134 135 136
	SNMP_MIB_SENTINEL
};

A
Alexey Dobriyan 已提交
137 138
static const struct {
	const char *name;
139 140 141 142 143 144 145 146 147 148 149 150 151
	int index;
} icmpmibmap[] = {
	{ "DestUnreachs", ICMP_DEST_UNREACH },
	{ "TimeExcds", ICMP_TIME_EXCEEDED },
	{ "ParmProbs", ICMP_PARAMETERPROB },
	{ "SrcQuenchs", ICMP_SOURCE_QUENCH },
	{ "Redirects", ICMP_REDIRECT },
	{ "Echos", ICMP_ECHO },
	{ "EchoReps", ICMP_ECHOREPLY },
	{ "Timestamps", ICMP_TIMESTAMP },
	{ "TimestampReps", ICMP_TIMESTAMPREPLY },
	{ "AddrMasks", ICMP_ADDRESS },
	{ "AddrMaskReps", ICMP_ADDRESSREPLY },
S
Stephen Hemminger 已提交
152
	{ NULL, 0 }
153 154 155
};


156
static const struct snmp_mib snmp4_tcp_list[] = {
L
Linus Torvalds 已提交
157 158 159 160 161 162 163 164 165 166 167 168 169 170
	SNMP_MIB_ITEM("RtoAlgorithm", TCP_MIB_RTOALGORITHM),
	SNMP_MIB_ITEM("RtoMin", TCP_MIB_RTOMIN),
	SNMP_MIB_ITEM("RtoMax", TCP_MIB_RTOMAX),
	SNMP_MIB_ITEM("MaxConn", TCP_MIB_MAXCONN),
	SNMP_MIB_ITEM("ActiveOpens", TCP_MIB_ACTIVEOPENS),
	SNMP_MIB_ITEM("PassiveOpens", TCP_MIB_PASSIVEOPENS),
	SNMP_MIB_ITEM("AttemptFails", TCP_MIB_ATTEMPTFAILS),
	SNMP_MIB_ITEM("EstabResets", TCP_MIB_ESTABRESETS),
	SNMP_MIB_ITEM("CurrEstab", TCP_MIB_CURRESTAB),
	SNMP_MIB_ITEM("InSegs", TCP_MIB_INSEGS),
	SNMP_MIB_ITEM("OutSegs", TCP_MIB_OUTSEGS),
	SNMP_MIB_ITEM("RetransSegs", TCP_MIB_RETRANSSEGS),
	SNMP_MIB_ITEM("InErrs", TCP_MIB_INERRS),
	SNMP_MIB_ITEM("OutRsts", TCP_MIB_OUTRSTS),
171
	SNMP_MIB_ITEM("InCsumErrors", TCP_MIB_CSUMERRORS),
L
Linus Torvalds 已提交
172 173 174
	SNMP_MIB_SENTINEL
};

175
static const struct snmp_mib snmp4_udp_list[] = {
L
Linus Torvalds 已提交
176 177 178 179
	SNMP_MIB_ITEM("InDatagrams", UDP_MIB_INDATAGRAMS),
	SNMP_MIB_ITEM("NoPorts", UDP_MIB_NOPORTS),
	SNMP_MIB_ITEM("InErrors", UDP_MIB_INERRORS),
	SNMP_MIB_ITEM("OutDatagrams", UDP_MIB_OUTDATAGRAMS),
180 181
	SNMP_MIB_ITEM("RcvbufErrors", UDP_MIB_RCVBUFERRORS),
	SNMP_MIB_ITEM("SndbufErrors", UDP_MIB_SNDBUFERRORS),
182
	SNMP_MIB_ITEM("InCsumErrors", UDP_MIB_CSUMERRORS),
L
Linus Torvalds 已提交
183 184 185
	SNMP_MIB_SENTINEL
};

186
static const struct snmp_mib snmp4_net_list[] = {
L
Linus Torvalds 已提交
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234
	SNMP_MIB_ITEM("SyncookiesSent", LINUX_MIB_SYNCOOKIESSENT),
	SNMP_MIB_ITEM("SyncookiesRecv", LINUX_MIB_SYNCOOKIESRECV),
	SNMP_MIB_ITEM("SyncookiesFailed", LINUX_MIB_SYNCOOKIESFAILED),
	SNMP_MIB_ITEM("EmbryonicRsts", LINUX_MIB_EMBRYONICRSTS),
	SNMP_MIB_ITEM("PruneCalled", LINUX_MIB_PRUNECALLED),
	SNMP_MIB_ITEM("RcvPruned", LINUX_MIB_RCVPRUNED),
	SNMP_MIB_ITEM("OfoPruned", LINUX_MIB_OFOPRUNED),
	SNMP_MIB_ITEM("OutOfWindowIcmps", LINUX_MIB_OUTOFWINDOWICMPS),
	SNMP_MIB_ITEM("LockDroppedIcmps", LINUX_MIB_LOCKDROPPEDICMPS),
	SNMP_MIB_ITEM("ArpFilter", LINUX_MIB_ARPFILTER),
	SNMP_MIB_ITEM("TW", LINUX_MIB_TIMEWAITED),
	SNMP_MIB_ITEM("TWRecycled", LINUX_MIB_TIMEWAITRECYCLED),
	SNMP_MIB_ITEM("TWKilled", LINUX_MIB_TIMEWAITKILLED),
	SNMP_MIB_ITEM("PAWSPassive", LINUX_MIB_PAWSPASSIVEREJECTED),
	SNMP_MIB_ITEM("PAWSActive", LINUX_MIB_PAWSACTIVEREJECTED),
	SNMP_MIB_ITEM("PAWSEstab", LINUX_MIB_PAWSESTABREJECTED),
	SNMP_MIB_ITEM("DelayedACKs", LINUX_MIB_DELAYEDACKS),
	SNMP_MIB_ITEM("DelayedACKLocked", LINUX_MIB_DELAYEDACKLOCKED),
	SNMP_MIB_ITEM("DelayedACKLost", LINUX_MIB_DELAYEDACKLOST),
	SNMP_MIB_ITEM("ListenOverflows", LINUX_MIB_LISTENOVERFLOWS),
	SNMP_MIB_ITEM("ListenDrops", LINUX_MIB_LISTENDROPS),
	SNMP_MIB_ITEM("TCPPrequeued", LINUX_MIB_TCPPREQUEUED),
	SNMP_MIB_ITEM("TCPDirectCopyFromBacklog", LINUX_MIB_TCPDIRECTCOPYFROMBACKLOG),
	SNMP_MIB_ITEM("TCPDirectCopyFromPrequeue", LINUX_MIB_TCPDIRECTCOPYFROMPREQUEUE),
	SNMP_MIB_ITEM("TCPPrequeueDropped", LINUX_MIB_TCPPREQUEUEDROPPED),
	SNMP_MIB_ITEM("TCPHPHits", LINUX_MIB_TCPHPHITS),
	SNMP_MIB_ITEM("TCPHPHitsToUser", LINUX_MIB_TCPHPHITSTOUSER),
	SNMP_MIB_ITEM("TCPPureAcks", LINUX_MIB_TCPPUREACKS),
	SNMP_MIB_ITEM("TCPHPAcks", LINUX_MIB_TCPHPACKS),
	SNMP_MIB_ITEM("TCPRenoRecovery", LINUX_MIB_TCPRENORECOVERY),
	SNMP_MIB_ITEM("TCPSackRecovery", LINUX_MIB_TCPSACKRECOVERY),
	SNMP_MIB_ITEM("TCPSACKReneging", LINUX_MIB_TCPSACKRENEGING),
	SNMP_MIB_ITEM("TCPFACKReorder", LINUX_MIB_TCPFACKREORDER),
	SNMP_MIB_ITEM("TCPSACKReorder", LINUX_MIB_TCPSACKREORDER),
	SNMP_MIB_ITEM("TCPRenoReorder", LINUX_MIB_TCPRENOREORDER),
	SNMP_MIB_ITEM("TCPTSReorder", LINUX_MIB_TCPTSREORDER),
	SNMP_MIB_ITEM("TCPFullUndo", LINUX_MIB_TCPFULLUNDO),
	SNMP_MIB_ITEM("TCPPartialUndo", LINUX_MIB_TCPPARTIALUNDO),
	SNMP_MIB_ITEM("TCPDSACKUndo", LINUX_MIB_TCPDSACKUNDO),
	SNMP_MIB_ITEM("TCPLossUndo", LINUX_MIB_TCPLOSSUNDO),
	SNMP_MIB_ITEM("TCPLostRetransmit", LINUX_MIB_TCPLOSTRETRANSMIT),
	SNMP_MIB_ITEM("TCPRenoFailures", LINUX_MIB_TCPRENOFAILURES),
	SNMP_MIB_ITEM("TCPSackFailures", LINUX_MIB_TCPSACKFAILURES),
	SNMP_MIB_ITEM("TCPLossFailures", LINUX_MIB_TCPLOSSFAILURES),
	SNMP_MIB_ITEM("TCPFastRetrans", LINUX_MIB_TCPFASTRETRANS),
	SNMP_MIB_ITEM("TCPForwardRetrans", LINUX_MIB_TCPFORWARDRETRANS),
	SNMP_MIB_ITEM("TCPSlowStartRetrans", LINUX_MIB_TCPSLOWSTARTRETRANS),
	SNMP_MIB_ITEM("TCPTimeouts", LINUX_MIB_TCPTIMEOUTS),
N
Nandita Dukkipati 已提交
235
	SNMP_MIB_ITEM("TCPLossProbes", LINUX_MIB_TCPLOSSPROBES),
N
Nandita Dukkipati 已提交
236
	SNMP_MIB_ITEM("TCPLossProbeRecovery", LINUX_MIB_TCPLOSSPROBERECOVERY),
L
Linus Torvalds 已提交
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
	SNMP_MIB_ITEM("TCPRenoRecoveryFail", LINUX_MIB_TCPRENORECOVERYFAIL),
	SNMP_MIB_ITEM("TCPSackRecoveryFail", LINUX_MIB_TCPSACKRECOVERYFAIL),
	SNMP_MIB_ITEM("TCPSchedulerFailed", LINUX_MIB_TCPSCHEDULERFAILED),
	SNMP_MIB_ITEM("TCPRcvCollapsed", LINUX_MIB_TCPRCVCOLLAPSED),
	SNMP_MIB_ITEM("TCPDSACKOldSent", LINUX_MIB_TCPDSACKOLDSENT),
	SNMP_MIB_ITEM("TCPDSACKOfoSent", LINUX_MIB_TCPDSACKOFOSENT),
	SNMP_MIB_ITEM("TCPDSACKRecv", LINUX_MIB_TCPDSACKRECV),
	SNMP_MIB_ITEM("TCPDSACKOfoRecv", LINUX_MIB_TCPDSACKOFORECV),
	SNMP_MIB_ITEM("TCPAbortOnData", LINUX_MIB_TCPABORTONDATA),
	SNMP_MIB_ITEM("TCPAbortOnClose", LINUX_MIB_TCPABORTONCLOSE),
	SNMP_MIB_ITEM("TCPAbortOnMemory", LINUX_MIB_TCPABORTONMEMORY),
	SNMP_MIB_ITEM("TCPAbortOnTimeout", LINUX_MIB_TCPABORTONTIMEOUT),
	SNMP_MIB_ITEM("TCPAbortOnLinger", LINUX_MIB_TCPABORTONLINGER),
	SNMP_MIB_ITEM("TCPAbortFailed", LINUX_MIB_TCPABORTFAILED),
	SNMP_MIB_ITEM("TCPMemoryPressures", LINUX_MIB_TCPMEMORYPRESSURES),
252 253 254
	SNMP_MIB_ITEM("TCPSACKDiscard", LINUX_MIB_TCPSACKDISCARD),
	SNMP_MIB_ITEM("TCPDSACKIgnoredOld", LINUX_MIB_TCPDSACKIGNOREDOLD),
	SNMP_MIB_ITEM("TCPDSACKIgnoredNoUndo", LINUX_MIB_TCPDSACKIGNOREDNOUNDO),
255
	SNMP_MIB_ITEM("TCPSpuriousRTOs", LINUX_MIB_TCPSPURIOUSRTOS),
256 257
	SNMP_MIB_ITEM("TCPMD5NotFound", LINUX_MIB_TCPMD5NOTFOUND),
	SNMP_MIB_ITEM("TCPMD5Unexpected", LINUX_MIB_TCPMD5UNEXPECTED),
258 259 260
	SNMP_MIB_ITEM("TCPSackShifted", LINUX_MIB_SACKSHIFTED),
	SNMP_MIB_ITEM("TCPSackMerged", LINUX_MIB_SACKMERGED),
	SNMP_MIB_ITEM("TCPSackShiftFallback", LINUX_MIB_SACKSHIFTFALLBACK),
261 262
	SNMP_MIB_ITEM("TCPBacklogDrop", LINUX_MIB_TCPBACKLOGDROP),
	SNMP_MIB_ITEM("TCPMinTTLDrop", LINUX_MIB_TCPMINTTLDROP),
263
	SNMP_MIB_ITEM("TCPDeferAcceptDrop", LINUX_MIB_TCPDEFERACCEPTDROP),
264
	SNMP_MIB_ITEM("IPReversePathFilter", LINUX_MIB_IPRPFILTER),
265
	SNMP_MIB_ITEM("TCPTimeWaitOverflow", LINUX_MIB_TCPTIMEWAITOVERFLOW),
266 267
	SNMP_MIB_ITEM("TCPReqQFullDoCookies", LINUX_MIB_TCPREQQFULLDOCOOKIES),
	SNMP_MIB_ITEM("TCPReqQFullDrop", LINUX_MIB_TCPREQQFULLDROP),
268
	SNMP_MIB_ITEM("TCPRetransFail", LINUX_MIB_TCPRETRANSFAIL),
269
	SNMP_MIB_ITEM("TCPRcvCoalesce", LINUX_MIB_TCPRCVCOALESCE),
E
Eric Dumazet 已提交
270 271 272
	SNMP_MIB_ITEM("TCPOFOQueue", LINUX_MIB_TCPOFOQUEUE),
	SNMP_MIB_ITEM("TCPOFODrop", LINUX_MIB_TCPOFODROP),
	SNMP_MIB_ITEM("TCPOFOMerge", LINUX_MIB_TCPOFOMERGE),
E
Eric Dumazet 已提交
273
	SNMP_MIB_ITEM("TCPChallengeACK", LINUX_MIB_TCPCHALLENGEACK),
E
Eric Dumazet 已提交
274
	SNMP_MIB_ITEM("TCPSYNChallenge", LINUX_MIB_TCPSYNCHALLENGE),
275
	SNMP_MIB_ITEM("TCPFastOpenActive", LINUX_MIB_TCPFASTOPENACTIVE),
276
	SNMP_MIB_ITEM("TCPFastOpenActiveFail", LINUX_MIB_TCPFASTOPENACTIVEFAIL),
277 278 279 280
	SNMP_MIB_ITEM("TCPFastOpenPassive", LINUX_MIB_TCPFASTOPENPASSIVE),
	SNMP_MIB_ITEM("TCPFastOpenPassiveFail", LINUX_MIB_TCPFASTOPENPASSIVEFAIL),
	SNMP_MIB_ITEM("TCPFastOpenListenOverflow", LINUX_MIB_TCPFASTOPENLISTENOVERFLOW),
	SNMP_MIB_ITEM("TCPFastOpenCookieReqd", LINUX_MIB_TCPFASTOPENCOOKIEREQD),
281
	SNMP_MIB_ITEM("TCPSpuriousRtxHostQueues", LINUX_MIB_TCPSPURIOUS_RTX_HOSTQUEUES),
282
	SNMP_MIB_ITEM("BusyPollRxPackets", LINUX_MIB_BUSYPOLLRXPACKETS),
E
Eric Dumazet 已提交
283
	SNMP_MIB_ITEM("TCPAutoCorking", LINUX_MIB_TCPAUTOCORKING),
284 285 286
	SNMP_MIB_ITEM("TCPFromZeroWindowAdv", LINUX_MIB_TCPFROMZEROWINDOWADV),
	SNMP_MIB_ITEM("TCPToZeroWindowAdv", LINUX_MIB_TCPTOZEROWINDOWADV),
	SNMP_MIB_ITEM("TCPWantZeroWindowAdv", LINUX_MIB_TCPWANTZEROWINDOWADV),
287 288
	SNMP_MIB_ITEM("TCPSynRetrans", LINUX_MIB_TCPSYNRETRANS),
	SNMP_MIB_ITEM("TCPOrigDataSent", LINUX_MIB_TCPORIGDATASENT),
L
Linus Torvalds 已提交
289 290 291
	SNMP_MIB_SENTINEL
};

292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
static void icmpmsg_put_line(struct seq_file *seq, unsigned long *vals,
			     unsigned short *type, int count)
{
	int j;

	if (count) {
		seq_printf(seq, "\nIcmpMsg:");
		for (j = 0; j < count; ++j)
			seq_printf(seq, " %sType%u",
				type[j] & 0x100 ? "Out" : "In",
				type[j] & 0xff);
		seq_printf(seq, "\nIcmpMsg:");
		for (j = 0; j < count; ++j)
			seq_printf(seq, " %lu", vals[j]);
	}
}

309 310 311 312
static void icmpmsg_put(struct seq_file *seq)
{
#define PERLINE	16

313 314 315
	int i, count;
	unsigned short type[PERLINE];
	unsigned long vals[PERLINE], val;
316
	struct net *net = seq->private;
317 318 319

	count = 0;
	for (i = 0; i < ICMPMSG_MIB_MAX; i++) {
320
		val = atomic_long_read(&net->mib.icmpmsg_statistics->mibs[i]);
321 322 323 324 325 326 327 328
		if (val) {
			type[count] = i;
			vals[count++] = val;
		}
		if (count == PERLINE) {
			icmpmsg_put_line(seq, vals, type, count);
			count = 0;
		}
329
	}
330
	icmpmsg_put_line(seq, vals, type, count);
331 332 333 334 335 336 337

#undef PERLINE
}

static void icmp_put(struct seq_file *seq)
{
	int i;
338
	struct net *net = seq->private;
339
	atomic_long_t *ptr = net->mib.icmpmsg_statistics->mibs;
340

341
	seq_puts(seq, "\nIcmp: InMsgs InErrors InCsumErrors");
342
	for (i = 0; icmpmibmap[i].name != NULL; i++)
343 344
		seq_printf(seq, " In%s", icmpmibmap[i].name);
	seq_printf(seq, " OutMsgs OutErrors");
345
	for (i = 0; icmpmibmap[i].name != NULL; i++)
346
		seq_printf(seq, " Out%s", icmpmibmap[i].name);
347
	seq_printf(seq, "\nIcmp: %lu %lu %lu",
348
		snmp_fold_field((void __percpu **) net->mib.icmp_statistics, ICMP_MIB_INMSGS),
349 350
		snmp_fold_field((void __percpu **) net->mib.icmp_statistics, ICMP_MIB_INERRORS),
		snmp_fold_field((void __percpu **) net->mib.icmp_statistics, ICMP_MIB_CSUMERRORS));
351
	for (i = 0; icmpmibmap[i].name != NULL; i++)
352
		seq_printf(seq, " %lu",
353
			   atomic_long_read(ptr + icmpmibmap[i].index));
354
	seq_printf(seq, " %lu %lu",
355 356
		snmp_fold_field((void __percpu **) net->mib.icmp_statistics, ICMP_MIB_OUTMSGS),
		snmp_fold_field((void __percpu **) net->mib.icmp_statistics, ICMP_MIB_OUTERRORS));
357
	for (i = 0; icmpmibmap[i].name != NULL; i++)
358
		seq_printf(seq, " %lu",
359
			   atomic_long_read(ptr + (icmpmibmap[i].index | 0x100)));
360 361
}

L
Linus Torvalds 已提交
362 363 364 365 366 367
/*
 *	Called from the PROCfs module. This outputs /proc/net/snmp.
 */
static int snmp_seq_show(struct seq_file *seq, void *v)
{
	int i;
368
	struct net *net = seq->private;
L
Linus Torvalds 已提交
369 370 371 372 373 374 375

	seq_puts(seq, "Ip: Forwarding DefaultTTL");

	for (i = 0; snmp4_ipstats_list[i].name != NULL; i++)
		seq_printf(seq, " %s", snmp4_ipstats_list[i].name);

	seq_printf(seq, "\nIp: %d %d",
376
		   IPV4_DEVCONF_ALL(net, FORWARDING) ? 1 : 2,
377
		   sysctl_ip_default_ttl);
L
Linus Torvalds 已提交
378

379
	BUILD_BUG_ON(offsetof(struct ipstats_mib, mibs) != 0);
L
Linus Torvalds 已提交
380
	for (i = 0; snmp4_ipstats_list[i].name != NULL; i++)
381 382 383 384
		seq_printf(seq, " %llu",
			   snmp_fold_field64((void __percpu **)net->mib.ip_statistics,
					     snmp4_ipstats_list[i].entry,
					     offsetof(struct ipstats_mib, syncp)));
L
Linus Torvalds 已提交
385

386 387
	icmp_put(seq);	/* RFC 2011 compatibility */
	icmpmsg_put(seq);
L
Linus Torvalds 已提交
388 389 390 391 392 393 394 395 396 397

	seq_puts(seq, "\nTcp:");
	for (i = 0; snmp4_tcp_list[i].name != NULL; i++)
		seq_printf(seq, " %s", snmp4_tcp_list[i].name);

	seq_puts(seq, "\nTcp:");
	for (i = 0; snmp4_tcp_list[i].name != NULL; i++) {
		/* MaxConn field is signed, RFC 2012 */
		if (snmp4_tcp_list[i].entry == TCP_MIB_MAXCONN)
			seq_printf(seq, " %ld",
398
				   snmp_fold_field((void __percpu **)net->mib.tcp_statistics,
399
						   snmp4_tcp_list[i].entry));
L
Linus Torvalds 已提交
400 401
		else
			seq_printf(seq, " %lu",
402
				   snmp_fold_field((void __percpu **)net->mib.tcp_statistics,
403
						   snmp4_tcp_list[i].entry));
L
Linus Torvalds 已提交
404 405 406 407 408 409 410 411 412
	}

	seq_puts(seq, "\nUdp:");
	for (i = 0; snmp4_udp_list[i].name != NULL; i++)
		seq_printf(seq, " %s", snmp4_udp_list[i].name);

	seq_puts(seq, "\nUdp:");
	for (i = 0; snmp4_udp_list[i].name != NULL; i++)
		seq_printf(seq, " %lu",
413
			   snmp_fold_field((void __percpu **)net->mib.udp_statistics,
414
					   snmp4_udp_list[i].entry));
L
Linus Torvalds 已提交
415

416 417 418 419 420 421 422 423
	/* the UDP and UDP-Lite MIBs are the same */
	seq_puts(seq, "\nUdpLite:");
	for (i = 0; snmp4_udp_list[i].name != NULL; i++)
		seq_printf(seq, " %s", snmp4_udp_list[i].name);

	seq_puts(seq, "\nUdpLite:");
	for (i = 0; snmp4_udp_list[i].name != NULL; i++)
		seq_printf(seq, " %lu",
424
			   snmp_fold_field((void __percpu **)net->mib.udplite_statistics,
425
					   snmp4_udp_list[i].entry));
426

L
Linus Torvalds 已提交
427 428 429 430 431 432
	seq_putc(seq, '\n');
	return 0;
}

static int snmp_seq_open(struct inode *inode, struct file *file)
{
433
	return single_open_net(inode, file, snmp_seq_show);
434 435
}

436
static const struct file_operations snmp_seq_fops = {
L
Linus Torvalds 已提交
437 438 439 440
	.owner	 = THIS_MODULE,
	.open	 = snmp_seq_open,
	.read	 = seq_read,
	.llseek	 = seq_lseek,
441
	.release = single_release_net,
L
Linus Torvalds 已提交
442 443
};

444 445


L
Linus Torvalds 已提交
446 447 448 449 450 451
/*
 *	Output /proc/net/netstat
 */
static int netstat_seq_show(struct seq_file *seq, void *v)
{
	int i;
452
	struct net *net = seq->private;
L
Linus Torvalds 已提交
453 454 455 456 457 458 459 460

	seq_puts(seq, "TcpExt:");
	for (i = 0; snmp4_net_list[i].name != NULL; i++)
		seq_printf(seq, " %s", snmp4_net_list[i].name);

	seq_puts(seq, "\nTcpExt:");
	for (i = 0; snmp4_net_list[i].name != NULL; i++)
		seq_printf(seq, " %lu",
461
			   snmp_fold_field((void __percpu **)net->mib.net_statistics,
462
					   snmp4_net_list[i].entry));
L
Linus Torvalds 已提交
463

464 465 466 467 468 469
	seq_puts(seq, "\nIpExt:");
	for (i = 0; snmp4_ipextstats_list[i].name != NULL; i++)
		seq_printf(seq, " %s", snmp4_ipextstats_list[i].name);

	seq_puts(seq, "\nIpExt:");
	for (i = 0; snmp4_ipextstats_list[i].name != NULL; i++)
470 471 472 473
		seq_printf(seq, " %llu",
			   snmp_fold_field64((void __percpu **)net->mib.ip_statistics,
					     snmp4_ipextstats_list[i].entry,
					     offsetof(struct ipstats_mib, syncp)));
474

L
Linus Torvalds 已提交
475 476 477 478 479 480
	seq_putc(seq, '\n');
	return 0;
}

static int netstat_seq_open(struct inode *inode, struct file *file)
{
481
	return single_open_net(inode, file, netstat_seq_show);
482 483
}

484
static const struct file_operations netstat_seq_fops = {
L
Linus Torvalds 已提交
485 486 487 488
	.owner	 = THIS_MODULE,
	.open	 = netstat_seq_open,
	.read	 = seq_read,
	.llseek	 = seq_lseek,
489
	.release = single_release_net,
L
Linus Torvalds 已提交
490 491
};

492 493
static __net_init int ip_proc_init_net(struct net *net)
{
494 495
	if (!proc_create("sockstat", S_IRUGO, net->proc_net,
			 &sockstat_seq_fops))
496
		goto out_sockstat;
497
	if (!proc_create("netstat", S_IRUGO, net->proc_net, &netstat_seq_fops))
498
		goto out_netstat;
499
	if (!proc_create("snmp", S_IRUGO, net->proc_net, &snmp_seq_fops))
500
		goto out_snmp;
501

502
	return 0;
503

504
out_snmp:
505
	remove_proc_entry("netstat", net->proc_net);
506
out_netstat:
507
	remove_proc_entry("sockstat", net->proc_net);
508
out_sockstat:
509
	return -ENOMEM;
510 511 512 513
}

static __net_exit void ip_proc_exit_net(struct net *net)
{
514 515 516
	remove_proc_entry("snmp", net->proc_net);
	remove_proc_entry("netstat", net->proc_net);
	remove_proc_entry("sockstat", net->proc_net);
517 518 519 520 521 522 523
}

static __net_initdata struct pernet_operations ip_proc_ops = {
	.init = ip_proc_init_net,
	.exit = ip_proc_exit_net,
};

L
Linus Torvalds 已提交
524 525
int __init ip_misc_proc_init(void)
{
526
	return register_pernet_subsys(&ip_proc_ops);
L
Linus Torvalds 已提交
527
}
528