18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci#include <linux/in.h> 38c2ecf20Sopenharmony_ci#include <linux/inet.h> 48c2ecf20Sopenharmony_ci#include <linux/list.h> 58c2ecf20Sopenharmony_ci#include <linux/module.h> 68c2ecf20Sopenharmony_ci#include <linux/net.h> 78c2ecf20Sopenharmony_ci#include <linux/proc_fs.h> 88c2ecf20Sopenharmony_ci#include <linux/rculist.h> 98c2ecf20Sopenharmony_ci#include <linux/seq_file.h> 108c2ecf20Sopenharmony_ci#include <linux/socket.h> 118c2ecf20Sopenharmony_ci#include <net/inet_sock.h> 128c2ecf20Sopenharmony_ci#include <net/kcm.h> 138c2ecf20Sopenharmony_ci#include <net/net_namespace.h> 148c2ecf20Sopenharmony_ci#include <net/netns/generic.h> 158c2ecf20Sopenharmony_ci#include <net/tcp.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#ifdef CONFIG_PROC_FS 188c2ecf20Sopenharmony_cistatic struct kcm_mux *kcm_get_first(struct seq_file *seq) 198c2ecf20Sopenharmony_ci{ 208c2ecf20Sopenharmony_ci struct net *net = seq_file_net(seq); 218c2ecf20Sopenharmony_ci struct kcm_net *knet = net_generic(net, kcm_net_id); 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci return list_first_or_null_rcu(&knet->mux_list, 248c2ecf20Sopenharmony_ci struct kcm_mux, kcm_mux_list); 258c2ecf20Sopenharmony_ci} 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_cistatic struct kcm_mux *kcm_get_next(struct kcm_mux *mux) 288c2ecf20Sopenharmony_ci{ 298c2ecf20Sopenharmony_ci struct kcm_net *knet = mux->knet; 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci return list_next_or_null_rcu(&knet->mux_list, &mux->kcm_mux_list, 328c2ecf20Sopenharmony_ci struct kcm_mux, kcm_mux_list); 338c2ecf20Sopenharmony_ci} 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cistatic struct kcm_mux *kcm_get_idx(struct seq_file *seq, loff_t pos) 368c2ecf20Sopenharmony_ci{ 378c2ecf20Sopenharmony_ci struct net *net = seq_file_net(seq); 388c2ecf20Sopenharmony_ci struct kcm_net *knet = net_generic(net, kcm_net_id); 398c2ecf20Sopenharmony_ci struct kcm_mux *m; 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci list_for_each_entry_rcu(m, &knet->mux_list, kcm_mux_list) { 428c2ecf20Sopenharmony_ci if (!pos) 438c2ecf20Sopenharmony_ci return m; 448c2ecf20Sopenharmony_ci --pos; 458c2ecf20Sopenharmony_ci } 468c2ecf20Sopenharmony_ci return NULL; 478c2ecf20Sopenharmony_ci} 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_cistatic void *kcm_seq_next(struct seq_file *seq, void *v, loff_t *pos) 508c2ecf20Sopenharmony_ci{ 518c2ecf20Sopenharmony_ci void *p; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci if (v == SEQ_START_TOKEN) 548c2ecf20Sopenharmony_ci p = kcm_get_first(seq); 558c2ecf20Sopenharmony_ci else 568c2ecf20Sopenharmony_ci p = kcm_get_next(v); 578c2ecf20Sopenharmony_ci ++*pos; 588c2ecf20Sopenharmony_ci return p; 598c2ecf20Sopenharmony_ci} 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_cistatic void *kcm_seq_start(struct seq_file *seq, loff_t *pos) 628c2ecf20Sopenharmony_ci __acquires(rcu) 638c2ecf20Sopenharmony_ci{ 648c2ecf20Sopenharmony_ci rcu_read_lock(); 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci if (!*pos) 678c2ecf20Sopenharmony_ci return SEQ_START_TOKEN; 688c2ecf20Sopenharmony_ci else 698c2ecf20Sopenharmony_ci return kcm_get_idx(seq, *pos - 1); 708c2ecf20Sopenharmony_ci} 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_cistatic void kcm_seq_stop(struct seq_file *seq, void *v) 738c2ecf20Sopenharmony_ci __releases(rcu) 748c2ecf20Sopenharmony_ci{ 758c2ecf20Sopenharmony_ci rcu_read_unlock(); 768c2ecf20Sopenharmony_ci} 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_cistruct kcm_proc_mux_state { 798c2ecf20Sopenharmony_ci struct seq_net_private p; 808c2ecf20Sopenharmony_ci int idx; 818c2ecf20Sopenharmony_ci}; 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_cistatic void kcm_format_mux_header(struct seq_file *seq) 848c2ecf20Sopenharmony_ci{ 858c2ecf20Sopenharmony_ci struct net *net = seq_file_net(seq); 868c2ecf20Sopenharmony_ci struct kcm_net *knet = net_generic(net, kcm_net_id); 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci seq_printf(seq, 898c2ecf20Sopenharmony_ci "*** KCM statistics (%d MUX) ****\n", 908c2ecf20Sopenharmony_ci knet->count); 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci seq_printf(seq, 938c2ecf20Sopenharmony_ci "%-14s %-10s %-16s %-10s %-16s %-8s %-8s %-8s %-8s %s", 948c2ecf20Sopenharmony_ci "Object", 958c2ecf20Sopenharmony_ci "RX-Msgs", 968c2ecf20Sopenharmony_ci "RX-Bytes", 978c2ecf20Sopenharmony_ci "TX-Msgs", 988c2ecf20Sopenharmony_ci "TX-Bytes", 998c2ecf20Sopenharmony_ci "Recv-Q", 1008c2ecf20Sopenharmony_ci "Rmem", 1018c2ecf20Sopenharmony_ci "Send-Q", 1028c2ecf20Sopenharmony_ci "Smem", 1038c2ecf20Sopenharmony_ci "Status"); 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci /* XXX: pdsts header stuff here */ 1068c2ecf20Sopenharmony_ci seq_puts(seq, "\n"); 1078c2ecf20Sopenharmony_ci} 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_cistatic void kcm_format_sock(struct kcm_sock *kcm, struct seq_file *seq, 1108c2ecf20Sopenharmony_ci int i, int *len) 1118c2ecf20Sopenharmony_ci{ 1128c2ecf20Sopenharmony_ci seq_printf(seq, 1138c2ecf20Sopenharmony_ci " kcm-%-7u %-10llu %-16llu %-10llu %-16llu %-8d %-8d %-8d %-8s ", 1148c2ecf20Sopenharmony_ci kcm->index, 1158c2ecf20Sopenharmony_ci kcm->stats.rx_msgs, 1168c2ecf20Sopenharmony_ci kcm->stats.rx_bytes, 1178c2ecf20Sopenharmony_ci kcm->stats.tx_msgs, 1188c2ecf20Sopenharmony_ci kcm->stats.tx_bytes, 1198c2ecf20Sopenharmony_ci kcm->sk.sk_receive_queue.qlen, 1208c2ecf20Sopenharmony_ci sk_rmem_alloc_get(&kcm->sk), 1218c2ecf20Sopenharmony_ci kcm->sk.sk_write_queue.qlen, 1228c2ecf20Sopenharmony_ci "-"); 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci if (kcm->tx_psock) 1258c2ecf20Sopenharmony_ci seq_printf(seq, "Psck-%u ", kcm->tx_psock->index); 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci if (kcm->tx_wait) 1288c2ecf20Sopenharmony_ci seq_puts(seq, "TxWait "); 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci if (kcm->tx_wait_more) 1318c2ecf20Sopenharmony_ci seq_puts(seq, "WMore "); 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci if (kcm->rx_wait) 1348c2ecf20Sopenharmony_ci seq_puts(seq, "RxWait "); 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci seq_puts(seq, "\n"); 1378c2ecf20Sopenharmony_ci} 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_cistatic void kcm_format_psock(struct kcm_psock *psock, struct seq_file *seq, 1408c2ecf20Sopenharmony_ci int i, int *len) 1418c2ecf20Sopenharmony_ci{ 1428c2ecf20Sopenharmony_ci seq_printf(seq, 1438c2ecf20Sopenharmony_ci " psock-%-5u %-10llu %-16llu %-10llu %-16llu %-8d %-8d %-8d %-8d ", 1448c2ecf20Sopenharmony_ci psock->index, 1458c2ecf20Sopenharmony_ci psock->strp.stats.msgs, 1468c2ecf20Sopenharmony_ci psock->strp.stats.bytes, 1478c2ecf20Sopenharmony_ci psock->stats.tx_msgs, 1488c2ecf20Sopenharmony_ci psock->stats.tx_bytes, 1498c2ecf20Sopenharmony_ci psock->sk->sk_receive_queue.qlen, 1508c2ecf20Sopenharmony_ci atomic_read(&psock->sk->sk_rmem_alloc), 1518c2ecf20Sopenharmony_ci psock->sk->sk_write_queue.qlen, 1528c2ecf20Sopenharmony_ci refcount_read(&psock->sk->sk_wmem_alloc)); 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci if (psock->done) 1558c2ecf20Sopenharmony_ci seq_puts(seq, "Done "); 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci if (psock->tx_stopped) 1588c2ecf20Sopenharmony_ci seq_puts(seq, "TxStop "); 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci if (psock->strp.stopped) 1618c2ecf20Sopenharmony_ci seq_puts(seq, "RxStop "); 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci if (psock->tx_kcm) 1648c2ecf20Sopenharmony_ci seq_printf(seq, "Rsvd-%d ", psock->tx_kcm->index); 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci if (!psock->strp.paused && !psock->ready_rx_msg) { 1678c2ecf20Sopenharmony_ci if (psock->sk->sk_receive_queue.qlen) { 1688c2ecf20Sopenharmony_ci if (psock->strp.need_bytes) 1698c2ecf20Sopenharmony_ci seq_printf(seq, "RxWait=%u ", 1708c2ecf20Sopenharmony_ci psock->strp.need_bytes); 1718c2ecf20Sopenharmony_ci else 1728c2ecf20Sopenharmony_ci seq_printf(seq, "RxWait "); 1738c2ecf20Sopenharmony_ci } 1748c2ecf20Sopenharmony_ci } else { 1758c2ecf20Sopenharmony_ci if (psock->strp.paused) 1768c2ecf20Sopenharmony_ci seq_puts(seq, "RxPause "); 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci if (psock->ready_rx_msg) 1798c2ecf20Sopenharmony_ci seq_puts(seq, "RdyRx "); 1808c2ecf20Sopenharmony_ci } 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci seq_puts(seq, "\n"); 1838c2ecf20Sopenharmony_ci} 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_cistatic void 1868c2ecf20Sopenharmony_cikcm_format_mux(struct kcm_mux *mux, loff_t idx, struct seq_file *seq) 1878c2ecf20Sopenharmony_ci{ 1888c2ecf20Sopenharmony_ci int i, len; 1898c2ecf20Sopenharmony_ci struct kcm_sock *kcm; 1908c2ecf20Sopenharmony_ci struct kcm_psock *psock; 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_ci /* mux information */ 1938c2ecf20Sopenharmony_ci seq_printf(seq, 1948c2ecf20Sopenharmony_ci "%-6s%-8s %-10llu %-16llu %-10llu %-16llu %-8s %-8s %-8s %-8s ", 1958c2ecf20Sopenharmony_ci "mux", "", 1968c2ecf20Sopenharmony_ci mux->stats.rx_msgs, 1978c2ecf20Sopenharmony_ci mux->stats.rx_bytes, 1988c2ecf20Sopenharmony_ci mux->stats.tx_msgs, 1998c2ecf20Sopenharmony_ci mux->stats.tx_bytes, 2008c2ecf20Sopenharmony_ci "-", "-", "-", "-"); 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ci seq_printf(seq, "KCMs: %d, Psocks %d\n", 2038c2ecf20Sopenharmony_ci mux->kcm_socks_cnt, mux->psocks_cnt); 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci /* kcm sock information */ 2068c2ecf20Sopenharmony_ci i = 0; 2078c2ecf20Sopenharmony_ci spin_lock_bh(&mux->lock); 2088c2ecf20Sopenharmony_ci list_for_each_entry(kcm, &mux->kcm_socks, kcm_sock_list) { 2098c2ecf20Sopenharmony_ci kcm_format_sock(kcm, seq, i, &len); 2108c2ecf20Sopenharmony_ci i++; 2118c2ecf20Sopenharmony_ci } 2128c2ecf20Sopenharmony_ci i = 0; 2138c2ecf20Sopenharmony_ci list_for_each_entry(psock, &mux->psocks, psock_list) { 2148c2ecf20Sopenharmony_ci kcm_format_psock(psock, seq, i, &len); 2158c2ecf20Sopenharmony_ci i++; 2168c2ecf20Sopenharmony_ci } 2178c2ecf20Sopenharmony_ci spin_unlock_bh(&mux->lock); 2188c2ecf20Sopenharmony_ci} 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_cistatic int kcm_seq_show(struct seq_file *seq, void *v) 2218c2ecf20Sopenharmony_ci{ 2228c2ecf20Sopenharmony_ci struct kcm_proc_mux_state *mux_state; 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci mux_state = seq->private; 2258c2ecf20Sopenharmony_ci if (v == SEQ_START_TOKEN) { 2268c2ecf20Sopenharmony_ci mux_state->idx = 0; 2278c2ecf20Sopenharmony_ci kcm_format_mux_header(seq); 2288c2ecf20Sopenharmony_ci } else { 2298c2ecf20Sopenharmony_ci kcm_format_mux(v, mux_state->idx, seq); 2308c2ecf20Sopenharmony_ci mux_state->idx++; 2318c2ecf20Sopenharmony_ci } 2328c2ecf20Sopenharmony_ci return 0; 2338c2ecf20Sopenharmony_ci} 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_cistatic const struct seq_operations kcm_seq_ops = { 2368c2ecf20Sopenharmony_ci .show = kcm_seq_show, 2378c2ecf20Sopenharmony_ci .start = kcm_seq_start, 2388c2ecf20Sopenharmony_ci .next = kcm_seq_next, 2398c2ecf20Sopenharmony_ci .stop = kcm_seq_stop, 2408c2ecf20Sopenharmony_ci}; 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_cistatic int kcm_stats_seq_show(struct seq_file *seq, void *v) 2438c2ecf20Sopenharmony_ci{ 2448c2ecf20Sopenharmony_ci struct kcm_psock_stats psock_stats; 2458c2ecf20Sopenharmony_ci struct kcm_mux_stats mux_stats; 2468c2ecf20Sopenharmony_ci struct strp_aggr_stats strp_stats; 2478c2ecf20Sopenharmony_ci struct kcm_mux *mux; 2488c2ecf20Sopenharmony_ci struct kcm_psock *psock; 2498c2ecf20Sopenharmony_ci struct net *net = seq->private; 2508c2ecf20Sopenharmony_ci struct kcm_net *knet = net_generic(net, kcm_net_id); 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci memset(&mux_stats, 0, sizeof(mux_stats)); 2538c2ecf20Sopenharmony_ci memset(&psock_stats, 0, sizeof(psock_stats)); 2548c2ecf20Sopenharmony_ci memset(&strp_stats, 0, sizeof(strp_stats)); 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci mutex_lock(&knet->mutex); 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci aggregate_mux_stats(&knet->aggregate_mux_stats, &mux_stats); 2598c2ecf20Sopenharmony_ci aggregate_psock_stats(&knet->aggregate_psock_stats, 2608c2ecf20Sopenharmony_ci &psock_stats); 2618c2ecf20Sopenharmony_ci aggregate_strp_stats(&knet->aggregate_strp_stats, 2628c2ecf20Sopenharmony_ci &strp_stats); 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci list_for_each_entry(mux, &knet->mux_list, kcm_mux_list) { 2658c2ecf20Sopenharmony_ci spin_lock_bh(&mux->lock); 2668c2ecf20Sopenharmony_ci aggregate_mux_stats(&mux->stats, &mux_stats); 2678c2ecf20Sopenharmony_ci aggregate_psock_stats(&mux->aggregate_psock_stats, 2688c2ecf20Sopenharmony_ci &psock_stats); 2698c2ecf20Sopenharmony_ci aggregate_strp_stats(&mux->aggregate_strp_stats, 2708c2ecf20Sopenharmony_ci &strp_stats); 2718c2ecf20Sopenharmony_ci list_for_each_entry(psock, &mux->psocks, psock_list) { 2728c2ecf20Sopenharmony_ci aggregate_psock_stats(&psock->stats, &psock_stats); 2738c2ecf20Sopenharmony_ci save_strp_stats(&psock->strp, &strp_stats); 2748c2ecf20Sopenharmony_ci } 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci spin_unlock_bh(&mux->lock); 2778c2ecf20Sopenharmony_ci } 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci mutex_unlock(&knet->mutex); 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ci seq_printf(seq, 2828c2ecf20Sopenharmony_ci "%-8s %-10s %-16s %-10s %-16s %-10s %-10s %-10s %-10s %-10s\n", 2838c2ecf20Sopenharmony_ci "MUX", 2848c2ecf20Sopenharmony_ci "RX-Msgs", 2858c2ecf20Sopenharmony_ci "RX-Bytes", 2868c2ecf20Sopenharmony_ci "TX-Msgs", 2878c2ecf20Sopenharmony_ci "TX-Bytes", 2888c2ecf20Sopenharmony_ci "TX-Retries", 2898c2ecf20Sopenharmony_ci "Attach", 2908c2ecf20Sopenharmony_ci "Unattach", 2918c2ecf20Sopenharmony_ci "UnattchRsvd", 2928c2ecf20Sopenharmony_ci "RX-RdyDrops"); 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ci seq_printf(seq, 2958c2ecf20Sopenharmony_ci "%-8s %-10llu %-16llu %-10llu %-16llu %-10u %-10u %-10u %-10u %-10u\n", 2968c2ecf20Sopenharmony_ci "", 2978c2ecf20Sopenharmony_ci mux_stats.rx_msgs, 2988c2ecf20Sopenharmony_ci mux_stats.rx_bytes, 2998c2ecf20Sopenharmony_ci mux_stats.tx_msgs, 3008c2ecf20Sopenharmony_ci mux_stats.tx_bytes, 3018c2ecf20Sopenharmony_ci mux_stats.tx_retries, 3028c2ecf20Sopenharmony_ci mux_stats.psock_attach, 3038c2ecf20Sopenharmony_ci mux_stats.psock_unattach_rsvd, 3048c2ecf20Sopenharmony_ci mux_stats.psock_unattach, 3058c2ecf20Sopenharmony_ci mux_stats.rx_ready_drops); 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ci seq_printf(seq, 3088c2ecf20Sopenharmony_ci "%-8s %-10s %-16s %-10s %-16s %-10s %-10s %-10s %-10s %-10s %-10s %-10s %-10s %-10s %-10s %-10s\n", 3098c2ecf20Sopenharmony_ci "Psock", 3108c2ecf20Sopenharmony_ci "RX-Msgs", 3118c2ecf20Sopenharmony_ci "RX-Bytes", 3128c2ecf20Sopenharmony_ci "TX-Msgs", 3138c2ecf20Sopenharmony_ci "TX-Bytes", 3148c2ecf20Sopenharmony_ci "Reserved", 3158c2ecf20Sopenharmony_ci "Unreserved", 3168c2ecf20Sopenharmony_ci "RX-Aborts", 3178c2ecf20Sopenharmony_ci "RX-Intr", 3188c2ecf20Sopenharmony_ci "RX-Unrecov", 3198c2ecf20Sopenharmony_ci "RX-MemFail", 3208c2ecf20Sopenharmony_ci "RX-NeedMor", 3218c2ecf20Sopenharmony_ci "RX-BadLen", 3228c2ecf20Sopenharmony_ci "RX-TooBig", 3238c2ecf20Sopenharmony_ci "RX-Timeout", 3248c2ecf20Sopenharmony_ci "TX-Aborts"); 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_ci seq_printf(seq, 3278c2ecf20Sopenharmony_ci "%-8s %-10llu %-16llu %-10llu %-16llu %-10llu %-10llu %-10u %-10u %-10u %-10u %-10u %-10u %-10u %-10u %-10u\n", 3288c2ecf20Sopenharmony_ci "", 3298c2ecf20Sopenharmony_ci strp_stats.msgs, 3308c2ecf20Sopenharmony_ci strp_stats.bytes, 3318c2ecf20Sopenharmony_ci psock_stats.tx_msgs, 3328c2ecf20Sopenharmony_ci psock_stats.tx_bytes, 3338c2ecf20Sopenharmony_ci psock_stats.reserved, 3348c2ecf20Sopenharmony_ci psock_stats.unreserved, 3358c2ecf20Sopenharmony_ci strp_stats.aborts, 3368c2ecf20Sopenharmony_ci strp_stats.interrupted, 3378c2ecf20Sopenharmony_ci strp_stats.unrecov_intr, 3388c2ecf20Sopenharmony_ci strp_stats.mem_fail, 3398c2ecf20Sopenharmony_ci strp_stats.need_more_hdr, 3408c2ecf20Sopenharmony_ci strp_stats.bad_hdr_len, 3418c2ecf20Sopenharmony_ci strp_stats.msg_too_big, 3428c2ecf20Sopenharmony_ci strp_stats.msg_timeouts, 3438c2ecf20Sopenharmony_ci psock_stats.tx_aborts); 3448c2ecf20Sopenharmony_ci 3458c2ecf20Sopenharmony_ci return 0; 3468c2ecf20Sopenharmony_ci} 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_cistatic int kcm_proc_init_net(struct net *net) 3498c2ecf20Sopenharmony_ci{ 3508c2ecf20Sopenharmony_ci if (!proc_create_net_single("kcm_stats", 0444, net->proc_net, 3518c2ecf20Sopenharmony_ci kcm_stats_seq_show, NULL)) 3528c2ecf20Sopenharmony_ci goto out_kcm_stats; 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_ci if (!proc_create_net("kcm", 0444, net->proc_net, &kcm_seq_ops, 3558c2ecf20Sopenharmony_ci sizeof(struct kcm_proc_mux_state))) 3568c2ecf20Sopenharmony_ci goto out_kcm; 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ci return 0; 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ciout_kcm: 3618c2ecf20Sopenharmony_ci remove_proc_entry("kcm_stats", net->proc_net); 3628c2ecf20Sopenharmony_ciout_kcm_stats: 3638c2ecf20Sopenharmony_ci return -ENOMEM; 3648c2ecf20Sopenharmony_ci} 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_cistatic void kcm_proc_exit_net(struct net *net) 3678c2ecf20Sopenharmony_ci{ 3688c2ecf20Sopenharmony_ci remove_proc_entry("kcm", net->proc_net); 3698c2ecf20Sopenharmony_ci remove_proc_entry("kcm_stats", net->proc_net); 3708c2ecf20Sopenharmony_ci} 3718c2ecf20Sopenharmony_ci 3728c2ecf20Sopenharmony_cistatic struct pernet_operations kcm_net_ops = { 3738c2ecf20Sopenharmony_ci .init = kcm_proc_init_net, 3748c2ecf20Sopenharmony_ci .exit = kcm_proc_exit_net, 3758c2ecf20Sopenharmony_ci}; 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ciint __init kcm_proc_init(void) 3788c2ecf20Sopenharmony_ci{ 3798c2ecf20Sopenharmony_ci return register_pernet_subsys(&kcm_net_ops); 3808c2ecf20Sopenharmony_ci} 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_civoid __exit kcm_proc_exit(void) 3838c2ecf20Sopenharmony_ci{ 3848c2ecf20Sopenharmony_ci unregister_pernet_subsys(&kcm_net_ops); 3858c2ecf20Sopenharmony_ci} 3868c2ecf20Sopenharmony_ci 3878c2ecf20Sopenharmony_ci#endif /* CONFIG_PROC_FS */ 388