~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/kcm/kcmproc.c

Version: ~ [ linux-5.10-rc5 ] ~ [ linux-5.9.10 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.79 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.159 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.208 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.245 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.245 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 #include <linux/in.h>
  3 #include <linux/inet.h>
  4 #include <linux/list.h>
  5 #include <linux/module.h>
  6 #include <linux/net.h>
  7 #include <linux/proc_fs.h>
  8 #include <linux/rculist.h>
  9 #include <linux/seq_file.h>
 10 #include <linux/socket.h>
 11 #include <net/inet_sock.h>
 12 #include <net/kcm.h>
 13 #include <net/net_namespace.h>
 14 #include <net/netns/generic.h>
 15 #include <net/tcp.h>
 16 
 17 #ifdef CONFIG_PROC_FS
 18 struct kcm_seq_muxinfo {
 19         char                            *name;
 20         const struct file_operations    *seq_fops;
 21         const struct seq_operations     seq_ops;
 22 };
 23 
 24 static struct kcm_mux *kcm_get_first(struct seq_file *seq)
 25 {
 26         struct net *net = seq_file_net(seq);
 27         struct kcm_net *knet = net_generic(net, kcm_net_id);
 28 
 29         return list_first_or_null_rcu(&knet->mux_list,
 30                                       struct kcm_mux, kcm_mux_list);
 31 }
 32 
 33 static struct kcm_mux *kcm_get_next(struct kcm_mux *mux)
 34 {
 35         struct kcm_net *knet = mux->knet;
 36 
 37         return list_next_or_null_rcu(&knet->mux_list, &mux->kcm_mux_list,
 38                                      struct kcm_mux, kcm_mux_list);
 39 }
 40 
 41 static struct kcm_mux *kcm_get_idx(struct seq_file *seq, loff_t pos)
 42 {
 43         struct net *net = seq_file_net(seq);
 44         struct kcm_net *knet = net_generic(net, kcm_net_id);
 45         struct kcm_mux *m;
 46 
 47         list_for_each_entry_rcu(m, &knet->mux_list, kcm_mux_list) {
 48                 if (!pos)
 49                         return m;
 50                 --pos;
 51         }
 52         return NULL;
 53 }
 54 
 55 static void *kcm_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 56 {
 57         void *p;
 58 
 59         if (v == SEQ_START_TOKEN)
 60                 p = kcm_get_first(seq);
 61         else
 62                 p = kcm_get_next(v);
 63         ++*pos;
 64         return p;
 65 }
 66 
 67 static void *kcm_seq_start(struct seq_file *seq, loff_t *pos)
 68         __acquires(rcu)
 69 {
 70         rcu_read_lock();
 71 
 72         if (!*pos)
 73                 return SEQ_START_TOKEN;
 74         else
 75                 return kcm_get_idx(seq, *pos - 1);
 76 }
 77 
 78 static void kcm_seq_stop(struct seq_file *seq, void *v)
 79         __releases(rcu)
 80 {
 81         rcu_read_unlock();
 82 }
 83 
 84 struct kcm_proc_mux_state {
 85         struct seq_net_private p;
 86         int idx;
 87 };
 88 
 89 static int kcm_seq_open(struct inode *inode, struct file *file)
 90 {
 91         struct kcm_seq_muxinfo *muxinfo = PDE_DATA(inode);
 92 
 93         return seq_open_net(inode, file, &muxinfo->seq_ops,
 94                            sizeof(struct kcm_proc_mux_state));
 95 }
 96 
 97 static void kcm_format_mux_header(struct seq_file *seq)
 98 {
 99         struct net *net = seq_file_net(seq);
100         struct kcm_net *knet = net_generic(net, kcm_net_id);
101 
102         seq_printf(seq,
103                    "*** KCM statistics (%d MUX) ****\n",
104                    knet->count);
105 
106         seq_printf(seq,
107                    "%-14s %-10s %-16s %-10s %-16s %-8s %-8s %-8s %-8s %s",
108                    "Object",
109                    "RX-Msgs",
110                    "RX-Bytes",
111                    "TX-Msgs",
112                    "TX-Bytes",
113                    "Recv-Q",
114                    "Rmem",
115                    "Send-Q",
116                    "Smem",
117                    "Status");
118 
119         /* XXX: pdsts header stuff here */
120         seq_puts(seq, "\n");
121 }
122 
123 static void kcm_format_sock(struct kcm_sock *kcm, struct seq_file *seq,
124                             int i, int *len)
125 {
126         seq_printf(seq,
127                    "   kcm-%-7u %-10llu %-16llu %-10llu %-16llu %-8d %-8d %-8d %-8s ",
128                    kcm->index,
129                    kcm->stats.rx_msgs,
130                    kcm->stats.rx_bytes,
131                    kcm->stats.tx_msgs,
132                    kcm->stats.tx_bytes,
133                    kcm->sk.sk_receive_queue.qlen,
134                    sk_rmem_alloc_get(&kcm->sk),
135                    kcm->sk.sk_write_queue.qlen,
136                    "-");
137 
138         if (kcm->tx_psock)
139                 seq_printf(seq, "Psck-%u ", kcm->tx_psock->index);
140 
141         if (kcm->tx_wait)
142                 seq_puts(seq, "TxWait ");
143 
144         if (kcm->tx_wait_more)
145                 seq_puts(seq, "WMore ");
146 
147         if (kcm->rx_wait)
148                 seq_puts(seq, "RxWait ");
149 
150         seq_puts(seq, "\n");
151 }
152 
153 static void kcm_format_psock(struct kcm_psock *psock, struct seq_file *seq,
154                              int i, int *len)
155 {
156         seq_printf(seq,
157                    "   psock-%-5u %-10llu %-16llu %-10llu %-16llu %-8d %-8d %-8d %-8d ",
158                    psock->index,
159                    psock->strp.stats.msgs,
160                    psock->strp.stats.bytes,
161                    psock->stats.tx_msgs,
162                    psock->stats.tx_bytes,
163                    psock->sk->sk_receive_queue.qlen,
164                    atomic_read(&psock->sk->sk_rmem_alloc),
165                    psock->sk->sk_write_queue.qlen,
166                    refcount_read(&psock->sk->sk_wmem_alloc));
167 
168         if (psock->done)
169                 seq_puts(seq, "Done ");
170 
171         if (psock->tx_stopped)
172                 seq_puts(seq, "TxStop ");
173 
174         if (psock->strp.stopped)
175                 seq_puts(seq, "RxStop ");
176 
177         if (psock->tx_kcm)
178                 seq_printf(seq, "Rsvd-%d ", psock->tx_kcm->index);
179 
180         if (!psock->strp.paused && !psock->ready_rx_msg) {
181                 if (psock->sk->sk_receive_queue.qlen) {
182                         if (psock->strp.need_bytes)
183                                 seq_printf(seq, "RxWait=%u ",
184                                            psock->strp.need_bytes);
185                         else
186                                 seq_printf(seq, "RxWait ");
187                 }
188         } else  {
189                 if (psock->strp.paused)
190                         seq_puts(seq, "RxPause ");
191 
192                 if (psock->ready_rx_msg)
193                         seq_puts(seq, "RdyRx ");
194         }
195 
196         seq_puts(seq, "\n");
197 }
198 
199 static void
200 kcm_format_mux(struct kcm_mux *mux, loff_t idx, struct seq_file *seq)
201 {
202         int i, len;
203         struct kcm_sock *kcm;
204         struct kcm_psock *psock;
205 
206         /* mux information */
207         seq_printf(seq,
208                    "%-6s%-8s %-10llu %-16llu %-10llu %-16llu %-8s %-8s %-8s %-8s ",
209                    "mux", "",
210                    mux->stats.rx_msgs,
211                    mux->stats.rx_bytes,
212                    mux->stats.tx_msgs,
213                    mux->stats.tx_bytes,
214                    "-", "-", "-", "-");
215 
216         seq_printf(seq, "KCMs: %d, Psocks %d\n",
217                    mux->kcm_socks_cnt, mux->psocks_cnt);
218 
219         /* kcm sock information */
220         i = 0;
221         spin_lock_bh(&mux->lock);
222         list_for_each_entry(kcm, &mux->kcm_socks, kcm_sock_list) {
223                 kcm_format_sock(kcm, seq, i, &len);
224                 i++;
225         }
226         i = 0;
227         list_for_each_entry(psock, &mux->psocks, psock_list) {
228                 kcm_format_psock(psock, seq, i, &len);
229                 i++;
230         }
231         spin_unlock_bh(&mux->lock);
232 }
233 
234 static int kcm_seq_show(struct seq_file *seq, void *v)
235 {
236         struct kcm_proc_mux_state *mux_state;
237 
238         mux_state = seq->private;
239         if (v == SEQ_START_TOKEN) {
240                 mux_state->idx = 0;
241                 kcm_format_mux_header(seq);
242         } else {
243                 kcm_format_mux(v, mux_state->idx, seq);
244                 mux_state->idx++;
245         }
246         return 0;
247 }
248 
249 static const struct file_operations kcm_seq_fops = {
250         .open           = kcm_seq_open,
251         .read           = seq_read,
252         .llseek         = seq_lseek,
253         .release        = seq_release_net,
254 };
255 
256 static struct kcm_seq_muxinfo kcm_seq_muxinfo = {
257         .name           = "kcm",
258         .seq_fops       = &kcm_seq_fops,
259         .seq_ops        = {
260                 .show   = kcm_seq_show,
261                 .start  = kcm_seq_start,
262                 .next   = kcm_seq_next,
263                 .stop   = kcm_seq_stop,
264         }
265 };
266 
267 static int kcm_proc_register(struct net *net, struct kcm_seq_muxinfo *muxinfo)
268 {
269         struct proc_dir_entry *p;
270         int rc = 0;
271 
272         p = proc_create_data(muxinfo->name, 0444, net->proc_net,
273                              muxinfo->seq_fops, muxinfo);
274         if (!p)
275                 rc = -ENOMEM;
276         return rc;
277 }
278 EXPORT_SYMBOL(kcm_proc_register);
279 
280 static void kcm_proc_unregister(struct net *net,
281                                 struct kcm_seq_muxinfo *muxinfo)
282 {
283         remove_proc_entry(muxinfo->name, net->proc_net);
284 }
285 EXPORT_SYMBOL(kcm_proc_unregister);
286 
287 static int kcm_stats_seq_show(struct seq_file *seq, void *v)
288 {
289         struct kcm_psock_stats psock_stats;
290         struct kcm_mux_stats mux_stats;
291         struct strp_aggr_stats strp_stats;
292         struct kcm_mux *mux;
293         struct kcm_psock *psock;
294         struct net *net = seq->private;
295         struct kcm_net *knet = net_generic(net, kcm_net_id);
296 
297         memset(&mux_stats, 0, sizeof(mux_stats));
298         memset(&psock_stats, 0, sizeof(psock_stats));
299         memset(&strp_stats, 0, sizeof(strp_stats));
300 
301         mutex_lock(&knet->mutex);
302 
303         aggregate_mux_stats(&knet->aggregate_mux_stats, &mux_stats);
304         aggregate_psock_stats(&knet->aggregate_psock_stats,
305                               &psock_stats);
306         aggregate_strp_stats(&knet->aggregate_strp_stats,
307                              &strp_stats);
308 
309         list_for_each_entry_rcu(mux, &knet->mux_list, kcm_mux_list) {
310                 spin_lock_bh(&mux->lock);
311                 aggregate_mux_stats(&mux->stats, &mux_stats);
312                 aggregate_psock_stats(&mux->aggregate_psock_stats,
313                                       &psock_stats);
314                 aggregate_strp_stats(&mux->aggregate_strp_stats,
315                                      &strp_stats);
316                 list_for_each_entry(psock, &mux->psocks, psock_list) {
317                         aggregate_psock_stats(&psock->stats, &psock_stats);
318                         save_strp_stats(&psock->strp, &strp_stats);
319                 }
320 
321                 spin_unlock_bh(&mux->lock);
322         }
323 
324         mutex_unlock(&knet->mutex);
325 
326         seq_printf(seq,
327                    "%-8s %-10s %-16s %-10s %-16s %-10s %-10s %-10s %-10s %-10s\n",
328                    "MUX",
329                    "RX-Msgs",
330                    "RX-Bytes",
331                    "TX-Msgs",
332                    "TX-Bytes",
333                    "TX-Retries",
334                    "Attach",
335                    "Unattach",
336                    "UnattchRsvd",
337                    "RX-RdyDrops");
338 
339         seq_printf(seq,
340                    "%-8s %-10llu %-16llu %-10llu %-16llu %-10u %-10u %-10u %-10u %-10u\n",
341                    "",
342                    mux_stats.rx_msgs,
343                    mux_stats.rx_bytes,
344                    mux_stats.tx_msgs,
345                    mux_stats.tx_bytes,
346                    mux_stats.tx_retries,
347                    mux_stats.psock_attach,
348                    mux_stats.psock_unattach_rsvd,
349                    mux_stats.psock_unattach,
350                    mux_stats.rx_ready_drops);
351 
352         seq_printf(seq,
353                    "%-8s %-10s %-16s %-10s %-16s %-10s %-10s %-10s %-10s %-10s %-10s %-10s %-10s %-10s %-10s %-10s\n",
354                    "Psock",
355                    "RX-Msgs",
356                    "RX-Bytes",
357                    "TX-Msgs",
358                    "TX-Bytes",
359                    "Reserved",
360                    "Unreserved",
361                    "RX-Aborts",
362                    "RX-Intr",
363                    "RX-Unrecov",
364                    "RX-MemFail",
365                    "RX-NeedMor",
366                    "RX-BadLen",
367                    "RX-TooBig",
368                    "RX-Timeout",
369                    "TX-Aborts");
370 
371         seq_printf(seq,
372                    "%-8s %-10llu %-16llu %-10llu %-16llu %-10llu %-10llu %-10u %-10u %-10u %-10u %-10u %-10u %-10u %-10u %-10u\n",
373                    "",
374                    strp_stats.msgs,
375                    strp_stats.bytes,
376                    psock_stats.tx_msgs,
377                    psock_stats.tx_bytes,
378                    psock_stats.reserved,
379                    psock_stats.unreserved,
380                    strp_stats.aborts,
381                    strp_stats.interrupted,
382                    strp_stats.unrecov_intr,
383                    strp_stats.mem_fail,
384                    strp_stats.need_more_hdr,
385                    strp_stats.bad_hdr_len,
386                    strp_stats.msg_too_big,
387                    strp_stats.msg_timeouts,
388                    psock_stats.tx_aborts);
389 
390         return 0;
391 }
392 
393 static int kcm_stats_seq_open(struct inode *inode, struct file *file)
394 {
395         return single_open_net(inode, file, kcm_stats_seq_show);
396 }
397 
398 static const struct file_operations kcm_stats_seq_fops = {
399         .open    = kcm_stats_seq_open,
400         .read    = seq_read,
401         .llseek  = seq_lseek,
402         .release = single_release_net,
403 };
404 
405 static int kcm_proc_init_net(struct net *net)
406 {
407         int err;
408 
409         if (!proc_create("kcm_stats", 0444, net->proc_net,
410                          &kcm_stats_seq_fops)) {
411                 err = -ENOMEM;
412                 goto out_kcm_stats;
413         }
414 
415         err = kcm_proc_register(net, &kcm_seq_muxinfo);
416         if (err)
417                 goto out_kcm;
418 
419         return 0;
420 
421 out_kcm:
422         remove_proc_entry("kcm_stats", net->proc_net);
423 out_kcm_stats:
424         return err;
425 }
426 
427 static void kcm_proc_exit_net(struct net *net)
428 {
429         kcm_proc_unregister(net, &kcm_seq_muxinfo);
430         remove_proc_entry("kcm_stats", net->proc_net);
431 }
432 
433 static struct pernet_operations kcm_net_ops = {
434         .init = kcm_proc_init_net,
435         .exit = kcm_proc_exit_net,
436 };
437 
438 int __init kcm_proc_init(void)
439 {
440         return register_pernet_subsys(&kcm_net_ops);
441 }
442 
443 void __exit kcm_proc_exit(void)
444 {
445         unregister_pernet_subsys(&kcm_net_ops);
446 }
447 
448 #endif /* CONFIG_PROC_FS */
449 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp