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 (11160B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/* SCTP kernel implementation
      3 * Copyright (c) 2003 International Business Machines, Corp.
      4 *
      5 * This file is part of the SCTP kernel implementation
      6 *
      7 * Please send any bug reports or fixes you make to the
      8 * email address(es):
      9 *    lksctp developers <linux-sctp@vger.kernel.org>
     10 *
     11 * Written or modified by:
     12 *    Sridhar Samudrala <sri@us.ibm.com>
     13 */
     14
     15#include <linux/types.h>
     16#include <linux/seq_file.h>
     17#include <linux/init.h>
     18#include <linux/export.h>
     19#include <net/sctp/sctp.h>
     20#include <net/ip.h> /* for snmp_fold_field */
     21
     22static const struct snmp_mib sctp_snmp_list[] = {
     23	SNMP_MIB_ITEM("SctpCurrEstab", SCTP_MIB_CURRESTAB),
     24	SNMP_MIB_ITEM("SctpActiveEstabs", SCTP_MIB_ACTIVEESTABS),
     25	SNMP_MIB_ITEM("SctpPassiveEstabs", SCTP_MIB_PASSIVEESTABS),
     26	SNMP_MIB_ITEM("SctpAborteds", SCTP_MIB_ABORTEDS),
     27	SNMP_MIB_ITEM("SctpShutdowns", SCTP_MIB_SHUTDOWNS),
     28	SNMP_MIB_ITEM("SctpOutOfBlues", SCTP_MIB_OUTOFBLUES),
     29	SNMP_MIB_ITEM("SctpChecksumErrors", SCTP_MIB_CHECKSUMERRORS),
     30	SNMP_MIB_ITEM("SctpOutCtrlChunks", SCTP_MIB_OUTCTRLCHUNKS),
     31	SNMP_MIB_ITEM("SctpOutOrderChunks", SCTP_MIB_OUTORDERCHUNKS),
     32	SNMP_MIB_ITEM("SctpOutUnorderChunks", SCTP_MIB_OUTUNORDERCHUNKS),
     33	SNMP_MIB_ITEM("SctpInCtrlChunks", SCTP_MIB_INCTRLCHUNKS),
     34	SNMP_MIB_ITEM("SctpInOrderChunks", SCTP_MIB_INORDERCHUNKS),
     35	SNMP_MIB_ITEM("SctpInUnorderChunks", SCTP_MIB_INUNORDERCHUNKS),
     36	SNMP_MIB_ITEM("SctpFragUsrMsgs", SCTP_MIB_FRAGUSRMSGS),
     37	SNMP_MIB_ITEM("SctpReasmUsrMsgs", SCTP_MIB_REASMUSRMSGS),
     38	SNMP_MIB_ITEM("SctpOutSCTPPacks", SCTP_MIB_OUTSCTPPACKS),
     39	SNMP_MIB_ITEM("SctpInSCTPPacks", SCTP_MIB_INSCTPPACKS),
     40	SNMP_MIB_ITEM("SctpT1InitExpireds", SCTP_MIB_T1_INIT_EXPIREDS),
     41	SNMP_MIB_ITEM("SctpT1CookieExpireds", SCTP_MIB_T1_COOKIE_EXPIREDS),
     42	SNMP_MIB_ITEM("SctpT2ShutdownExpireds", SCTP_MIB_T2_SHUTDOWN_EXPIREDS),
     43	SNMP_MIB_ITEM("SctpT3RtxExpireds", SCTP_MIB_T3_RTX_EXPIREDS),
     44	SNMP_MIB_ITEM("SctpT4RtoExpireds", SCTP_MIB_T4_RTO_EXPIREDS),
     45	SNMP_MIB_ITEM("SctpT5ShutdownGuardExpireds", SCTP_MIB_T5_SHUTDOWN_GUARD_EXPIREDS),
     46	SNMP_MIB_ITEM("SctpDelaySackExpireds", SCTP_MIB_DELAY_SACK_EXPIREDS),
     47	SNMP_MIB_ITEM("SctpAutocloseExpireds", SCTP_MIB_AUTOCLOSE_EXPIREDS),
     48	SNMP_MIB_ITEM("SctpT3Retransmits", SCTP_MIB_T3_RETRANSMITS),
     49	SNMP_MIB_ITEM("SctpPmtudRetransmits", SCTP_MIB_PMTUD_RETRANSMITS),
     50	SNMP_MIB_ITEM("SctpFastRetransmits", SCTP_MIB_FAST_RETRANSMITS),
     51	SNMP_MIB_ITEM("SctpInPktSoftirq", SCTP_MIB_IN_PKT_SOFTIRQ),
     52	SNMP_MIB_ITEM("SctpInPktBacklog", SCTP_MIB_IN_PKT_BACKLOG),
     53	SNMP_MIB_ITEM("SctpInPktDiscards", SCTP_MIB_IN_PKT_DISCARDS),
     54	SNMP_MIB_ITEM("SctpInDataChunkDiscards", SCTP_MIB_IN_DATA_CHUNK_DISCARDS),
     55	SNMP_MIB_SENTINEL
     56};
     57
     58/* Display sctp snmp mib statistics(/proc/net/sctp/snmp). */
     59static int sctp_snmp_seq_show(struct seq_file *seq, void *v)
     60{
     61	unsigned long buff[SCTP_MIB_MAX];
     62	struct net *net = seq->private;
     63	int i;
     64
     65	memset(buff, 0, sizeof(unsigned long) * SCTP_MIB_MAX);
     66
     67	snmp_get_cpu_field_batch(buff, sctp_snmp_list,
     68				 net->sctp.sctp_statistics);
     69	for (i = 0; sctp_snmp_list[i].name; i++)
     70		seq_printf(seq, "%-32s\t%ld\n", sctp_snmp_list[i].name,
     71						buff[i]);
     72
     73	return 0;
     74}
     75
     76/* Dump local addresses of an association/endpoint. */
     77static void sctp_seq_dump_local_addrs(struct seq_file *seq, struct sctp_ep_common *epb)
     78{
     79	struct sctp_association *asoc;
     80	struct sctp_sockaddr_entry *laddr;
     81	struct sctp_transport *peer;
     82	union sctp_addr *addr, *primary = NULL;
     83	struct sctp_af *af;
     84
     85	if (epb->type == SCTP_EP_TYPE_ASSOCIATION) {
     86		asoc = sctp_assoc(epb);
     87
     88		peer = asoc->peer.primary_path;
     89		if (unlikely(peer == NULL)) {
     90			WARN(1, "Association %p with NULL primary path!\n", asoc);
     91			return;
     92		}
     93
     94		primary = &peer->saddr;
     95	}
     96
     97	rcu_read_lock();
     98	list_for_each_entry_rcu(laddr, &epb->bind_addr.address_list, list) {
     99		if (!laddr->valid)
    100			continue;
    101
    102		addr = &laddr->a;
    103		af = sctp_get_af_specific(addr->sa.sa_family);
    104		if (primary && af->cmp_addr(addr, primary)) {
    105			seq_printf(seq, "*");
    106		}
    107		af->seq_dump_addr(seq, addr);
    108	}
    109	rcu_read_unlock();
    110}
    111
    112/* Dump remote addresses of an association. */
    113static void sctp_seq_dump_remote_addrs(struct seq_file *seq, struct sctp_association *assoc)
    114{
    115	struct sctp_transport *transport;
    116	union sctp_addr *addr, *primary;
    117	struct sctp_af *af;
    118
    119	primary = &assoc->peer.primary_addr;
    120	list_for_each_entry_rcu(transport, &assoc->peer.transport_addr_list,
    121			transports) {
    122		addr = &transport->ipaddr;
    123
    124		af = sctp_get_af_specific(addr->sa.sa_family);
    125		if (af->cmp_addr(addr, primary)) {
    126			seq_printf(seq, "*");
    127		}
    128		af->seq_dump_addr(seq, addr);
    129	}
    130}
    131
    132static void *sctp_eps_seq_start(struct seq_file *seq, loff_t *pos)
    133{
    134	if (*pos >= sctp_ep_hashsize)
    135		return NULL;
    136
    137	if (*pos < 0)
    138		*pos = 0;
    139
    140	if (*pos == 0)
    141		seq_printf(seq, " ENDPT     SOCK   STY SST HBKT LPORT   UID INODE LADDRS\n");
    142
    143	return (void *)pos;
    144}
    145
    146static void sctp_eps_seq_stop(struct seq_file *seq, void *v)
    147{
    148}
    149
    150
    151static void *sctp_eps_seq_next(struct seq_file *seq, void *v, loff_t *pos)
    152{
    153	if (++*pos >= sctp_ep_hashsize)
    154		return NULL;
    155
    156	return pos;
    157}
    158
    159
    160/* Display sctp endpoints (/proc/net/sctp/eps). */
    161static int sctp_eps_seq_show(struct seq_file *seq, void *v)
    162{
    163	struct sctp_hashbucket *head;
    164	struct sctp_endpoint *ep;
    165	struct sock *sk;
    166	int    hash = *(loff_t *)v;
    167
    168	if (hash >= sctp_ep_hashsize)
    169		return -ENOMEM;
    170
    171	head = &sctp_ep_hashtable[hash];
    172	read_lock_bh(&head->lock);
    173	sctp_for_each_hentry(ep, &head->chain) {
    174		sk = ep->base.sk;
    175		if (!net_eq(sock_net(sk), seq_file_net(seq)))
    176			continue;
    177		seq_printf(seq, "%8pK %8pK %-3d %-3d %-4d %-5d %5u %5lu ", ep, sk,
    178			   sctp_sk(sk)->type, sk->sk_state, hash,
    179			   ep->base.bind_addr.port,
    180			   from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk)),
    181			   sock_i_ino(sk));
    182
    183		sctp_seq_dump_local_addrs(seq, &ep->base);
    184		seq_printf(seq, "\n");
    185	}
    186	read_unlock_bh(&head->lock);
    187
    188	return 0;
    189}
    190
    191static const struct seq_operations sctp_eps_ops = {
    192	.start = sctp_eps_seq_start,
    193	.next  = sctp_eps_seq_next,
    194	.stop  = sctp_eps_seq_stop,
    195	.show  = sctp_eps_seq_show,
    196};
    197
    198struct sctp_ht_iter {
    199	struct seq_net_private p;
    200	struct rhashtable_iter hti;
    201};
    202
    203static void *sctp_transport_seq_start(struct seq_file *seq, loff_t *pos)
    204{
    205	struct sctp_ht_iter *iter = seq->private;
    206
    207	sctp_transport_walk_start(&iter->hti);
    208
    209	return sctp_transport_get_idx(seq_file_net(seq), &iter->hti, *pos);
    210}
    211
    212static void sctp_transport_seq_stop(struct seq_file *seq, void *v)
    213{
    214	struct sctp_ht_iter *iter = seq->private;
    215
    216	if (v && v != SEQ_START_TOKEN) {
    217		struct sctp_transport *transport = v;
    218
    219		sctp_transport_put(transport);
    220	}
    221
    222	sctp_transport_walk_stop(&iter->hti);
    223}
    224
    225static void *sctp_transport_seq_next(struct seq_file *seq, void *v, loff_t *pos)
    226{
    227	struct sctp_ht_iter *iter = seq->private;
    228
    229	if (v && v != SEQ_START_TOKEN) {
    230		struct sctp_transport *transport = v;
    231
    232		sctp_transport_put(transport);
    233	}
    234
    235	++*pos;
    236
    237	return sctp_transport_get_next(seq_file_net(seq), &iter->hti);
    238}
    239
    240/* Display sctp associations (/proc/net/sctp/assocs). */
    241static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
    242{
    243	struct sctp_transport *transport;
    244	struct sctp_association *assoc;
    245	struct sctp_ep_common *epb;
    246	struct sock *sk;
    247
    248	if (v == SEQ_START_TOKEN) {
    249		seq_printf(seq, " ASSOC     SOCK   STY SST ST HBKT "
    250				"ASSOC-ID TX_QUEUE RX_QUEUE UID INODE LPORT "
    251				"RPORT LADDRS <-> RADDRS "
    252				"HBINT INS OUTS MAXRT T1X T2X RTXC "
    253				"wmema wmemq sndbuf rcvbuf\n");
    254		return 0;
    255	}
    256
    257	transport = (struct sctp_transport *)v;
    258	assoc = transport->asoc;
    259	epb = &assoc->base;
    260	sk = epb->sk;
    261
    262	seq_printf(seq,
    263		   "%8pK %8pK %-3d %-3d %-2d %-4d "
    264		   "%4d %8d %8d %7u %5lu %-5d %5d ",
    265		   assoc, sk, sctp_sk(sk)->type, sk->sk_state,
    266		   assoc->state, 0,
    267		   assoc->assoc_id,
    268		   assoc->sndbuf_used,
    269		   atomic_read(&assoc->rmem_alloc),
    270		   from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk)),
    271		   sock_i_ino(sk),
    272		   epb->bind_addr.port,
    273		   assoc->peer.port);
    274	seq_printf(seq, " ");
    275	sctp_seq_dump_local_addrs(seq, epb);
    276	seq_printf(seq, "<-> ");
    277	sctp_seq_dump_remote_addrs(seq, assoc);
    278	seq_printf(seq, "\t%8lu %5d %5d %4d %4d %4d %8d "
    279		   "%8d %8d %8d %8d",
    280		assoc->hbinterval, assoc->stream.incnt,
    281		assoc->stream.outcnt, assoc->max_retrans,
    282		assoc->init_retries, assoc->shutdown_retries,
    283		assoc->rtx_data_chunks,
    284		refcount_read(&sk->sk_wmem_alloc),
    285		sk->sk_wmem_queued,
    286		sk->sk_sndbuf,
    287		sk->sk_rcvbuf);
    288	seq_printf(seq, "\n");
    289
    290	return 0;
    291}
    292
    293static const struct seq_operations sctp_assoc_ops = {
    294	.start = sctp_transport_seq_start,
    295	.next  = sctp_transport_seq_next,
    296	.stop  = sctp_transport_seq_stop,
    297	.show  = sctp_assocs_seq_show,
    298};
    299
    300static int sctp_remaddr_seq_show(struct seq_file *seq, void *v)
    301{
    302	struct sctp_association *assoc;
    303	struct sctp_transport *transport, *tsp;
    304
    305	if (v == SEQ_START_TOKEN) {
    306		seq_printf(seq, "ADDR ASSOC_ID HB_ACT RTO MAX_PATH_RTX "
    307				"REM_ADDR_RTX START STATE\n");
    308		return 0;
    309	}
    310
    311	transport = (struct sctp_transport *)v;
    312	assoc = transport->asoc;
    313
    314	list_for_each_entry_rcu(tsp, &assoc->peer.transport_addr_list,
    315				transports) {
    316		/*
    317		 * The remote address (ADDR)
    318		 */
    319		tsp->af_specific->seq_dump_addr(seq, &tsp->ipaddr);
    320		seq_printf(seq, " ");
    321		/*
    322		 * The association ID (ASSOC_ID)
    323		 */
    324		seq_printf(seq, "%d ", tsp->asoc->assoc_id);
    325
    326		/*
    327		 * If the Heartbeat is active (HB_ACT)
    328		 * Note: 1 = Active, 0 = Inactive
    329		 */
    330		seq_printf(seq, "%d ", timer_pending(&tsp->hb_timer));
    331
    332		/*
    333		 * Retransmit time out (RTO)
    334		 */
    335		seq_printf(seq, "%lu ", tsp->rto);
    336
    337		/*
    338		 * Maximum path retransmit count (PATH_MAX_RTX)
    339		 */
    340		seq_printf(seq, "%d ", tsp->pathmaxrxt);
    341
    342		/*
    343		 * remote address retransmit count (REM_ADDR_RTX)
    344		 * Note: We don't have a way to tally this at the moment
    345		 * so lets just leave it as zero for the moment
    346		 */
    347		seq_puts(seq, "0 ");
    348
    349		/*
    350		 * remote address start time (START).  This is also not
    351		 * currently implemented, but we can record it with a
    352		 * jiffies marker in a subsequent patch
    353		 */
    354		seq_puts(seq, "0 ");
    355
    356		/*
    357		 * The current state of this destination. I.e.
    358		 * SCTP_ACTIVE, SCTP_INACTIVE, ...
    359		 */
    360		seq_printf(seq, "%d", tsp->state);
    361
    362		seq_printf(seq, "\n");
    363	}
    364
    365	return 0;
    366}
    367
    368static const struct seq_operations sctp_remaddr_ops = {
    369	.start = sctp_transport_seq_start,
    370	.next  = sctp_transport_seq_next,
    371	.stop  = sctp_transport_seq_stop,
    372	.show  = sctp_remaddr_seq_show,
    373};
    374
    375/* Set up the proc fs entry for the SCTP protocol. */
    376int __net_init sctp_proc_init(struct net *net)
    377{
    378	net->sctp.proc_net_sctp = proc_net_mkdir(net, "sctp", net->proc_net);
    379	if (!net->sctp.proc_net_sctp)
    380		return -ENOMEM;
    381	if (!proc_create_net_single("snmp", 0444, net->sctp.proc_net_sctp,
    382			 sctp_snmp_seq_show, NULL))
    383		goto cleanup;
    384	if (!proc_create_net("eps", 0444, net->sctp.proc_net_sctp,
    385			&sctp_eps_ops, sizeof(struct seq_net_private)))
    386		goto cleanup;
    387	if (!proc_create_net("assocs", 0444, net->sctp.proc_net_sctp,
    388			&sctp_assoc_ops, sizeof(struct sctp_ht_iter)))
    389		goto cleanup;
    390	if (!proc_create_net("remaddr", 0444, net->sctp.proc_net_sctp,
    391			&sctp_remaddr_ops, sizeof(struct sctp_ht_iter)))
    392		goto cleanup;
    393	return 0;
    394
    395cleanup:
    396	remove_proc_subtree("sctp", net->proc_net);
    397	net->sctp.proc_net_sctp = NULL;
    398	return -ENOMEM;
    399}