cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

proc.c (21484B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * INET		An implementation of the TCP/IP protocol suite for the LINUX
      4 *		operating system.  INET is implemented using the  BSD Socket
      5 *		interface as the means of communication with the user level.
      6 *
      7 *		This file implements the various access functions for the
      8 *		PROC file system.  It is mainly used for debugging and
      9 *		statistics.
     10 *
     11 * Authors:	Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
     12 *		Gerald J. Heim, <heim@peanuts.informatik.uni-tuebingen.de>
     13 *		Fred Baumgarten, <dc6iq@insu1.etec.uni-karlsruhe.de>
     14 *		Erik Schoenfelder, <schoenfr@ibr.cs.tu-bs.de>
     15 *
     16 * Fixes:
     17 *		Alan Cox	:	UDP sockets show the rxqueue/txqueue
     18 *					using hint flag for the netinfo.
     19 *	Pauline Middelink	:	identd support
     20 *		Alan Cox	:	Make /proc safer.
     21 *	Erik Schoenfelder	:	/proc/net/snmp
     22 *		Alan Cox	:	Handle dead sockets properly.
     23 *	Gerhard Koerting	:	Show both timers
     24 *		Alan Cox	:	Allow inode to be NULL (kernel socket)
     25 *	Andi Kleen		:	Add support for open_requests and
     26 *					split functions for more readibility.
     27 *	Andi Kleen		:	Add support for /proc/net/netstat
     28 *	Arnaldo C. Melo		:	Convert to seq_file
     29 */
     30#include <linux/types.h>
     31#include <net/net_namespace.h>
     32#include <net/icmp.h>
     33#include <net/protocol.h>
     34#include <net/tcp.h>
     35#include <net/mptcp.h>
     36#include <net/udp.h>
     37#include <net/udplite.h>
     38#include <linux/bottom_half.h>
     39#include <linux/inetdevice.h>
     40#include <linux/proc_fs.h>
     41#include <linux/seq_file.h>
     42#include <linux/export.h>
     43#include <net/sock.h>
     44#include <net/raw.h>
     45
     46#define TCPUDP_MIB_MAX max_t(u32, UDP_MIB_MAX, TCP_MIB_MAX)
     47
     48/*
     49 *	Report socket allocation statistics [mea@utu.fi]
     50 */
     51static int sockstat_seq_show(struct seq_file *seq, void *v)
     52{
     53	struct net *net = seq->private;
     54	int orphans, sockets;
     55
     56	orphans = tcp_orphan_count_sum();
     57	sockets = proto_sockets_allocated_sum_positive(&tcp_prot);
     58
     59	socket_seq_show(seq);
     60	seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %ld\n",
     61		   sock_prot_inuse_get(net, &tcp_prot), orphans,
     62		   refcount_read(&net->ipv4.tcp_death_row->tw_refcount) - 1,
     63		   sockets, proto_memory_allocated(&tcp_prot));
     64	seq_printf(seq, "UDP: inuse %d mem %ld\n",
     65		   sock_prot_inuse_get(net, &udp_prot),
     66		   proto_memory_allocated(&udp_prot));
     67	seq_printf(seq, "UDPLITE: inuse %d\n",
     68		   sock_prot_inuse_get(net, &udplite_prot));
     69	seq_printf(seq, "RAW: inuse %d\n",
     70		   sock_prot_inuse_get(net, &raw_prot));
     71	seq_printf(seq,  "FRAG: inuse %u memory %lu\n",
     72		   atomic_read(&net->ipv4.fqdir->rhashtable.nelems),
     73		   frag_mem_limit(net->ipv4.fqdir));
     74	return 0;
     75}
     76
     77/* snmp items */
     78static const struct snmp_mib snmp4_ipstats_list[] = {
     79	SNMP_MIB_ITEM("InReceives", IPSTATS_MIB_INPKTS),
     80	SNMP_MIB_ITEM("InHdrErrors", IPSTATS_MIB_INHDRERRORS),
     81	SNMP_MIB_ITEM("InAddrErrors", IPSTATS_MIB_INADDRERRORS),
     82	SNMP_MIB_ITEM("ForwDatagrams", IPSTATS_MIB_OUTFORWDATAGRAMS),
     83	SNMP_MIB_ITEM("InUnknownProtos", IPSTATS_MIB_INUNKNOWNPROTOS),
     84	SNMP_MIB_ITEM("InDiscards", IPSTATS_MIB_INDISCARDS),
     85	SNMP_MIB_ITEM("InDelivers", IPSTATS_MIB_INDELIVERS),
     86	SNMP_MIB_ITEM("OutRequests", IPSTATS_MIB_OUTPKTS),
     87	SNMP_MIB_ITEM("OutDiscards", IPSTATS_MIB_OUTDISCARDS),
     88	SNMP_MIB_ITEM("OutNoRoutes", IPSTATS_MIB_OUTNOROUTES),
     89	SNMP_MIB_ITEM("ReasmTimeout", IPSTATS_MIB_REASMTIMEOUT),
     90	SNMP_MIB_ITEM("ReasmReqds", IPSTATS_MIB_REASMREQDS),
     91	SNMP_MIB_ITEM("ReasmOKs", IPSTATS_MIB_REASMOKS),
     92	SNMP_MIB_ITEM("ReasmFails", IPSTATS_MIB_REASMFAILS),
     93	SNMP_MIB_ITEM("FragOKs", IPSTATS_MIB_FRAGOKS),
     94	SNMP_MIB_ITEM("FragFails", IPSTATS_MIB_FRAGFAILS),
     95	SNMP_MIB_ITEM("FragCreates", IPSTATS_MIB_FRAGCREATES),
     96	SNMP_MIB_SENTINEL
     97};
     98
     99/* Following items are displayed in /proc/net/netstat */
    100static const struct snmp_mib snmp4_ipextstats_list[] = {
    101	SNMP_MIB_ITEM("InNoRoutes", IPSTATS_MIB_INNOROUTES),
    102	SNMP_MIB_ITEM("InTruncatedPkts", IPSTATS_MIB_INTRUNCATEDPKTS),
    103	SNMP_MIB_ITEM("InMcastPkts", IPSTATS_MIB_INMCASTPKTS),
    104	SNMP_MIB_ITEM("OutMcastPkts", IPSTATS_MIB_OUTMCASTPKTS),
    105	SNMP_MIB_ITEM("InBcastPkts", IPSTATS_MIB_INBCASTPKTS),
    106	SNMP_MIB_ITEM("OutBcastPkts", IPSTATS_MIB_OUTBCASTPKTS),
    107	SNMP_MIB_ITEM("InOctets", IPSTATS_MIB_INOCTETS),
    108	SNMP_MIB_ITEM("OutOctets", IPSTATS_MIB_OUTOCTETS),
    109	SNMP_MIB_ITEM("InMcastOctets", IPSTATS_MIB_INMCASTOCTETS),
    110	SNMP_MIB_ITEM("OutMcastOctets", IPSTATS_MIB_OUTMCASTOCTETS),
    111	SNMP_MIB_ITEM("InBcastOctets", IPSTATS_MIB_INBCASTOCTETS),
    112	SNMP_MIB_ITEM("OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS),
    113	/* Non RFC4293 fields */
    114	SNMP_MIB_ITEM("InCsumErrors", IPSTATS_MIB_CSUMERRORS),
    115	SNMP_MIB_ITEM("InNoECTPkts", IPSTATS_MIB_NOECTPKTS),
    116	SNMP_MIB_ITEM("InECT1Pkts", IPSTATS_MIB_ECT1PKTS),
    117	SNMP_MIB_ITEM("InECT0Pkts", IPSTATS_MIB_ECT0PKTS),
    118	SNMP_MIB_ITEM("InCEPkts", IPSTATS_MIB_CEPKTS),
    119	SNMP_MIB_ITEM("ReasmOverlaps", IPSTATS_MIB_REASM_OVERLAPS),
    120	SNMP_MIB_SENTINEL
    121};
    122
    123static const struct {
    124	const char *name;
    125	int index;
    126} icmpmibmap[] = {
    127	{ "DestUnreachs", ICMP_DEST_UNREACH },
    128	{ "TimeExcds", ICMP_TIME_EXCEEDED },
    129	{ "ParmProbs", ICMP_PARAMETERPROB },
    130	{ "SrcQuenchs", ICMP_SOURCE_QUENCH },
    131	{ "Redirects", ICMP_REDIRECT },
    132	{ "Echos", ICMP_ECHO },
    133	{ "EchoReps", ICMP_ECHOREPLY },
    134	{ "Timestamps", ICMP_TIMESTAMP },
    135	{ "TimestampReps", ICMP_TIMESTAMPREPLY },
    136	{ "AddrMasks", ICMP_ADDRESS },
    137	{ "AddrMaskReps", ICMP_ADDRESSREPLY },
    138	{ NULL, 0 }
    139};
    140
    141
    142static const struct snmp_mib snmp4_tcp_list[] = {
    143	SNMP_MIB_ITEM("RtoAlgorithm", TCP_MIB_RTOALGORITHM),
    144	SNMP_MIB_ITEM("RtoMin", TCP_MIB_RTOMIN),
    145	SNMP_MIB_ITEM("RtoMax", TCP_MIB_RTOMAX),
    146	SNMP_MIB_ITEM("MaxConn", TCP_MIB_MAXCONN),
    147	SNMP_MIB_ITEM("ActiveOpens", TCP_MIB_ACTIVEOPENS),
    148	SNMP_MIB_ITEM("PassiveOpens", TCP_MIB_PASSIVEOPENS),
    149	SNMP_MIB_ITEM("AttemptFails", TCP_MIB_ATTEMPTFAILS),
    150	SNMP_MIB_ITEM("EstabResets", TCP_MIB_ESTABRESETS),
    151	SNMP_MIB_ITEM("CurrEstab", TCP_MIB_CURRESTAB),
    152	SNMP_MIB_ITEM("InSegs", TCP_MIB_INSEGS),
    153	SNMP_MIB_ITEM("OutSegs", TCP_MIB_OUTSEGS),
    154	SNMP_MIB_ITEM("RetransSegs", TCP_MIB_RETRANSSEGS),
    155	SNMP_MIB_ITEM("InErrs", TCP_MIB_INERRS),
    156	SNMP_MIB_ITEM("OutRsts", TCP_MIB_OUTRSTS),
    157	SNMP_MIB_ITEM("InCsumErrors", TCP_MIB_CSUMERRORS),
    158	SNMP_MIB_SENTINEL
    159};
    160
    161static const struct snmp_mib snmp4_udp_list[] = {
    162	SNMP_MIB_ITEM("InDatagrams", UDP_MIB_INDATAGRAMS),
    163	SNMP_MIB_ITEM("NoPorts", UDP_MIB_NOPORTS),
    164	SNMP_MIB_ITEM("InErrors", UDP_MIB_INERRORS),
    165	SNMP_MIB_ITEM("OutDatagrams", UDP_MIB_OUTDATAGRAMS),
    166	SNMP_MIB_ITEM("RcvbufErrors", UDP_MIB_RCVBUFERRORS),
    167	SNMP_MIB_ITEM("SndbufErrors", UDP_MIB_SNDBUFERRORS),
    168	SNMP_MIB_ITEM("InCsumErrors", UDP_MIB_CSUMERRORS),
    169	SNMP_MIB_ITEM("IgnoredMulti", UDP_MIB_IGNOREDMULTI),
    170	SNMP_MIB_ITEM("MemErrors", UDP_MIB_MEMERRORS),
    171	SNMP_MIB_SENTINEL
    172};
    173
    174static const struct snmp_mib snmp4_net_list[] = {
    175	SNMP_MIB_ITEM("SyncookiesSent", LINUX_MIB_SYNCOOKIESSENT),
    176	SNMP_MIB_ITEM("SyncookiesRecv", LINUX_MIB_SYNCOOKIESRECV),
    177	SNMP_MIB_ITEM("SyncookiesFailed", LINUX_MIB_SYNCOOKIESFAILED),
    178	SNMP_MIB_ITEM("EmbryonicRsts", LINUX_MIB_EMBRYONICRSTS),
    179	SNMP_MIB_ITEM("PruneCalled", LINUX_MIB_PRUNECALLED),
    180	SNMP_MIB_ITEM("RcvPruned", LINUX_MIB_RCVPRUNED),
    181	SNMP_MIB_ITEM("OfoPruned", LINUX_MIB_OFOPRUNED),
    182	SNMP_MIB_ITEM("OutOfWindowIcmps", LINUX_MIB_OUTOFWINDOWICMPS),
    183	SNMP_MIB_ITEM("LockDroppedIcmps", LINUX_MIB_LOCKDROPPEDICMPS),
    184	SNMP_MIB_ITEM("ArpFilter", LINUX_MIB_ARPFILTER),
    185	SNMP_MIB_ITEM("TW", LINUX_MIB_TIMEWAITED),
    186	SNMP_MIB_ITEM("TWRecycled", LINUX_MIB_TIMEWAITRECYCLED),
    187	SNMP_MIB_ITEM("TWKilled", LINUX_MIB_TIMEWAITKILLED),
    188	SNMP_MIB_ITEM("PAWSActive", LINUX_MIB_PAWSACTIVEREJECTED),
    189	SNMP_MIB_ITEM("PAWSEstab", LINUX_MIB_PAWSESTABREJECTED),
    190	SNMP_MIB_ITEM("DelayedACKs", LINUX_MIB_DELAYEDACKS),
    191	SNMP_MIB_ITEM("DelayedACKLocked", LINUX_MIB_DELAYEDACKLOCKED),
    192	SNMP_MIB_ITEM("DelayedACKLost", LINUX_MIB_DELAYEDACKLOST),
    193	SNMP_MIB_ITEM("ListenOverflows", LINUX_MIB_LISTENOVERFLOWS),
    194	SNMP_MIB_ITEM("ListenDrops", LINUX_MIB_LISTENDROPS),
    195	SNMP_MIB_ITEM("TCPHPHits", LINUX_MIB_TCPHPHITS),
    196	SNMP_MIB_ITEM("TCPPureAcks", LINUX_MIB_TCPPUREACKS),
    197	SNMP_MIB_ITEM("TCPHPAcks", LINUX_MIB_TCPHPACKS),
    198	SNMP_MIB_ITEM("TCPRenoRecovery", LINUX_MIB_TCPRENORECOVERY),
    199	SNMP_MIB_ITEM("TCPSackRecovery", LINUX_MIB_TCPSACKRECOVERY),
    200	SNMP_MIB_ITEM("TCPSACKReneging", LINUX_MIB_TCPSACKRENEGING),
    201	SNMP_MIB_ITEM("TCPSACKReorder", LINUX_MIB_TCPSACKREORDER),
    202	SNMP_MIB_ITEM("TCPRenoReorder", LINUX_MIB_TCPRENOREORDER),
    203	SNMP_MIB_ITEM("TCPTSReorder", LINUX_MIB_TCPTSREORDER),
    204	SNMP_MIB_ITEM("TCPFullUndo", LINUX_MIB_TCPFULLUNDO),
    205	SNMP_MIB_ITEM("TCPPartialUndo", LINUX_MIB_TCPPARTIALUNDO),
    206	SNMP_MIB_ITEM("TCPDSACKUndo", LINUX_MIB_TCPDSACKUNDO),
    207	SNMP_MIB_ITEM("TCPLossUndo", LINUX_MIB_TCPLOSSUNDO),
    208	SNMP_MIB_ITEM("TCPLostRetransmit", LINUX_MIB_TCPLOSTRETRANSMIT),
    209	SNMP_MIB_ITEM("TCPRenoFailures", LINUX_MIB_TCPRENOFAILURES),
    210	SNMP_MIB_ITEM("TCPSackFailures", LINUX_MIB_TCPSACKFAILURES),
    211	SNMP_MIB_ITEM("TCPLossFailures", LINUX_MIB_TCPLOSSFAILURES),
    212	SNMP_MIB_ITEM("TCPFastRetrans", LINUX_MIB_TCPFASTRETRANS),
    213	SNMP_MIB_ITEM("TCPSlowStartRetrans", LINUX_MIB_TCPSLOWSTARTRETRANS),
    214	SNMP_MIB_ITEM("TCPTimeouts", LINUX_MIB_TCPTIMEOUTS),
    215	SNMP_MIB_ITEM("TCPLossProbes", LINUX_MIB_TCPLOSSPROBES),
    216	SNMP_MIB_ITEM("TCPLossProbeRecovery", LINUX_MIB_TCPLOSSPROBERECOVERY),
    217	SNMP_MIB_ITEM("TCPRenoRecoveryFail", LINUX_MIB_TCPRENORECOVERYFAIL),
    218	SNMP_MIB_ITEM("TCPSackRecoveryFail", LINUX_MIB_TCPSACKRECOVERYFAIL),
    219	SNMP_MIB_ITEM("TCPRcvCollapsed", LINUX_MIB_TCPRCVCOLLAPSED),
    220	SNMP_MIB_ITEM("TCPBacklogCoalesce", LINUX_MIB_TCPBACKLOGCOALESCE),
    221	SNMP_MIB_ITEM("TCPDSACKOldSent", LINUX_MIB_TCPDSACKOLDSENT),
    222	SNMP_MIB_ITEM("TCPDSACKOfoSent", LINUX_MIB_TCPDSACKOFOSENT),
    223	SNMP_MIB_ITEM("TCPDSACKRecv", LINUX_MIB_TCPDSACKRECV),
    224	SNMP_MIB_ITEM("TCPDSACKOfoRecv", LINUX_MIB_TCPDSACKOFORECV),
    225	SNMP_MIB_ITEM("TCPAbortOnData", LINUX_MIB_TCPABORTONDATA),
    226	SNMP_MIB_ITEM("TCPAbortOnClose", LINUX_MIB_TCPABORTONCLOSE),
    227	SNMP_MIB_ITEM("TCPAbortOnMemory", LINUX_MIB_TCPABORTONMEMORY),
    228	SNMP_MIB_ITEM("TCPAbortOnTimeout", LINUX_MIB_TCPABORTONTIMEOUT),
    229	SNMP_MIB_ITEM("TCPAbortOnLinger", LINUX_MIB_TCPABORTONLINGER),
    230	SNMP_MIB_ITEM("TCPAbortFailed", LINUX_MIB_TCPABORTFAILED),
    231	SNMP_MIB_ITEM("TCPMemoryPressures", LINUX_MIB_TCPMEMORYPRESSURES),
    232	SNMP_MIB_ITEM("TCPMemoryPressuresChrono", LINUX_MIB_TCPMEMORYPRESSURESCHRONO),
    233	SNMP_MIB_ITEM("TCPSACKDiscard", LINUX_MIB_TCPSACKDISCARD),
    234	SNMP_MIB_ITEM("TCPDSACKIgnoredOld", LINUX_MIB_TCPDSACKIGNOREDOLD),
    235	SNMP_MIB_ITEM("TCPDSACKIgnoredNoUndo", LINUX_MIB_TCPDSACKIGNOREDNOUNDO),
    236	SNMP_MIB_ITEM("TCPSpuriousRTOs", LINUX_MIB_TCPSPURIOUSRTOS),
    237	SNMP_MIB_ITEM("TCPMD5NotFound", LINUX_MIB_TCPMD5NOTFOUND),
    238	SNMP_MIB_ITEM("TCPMD5Unexpected", LINUX_MIB_TCPMD5UNEXPECTED),
    239	SNMP_MIB_ITEM("TCPMD5Failure", LINUX_MIB_TCPMD5FAILURE),
    240	SNMP_MIB_ITEM("TCPSackShifted", LINUX_MIB_SACKSHIFTED),
    241	SNMP_MIB_ITEM("TCPSackMerged", LINUX_MIB_SACKMERGED),
    242	SNMP_MIB_ITEM("TCPSackShiftFallback", LINUX_MIB_SACKSHIFTFALLBACK),
    243	SNMP_MIB_ITEM("TCPBacklogDrop", LINUX_MIB_TCPBACKLOGDROP),
    244	SNMP_MIB_ITEM("PFMemallocDrop", LINUX_MIB_PFMEMALLOCDROP),
    245	SNMP_MIB_ITEM("TCPMinTTLDrop", LINUX_MIB_TCPMINTTLDROP),
    246	SNMP_MIB_ITEM("TCPDeferAcceptDrop", LINUX_MIB_TCPDEFERACCEPTDROP),
    247	SNMP_MIB_ITEM("IPReversePathFilter", LINUX_MIB_IPRPFILTER),
    248	SNMP_MIB_ITEM("TCPTimeWaitOverflow", LINUX_MIB_TCPTIMEWAITOVERFLOW),
    249	SNMP_MIB_ITEM("TCPReqQFullDoCookies", LINUX_MIB_TCPREQQFULLDOCOOKIES),
    250	SNMP_MIB_ITEM("TCPReqQFullDrop", LINUX_MIB_TCPREQQFULLDROP),
    251	SNMP_MIB_ITEM("TCPRetransFail", LINUX_MIB_TCPRETRANSFAIL),
    252	SNMP_MIB_ITEM("TCPRcvCoalesce", LINUX_MIB_TCPRCVCOALESCE),
    253	SNMP_MIB_ITEM("TCPOFOQueue", LINUX_MIB_TCPOFOQUEUE),
    254	SNMP_MIB_ITEM("TCPOFODrop", LINUX_MIB_TCPOFODROP),
    255	SNMP_MIB_ITEM("TCPOFOMerge", LINUX_MIB_TCPOFOMERGE),
    256	SNMP_MIB_ITEM("TCPChallengeACK", LINUX_MIB_TCPCHALLENGEACK),
    257	SNMP_MIB_ITEM("TCPSYNChallenge", LINUX_MIB_TCPSYNCHALLENGE),
    258	SNMP_MIB_ITEM("TCPFastOpenActive", LINUX_MIB_TCPFASTOPENACTIVE),
    259	SNMP_MIB_ITEM("TCPFastOpenActiveFail", LINUX_MIB_TCPFASTOPENACTIVEFAIL),
    260	SNMP_MIB_ITEM("TCPFastOpenPassive", LINUX_MIB_TCPFASTOPENPASSIVE),
    261	SNMP_MIB_ITEM("TCPFastOpenPassiveFail", LINUX_MIB_TCPFASTOPENPASSIVEFAIL),
    262	SNMP_MIB_ITEM("TCPFastOpenListenOverflow", LINUX_MIB_TCPFASTOPENLISTENOVERFLOW),
    263	SNMP_MIB_ITEM("TCPFastOpenCookieReqd", LINUX_MIB_TCPFASTOPENCOOKIEREQD),
    264	SNMP_MIB_ITEM("TCPFastOpenBlackhole", LINUX_MIB_TCPFASTOPENBLACKHOLE),
    265	SNMP_MIB_ITEM("TCPSpuriousRtxHostQueues", LINUX_MIB_TCPSPURIOUS_RTX_HOSTQUEUES),
    266	SNMP_MIB_ITEM("BusyPollRxPackets", LINUX_MIB_BUSYPOLLRXPACKETS),
    267	SNMP_MIB_ITEM("TCPAutoCorking", LINUX_MIB_TCPAUTOCORKING),
    268	SNMP_MIB_ITEM("TCPFromZeroWindowAdv", LINUX_MIB_TCPFROMZEROWINDOWADV),
    269	SNMP_MIB_ITEM("TCPToZeroWindowAdv", LINUX_MIB_TCPTOZEROWINDOWADV),
    270	SNMP_MIB_ITEM("TCPWantZeroWindowAdv", LINUX_MIB_TCPWANTZEROWINDOWADV),
    271	SNMP_MIB_ITEM("TCPSynRetrans", LINUX_MIB_TCPSYNRETRANS),
    272	SNMP_MIB_ITEM("TCPOrigDataSent", LINUX_MIB_TCPORIGDATASENT),
    273	SNMP_MIB_ITEM("TCPHystartTrainDetect", LINUX_MIB_TCPHYSTARTTRAINDETECT),
    274	SNMP_MIB_ITEM("TCPHystartTrainCwnd", LINUX_MIB_TCPHYSTARTTRAINCWND),
    275	SNMP_MIB_ITEM("TCPHystartDelayDetect", LINUX_MIB_TCPHYSTARTDELAYDETECT),
    276	SNMP_MIB_ITEM("TCPHystartDelayCwnd", LINUX_MIB_TCPHYSTARTDELAYCWND),
    277	SNMP_MIB_ITEM("TCPACKSkippedSynRecv", LINUX_MIB_TCPACKSKIPPEDSYNRECV),
    278	SNMP_MIB_ITEM("TCPACKSkippedPAWS", LINUX_MIB_TCPACKSKIPPEDPAWS),
    279	SNMP_MIB_ITEM("TCPACKSkippedSeq", LINUX_MIB_TCPACKSKIPPEDSEQ),
    280	SNMP_MIB_ITEM("TCPACKSkippedFinWait2", LINUX_MIB_TCPACKSKIPPEDFINWAIT2),
    281	SNMP_MIB_ITEM("TCPACKSkippedTimeWait", LINUX_MIB_TCPACKSKIPPEDTIMEWAIT),
    282	SNMP_MIB_ITEM("TCPACKSkippedChallenge", LINUX_MIB_TCPACKSKIPPEDCHALLENGE),
    283	SNMP_MIB_ITEM("TCPWinProbe", LINUX_MIB_TCPWINPROBE),
    284	SNMP_MIB_ITEM("TCPKeepAlive", LINUX_MIB_TCPKEEPALIVE),
    285	SNMP_MIB_ITEM("TCPMTUPFail", LINUX_MIB_TCPMTUPFAIL),
    286	SNMP_MIB_ITEM("TCPMTUPSuccess", LINUX_MIB_TCPMTUPSUCCESS),
    287	SNMP_MIB_ITEM("TCPDelivered", LINUX_MIB_TCPDELIVERED),
    288	SNMP_MIB_ITEM("TCPDeliveredCE", LINUX_MIB_TCPDELIVEREDCE),
    289	SNMP_MIB_ITEM("TCPAckCompressed", LINUX_MIB_TCPACKCOMPRESSED),
    290	SNMP_MIB_ITEM("TCPZeroWindowDrop", LINUX_MIB_TCPZEROWINDOWDROP),
    291	SNMP_MIB_ITEM("TCPRcvQDrop", LINUX_MIB_TCPRCVQDROP),
    292	SNMP_MIB_ITEM("TCPWqueueTooBig", LINUX_MIB_TCPWQUEUETOOBIG),
    293	SNMP_MIB_ITEM("TCPFastOpenPassiveAltKey", LINUX_MIB_TCPFASTOPENPASSIVEALTKEY),
    294	SNMP_MIB_ITEM("TcpTimeoutRehash", LINUX_MIB_TCPTIMEOUTREHASH),
    295	SNMP_MIB_ITEM("TcpDuplicateDataRehash", LINUX_MIB_TCPDUPLICATEDATAREHASH),
    296	SNMP_MIB_ITEM("TCPDSACKRecvSegs", LINUX_MIB_TCPDSACKRECVSEGS),
    297	SNMP_MIB_ITEM("TCPDSACKIgnoredDubious", LINUX_MIB_TCPDSACKIGNOREDDUBIOUS),
    298	SNMP_MIB_ITEM("TCPMigrateReqSuccess", LINUX_MIB_TCPMIGRATEREQSUCCESS),
    299	SNMP_MIB_ITEM("TCPMigrateReqFailure", LINUX_MIB_TCPMIGRATEREQFAILURE),
    300	SNMP_MIB_SENTINEL
    301};
    302
    303static void icmpmsg_put_line(struct seq_file *seq, unsigned long *vals,
    304			     unsigned short *type, int count)
    305{
    306	int j;
    307
    308	if (count) {
    309		seq_puts(seq, "\nIcmpMsg:");
    310		for (j = 0; j < count; ++j)
    311			seq_printf(seq, " %sType%u",
    312				type[j] & 0x100 ? "Out" : "In",
    313				type[j] & 0xff);
    314		seq_puts(seq, "\nIcmpMsg:");
    315		for (j = 0; j < count; ++j)
    316			seq_printf(seq, " %lu", vals[j]);
    317	}
    318}
    319
    320static void icmpmsg_put(struct seq_file *seq)
    321{
    322#define PERLINE	16
    323
    324	int i, count;
    325	unsigned short type[PERLINE];
    326	unsigned long vals[PERLINE], val;
    327	struct net *net = seq->private;
    328
    329	count = 0;
    330	for (i = 0; i < ICMPMSG_MIB_MAX; i++) {
    331		val = atomic_long_read(&net->mib.icmpmsg_statistics->mibs[i]);
    332		if (val) {
    333			type[count] = i;
    334			vals[count++] = val;
    335		}
    336		if (count == PERLINE) {
    337			icmpmsg_put_line(seq, vals, type, count);
    338			count = 0;
    339		}
    340	}
    341	icmpmsg_put_line(seq, vals, type, count);
    342
    343#undef PERLINE
    344}
    345
    346static void icmp_put(struct seq_file *seq)
    347{
    348	int i;
    349	struct net *net = seq->private;
    350	atomic_long_t *ptr = net->mib.icmpmsg_statistics->mibs;
    351
    352	seq_puts(seq, "\nIcmp: InMsgs InErrors InCsumErrors");
    353	for (i = 0; icmpmibmap[i].name; i++)
    354		seq_printf(seq, " In%s", icmpmibmap[i].name);
    355	seq_puts(seq, " OutMsgs OutErrors");
    356	for (i = 0; icmpmibmap[i].name; i++)
    357		seq_printf(seq, " Out%s", icmpmibmap[i].name);
    358	seq_printf(seq, "\nIcmp: %lu %lu %lu",
    359		snmp_fold_field(net->mib.icmp_statistics, ICMP_MIB_INMSGS),
    360		snmp_fold_field(net->mib.icmp_statistics, ICMP_MIB_INERRORS),
    361		snmp_fold_field(net->mib.icmp_statistics, ICMP_MIB_CSUMERRORS));
    362	for (i = 0; icmpmibmap[i].name; i++)
    363		seq_printf(seq, " %lu",
    364			   atomic_long_read(ptr + icmpmibmap[i].index));
    365	seq_printf(seq, " %lu %lu",
    366		snmp_fold_field(net->mib.icmp_statistics, ICMP_MIB_OUTMSGS),
    367		snmp_fold_field(net->mib.icmp_statistics, ICMP_MIB_OUTERRORS));
    368	for (i = 0; icmpmibmap[i].name; i++)
    369		seq_printf(seq, " %lu",
    370			   atomic_long_read(ptr + (icmpmibmap[i].index | 0x100)));
    371}
    372
    373/*
    374 *	Called from the PROCfs module. This outputs /proc/net/snmp.
    375 */
    376static int snmp_seq_show_ipstats(struct seq_file *seq, void *v)
    377{
    378	struct net *net = seq->private;
    379	u64 buff64[IPSTATS_MIB_MAX];
    380	int i;
    381
    382	memset(buff64, 0, IPSTATS_MIB_MAX * sizeof(u64));
    383
    384	seq_puts(seq, "Ip: Forwarding DefaultTTL");
    385	for (i = 0; snmp4_ipstats_list[i].name; i++)
    386		seq_printf(seq, " %s", snmp4_ipstats_list[i].name);
    387
    388	seq_printf(seq, "\nIp: %d %d",
    389		   IPV4_DEVCONF_ALL(net, FORWARDING) ? 1 : 2,
    390		   net->ipv4.sysctl_ip_default_ttl);
    391
    392	BUILD_BUG_ON(offsetof(struct ipstats_mib, mibs) != 0);
    393	snmp_get_cpu_field64_batch(buff64, snmp4_ipstats_list,
    394				   net->mib.ip_statistics,
    395				   offsetof(struct ipstats_mib, syncp));
    396	for (i = 0; snmp4_ipstats_list[i].name; i++)
    397		seq_printf(seq, " %llu", buff64[i]);
    398
    399	return 0;
    400}
    401
    402static int snmp_seq_show_tcp_udp(struct seq_file *seq, void *v)
    403{
    404	unsigned long buff[TCPUDP_MIB_MAX];
    405	struct net *net = seq->private;
    406	int i;
    407
    408	memset(buff, 0, TCPUDP_MIB_MAX * sizeof(unsigned long));
    409
    410	seq_puts(seq, "\nTcp:");
    411	for (i = 0; snmp4_tcp_list[i].name; i++)
    412		seq_printf(seq, " %s", snmp4_tcp_list[i].name);
    413
    414	seq_puts(seq, "\nTcp:");
    415	snmp_get_cpu_field_batch(buff, snmp4_tcp_list,
    416				 net->mib.tcp_statistics);
    417	for (i = 0; snmp4_tcp_list[i].name; i++) {
    418		/* MaxConn field is signed, RFC 2012 */
    419		if (snmp4_tcp_list[i].entry == TCP_MIB_MAXCONN)
    420			seq_printf(seq, " %ld", buff[i]);
    421		else
    422			seq_printf(seq, " %lu", buff[i]);
    423	}
    424
    425	memset(buff, 0, TCPUDP_MIB_MAX * sizeof(unsigned long));
    426
    427	snmp_get_cpu_field_batch(buff, snmp4_udp_list,
    428				 net->mib.udp_statistics);
    429	seq_puts(seq, "\nUdp:");
    430	for (i = 0; snmp4_udp_list[i].name; i++)
    431		seq_printf(seq, " %s", snmp4_udp_list[i].name);
    432	seq_puts(seq, "\nUdp:");
    433	for (i = 0; snmp4_udp_list[i].name; i++)
    434		seq_printf(seq, " %lu", buff[i]);
    435
    436	memset(buff, 0, TCPUDP_MIB_MAX * sizeof(unsigned long));
    437
    438	/* the UDP and UDP-Lite MIBs are the same */
    439	seq_puts(seq, "\nUdpLite:");
    440	snmp_get_cpu_field_batch(buff, snmp4_udp_list,
    441				 net->mib.udplite_statistics);
    442	for (i = 0; snmp4_udp_list[i].name; i++)
    443		seq_printf(seq, " %s", snmp4_udp_list[i].name);
    444	seq_puts(seq, "\nUdpLite:");
    445	for (i = 0; snmp4_udp_list[i].name; i++)
    446		seq_printf(seq, " %lu", buff[i]);
    447
    448	seq_putc(seq, '\n');
    449	return 0;
    450}
    451
    452static int snmp_seq_show(struct seq_file *seq, void *v)
    453{
    454	snmp_seq_show_ipstats(seq, v);
    455
    456	icmp_put(seq);	/* RFC 2011 compatibility */
    457	icmpmsg_put(seq);
    458
    459	snmp_seq_show_tcp_udp(seq, v);
    460
    461	return 0;
    462}
    463
    464/*
    465 *	Output /proc/net/netstat
    466 */
    467static int netstat_seq_show(struct seq_file *seq, void *v)
    468{
    469	const int ip_cnt = ARRAY_SIZE(snmp4_ipextstats_list) - 1;
    470	const int tcp_cnt = ARRAY_SIZE(snmp4_net_list) - 1;
    471	struct net *net = seq->private;
    472	unsigned long *buff;
    473	int i;
    474
    475	seq_puts(seq, "TcpExt:");
    476	for (i = 0; i < tcp_cnt; i++)
    477		seq_printf(seq, " %s", snmp4_net_list[i].name);
    478
    479	seq_puts(seq, "\nTcpExt:");
    480	buff = kzalloc(max(tcp_cnt * sizeof(long), ip_cnt * sizeof(u64)),
    481		       GFP_KERNEL);
    482	if (buff) {
    483		snmp_get_cpu_field_batch(buff, snmp4_net_list,
    484					 net->mib.net_statistics);
    485		for (i = 0; i < tcp_cnt; i++)
    486			seq_printf(seq, " %lu", buff[i]);
    487	} else {
    488		for (i = 0; i < tcp_cnt; i++)
    489			seq_printf(seq, " %lu",
    490				   snmp_fold_field(net->mib.net_statistics,
    491						   snmp4_net_list[i].entry));
    492	}
    493	seq_puts(seq, "\nIpExt:");
    494	for (i = 0; i < ip_cnt; i++)
    495		seq_printf(seq, " %s", snmp4_ipextstats_list[i].name);
    496
    497	seq_puts(seq, "\nIpExt:");
    498	if (buff) {
    499		u64 *buff64 = (u64 *)buff;
    500
    501		memset(buff64, 0, ip_cnt * sizeof(u64));
    502		snmp_get_cpu_field64_batch(buff64, snmp4_ipextstats_list,
    503					   net->mib.ip_statistics,
    504					   offsetof(struct ipstats_mib, syncp));
    505		for (i = 0; i < ip_cnt; i++)
    506			seq_printf(seq, " %llu", buff64[i]);
    507	} else {
    508		for (i = 0; i < ip_cnt; i++)
    509			seq_printf(seq, " %llu",
    510				   snmp_fold_field64(net->mib.ip_statistics,
    511						     snmp4_ipextstats_list[i].entry,
    512						     offsetof(struct ipstats_mib, syncp)));
    513	}
    514	kfree(buff);
    515	seq_putc(seq, '\n');
    516	mptcp_seq_show(seq);
    517	return 0;
    518}
    519
    520static __net_init int ip_proc_init_net(struct net *net)
    521{
    522	if (!proc_create_net_single("sockstat", 0444, net->proc_net,
    523			sockstat_seq_show, NULL))
    524		goto out_sockstat;
    525	if (!proc_create_net_single("netstat", 0444, net->proc_net,
    526			netstat_seq_show, NULL))
    527		goto out_netstat;
    528	if (!proc_create_net_single("snmp", 0444, net->proc_net, snmp_seq_show,
    529			NULL))
    530		goto out_snmp;
    531
    532	return 0;
    533
    534out_snmp:
    535	remove_proc_entry("netstat", net->proc_net);
    536out_netstat:
    537	remove_proc_entry("sockstat", net->proc_net);
    538out_sockstat:
    539	return -ENOMEM;
    540}
    541
    542static __net_exit void ip_proc_exit_net(struct net *net)
    543{
    544	remove_proc_entry("snmp", net->proc_net);
    545	remove_proc_entry("netstat", net->proc_net);
    546	remove_proc_entry("sockstat", net->proc_net);
    547}
    548
    549static __net_initdata struct pernet_operations ip_proc_ops = {
    550	.init = ip_proc_init_net,
    551	.exit = ip_proc_exit_net,
    552};
    553
    554int __init ip_misc_proc_init(void)
    555{
    556	return register_pernet_subsys(&ip_proc_ops);
    557}