1// SPDX-License-Identifier: GPL-2.0-only
2#include <linux/kernel.h>
3#include <linux/proc_fs.h>
4#include <net/netfilter/nf_flow_table.h>
5
6static void *nf_flow_table_cpu_seq_start(struct seq_file *seq, loff_t *pos)
7{
8 struct net *net = seq_file_net(seq);
9 int cpu;
10
11 if (*pos == 0)
12 return SEQ_START_TOKEN;
13
14 for (cpu = *pos - 1; cpu < nr_cpu_ids; ++cpu) {
15 if (!cpu_possible(cpu))
16 continue;
17 *pos = cpu + 1;
18 return per_cpu_ptr(net->ft.stat, cpu);
19 }
20
21 return NULL;
22}
23
24static void *nf_flow_table_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos)
25{
26 struct net *net = seq_file_net(seq);
27 int cpu;
28
29 for (cpu = *pos; cpu < nr_cpu_ids; ++cpu) {
30 if (!cpu_possible(cpu))
31 continue;
32 *pos = cpu + 1;
33 return per_cpu_ptr(net->ft.stat, cpu);
34 }
35 (*pos)++;
36 return NULL;
37}
38
39static void nf_flow_table_cpu_seq_stop(struct seq_file *seq, void *v)
40{
41}
42
43static int nf_flow_table_cpu_seq_show(struct seq_file *seq, void *v)
44{
45 const struct nf_flow_table_stat *st = v;
46
47 if (v == SEQ_START_TOKEN) {
48 seq_puts(m: seq, s: "wq_add wq_del wq_stats\n");
49 return 0;
50 }
51
52 seq_printf(m: seq, fmt: "%8d %8d %8d\n",
53 st->count_wq_add,
54 st->count_wq_del,
55 st->count_wq_stats
56 );
57 return 0;
58}
59
60static const struct seq_operations nf_flow_table_cpu_seq_ops = {
61 .start = nf_flow_table_cpu_seq_start,
62 .next = nf_flow_table_cpu_seq_next,
63 .stop = nf_flow_table_cpu_seq_stop,
64 .show = nf_flow_table_cpu_seq_show,
65};
66
67int nf_flow_table_init_proc(struct net *net)
68{
69 struct proc_dir_entry *pde;
70
71 pde = proc_create_net("nf_flowtable", 0444, net->proc_net_stat,
72 &nf_flow_table_cpu_seq_ops,
73 sizeof(struct seq_net_private));
74 return pde ? 0 : -ENOMEM;
75}
76
77void nf_flow_table_fini_proc(struct net *net)
78{
79 remove_proc_entry("nf_flowtable", net->proc_net_stat);
80}
81

source code of linux/net/netfilter/nf_flow_table_procfs.c