]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - net/ipv6/proc.c
[NET]: all net/ cleanup with ARRAY_SIZE
[mirror_ubuntu-jammy-kernel.git] / net / ipv6 / proc.c
CommitLineData
1da177e4
LT
1/*
2 * INET An implementation of the TCP/IP protocol suite for the LINUX
3 * operating system. INET is implemented using the BSD Socket
4 * interface as the means of communication with the user level.
5 *
6 * This file implements the various access functions for the
7 * PROC file system. This is very similar to the IPv4 version,
8 * except it reports the sockets in the INET6 address family.
9 *
10 * Version: $Id: proc.c,v 1.17 2002/02/01 22:01:04 davem Exp $
11 *
12 * Authors: David S. Miller (davem@caip.rutgers.edu)
13 * YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version
18 * 2 of the License, or (at your option) any later version.
19 */
1da177e4
LT
20#include <linux/socket.h>
21#include <linux/net.h>
22#include <linux/ipv6.h>
23#include <linux/proc_fs.h>
24#include <linux/seq_file.h>
25#include <linux/stddef.h>
457c4cbc 26#include <net/net_namespace.h>
7f7d9a6b 27#include <net/ip.h>
1da177e4
LT
28#include <net/sock.h>
29#include <net/tcp.h>
30#include <net/transp_v6.h>
31#include <net/ipv6.h>
32
1da177e4
LT
33static struct proc_dir_entry *proc_net_devsnmp6;
34
35static int fold_prot_inuse(struct proto *proto)
36{
37 int res = 0;
38 int cpu;
39
6f912042 40 for_each_possible_cpu(cpu)
1da177e4
LT
41 res += proto->stats[cpu].inuse;
42
43 return res;
44}
45
46static int sockstat6_seq_show(struct seq_file *seq, void *v)
47{
48 seq_printf(seq, "TCP6: inuse %d\n",
49 fold_prot_inuse(&tcpv6_prot));
50 seq_printf(seq, "UDP6: inuse %d\n",
51 fold_prot_inuse(&udpv6_prot));
ba4e58ec 52 seq_printf(seq, "UDPLITE6: inuse %d\n",
1ab1457c 53 fold_prot_inuse(&udplitev6_prot));
1da177e4
LT
54 seq_printf(seq, "RAW6: inuse %d\n",
55 fold_prot_inuse(&rawv6_prot));
56 seq_printf(seq, "FRAG6: inuse %d memory %d\n",
57 ip6_frag_nqueues, atomic_read(&ip6_frag_mem));
58 return 0;
59}
60
61static struct snmp_mib snmp6_ipstats_list[] = {
62/* ipv6 mib according to RFC 2465 */
63 SNMP_MIB_ITEM("Ip6InReceives", IPSTATS_MIB_INRECEIVES),
64 SNMP_MIB_ITEM("Ip6InHdrErrors", IPSTATS_MIB_INHDRERRORS),
65 SNMP_MIB_ITEM("Ip6InTooBigErrors", IPSTATS_MIB_INTOOBIGERRORS),
66 SNMP_MIB_ITEM("Ip6InNoRoutes", IPSTATS_MIB_INNOROUTES),
67 SNMP_MIB_ITEM("Ip6InAddrErrors", IPSTATS_MIB_INADDRERRORS),
68 SNMP_MIB_ITEM("Ip6InUnknownProtos", IPSTATS_MIB_INUNKNOWNPROTOS),
69 SNMP_MIB_ITEM("Ip6InTruncatedPkts", IPSTATS_MIB_INTRUNCATEDPKTS),
70 SNMP_MIB_ITEM("Ip6InDiscards", IPSTATS_MIB_INDISCARDS),
71 SNMP_MIB_ITEM("Ip6InDelivers", IPSTATS_MIB_INDELIVERS),
72 SNMP_MIB_ITEM("Ip6OutForwDatagrams", IPSTATS_MIB_OUTFORWDATAGRAMS),
73 SNMP_MIB_ITEM("Ip6OutRequests", IPSTATS_MIB_OUTREQUESTS),
74 SNMP_MIB_ITEM("Ip6OutDiscards", IPSTATS_MIB_OUTDISCARDS),
75 SNMP_MIB_ITEM("Ip6OutNoRoutes", IPSTATS_MIB_OUTNOROUTES),
76 SNMP_MIB_ITEM("Ip6ReasmTimeout", IPSTATS_MIB_REASMTIMEOUT),
77 SNMP_MIB_ITEM("Ip6ReasmReqds", IPSTATS_MIB_REASMREQDS),
78 SNMP_MIB_ITEM("Ip6ReasmOKs", IPSTATS_MIB_REASMOKS),
79 SNMP_MIB_ITEM("Ip6ReasmFails", IPSTATS_MIB_REASMFAILS),
80 SNMP_MIB_ITEM("Ip6FragOKs", IPSTATS_MIB_FRAGOKS),
81 SNMP_MIB_ITEM("Ip6FragFails", IPSTATS_MIB_FRAGFAILS),
82 SNMP_MIB_ITEM("Ip6FragCreates", IPSTATS_MIB_FRAGCREATES),
83 SNMP_MIB_ITEM("Ip6InMcastPkts", IPSTATS_MIB_INMCASTPKTS),
84 SNMP_MIB_ITEM("Ip6OutMcastPkts", IPSTATS_MIB_OUTMCASTPKTS),
85 SNMP_MIB_SENTINEL
86};
87
88static struct snmp_mib snmp6_icmp6_list[] = {
89/* icmpv6 mib according to RFC 2466
90
91 Exceptions: {In|Out}AdminProhibs are removed, because I see
1ab1457c 92 no good reasons to account them separately
1da177e4
LT
93 of another dest.unreachs.
94 OutErrs is zero identically.
95 OutEchos too.
96 OutRouterAdvertisements too.
97 OutGroupMembQueries too.
98 */
99 SNMP_MIB_ITEM("Icmp6InMsgs", ICMP6_MIB_INMSGS),
100 SNMP_MIB_ITEM("Icmp6InErrors", ICMP6_MIB_INERRORS),
101 SNMP_MIB_ITEM("Icmp6InDestUnreachs", ICMP6_MIB_INDESTUNREACHS),
102 SNMP_MIB_ITEM("Icmp6InPktTooBigs", ICMP6_MIB_INPKTTOOBIGS),
103 SNMP_MIB_ITEM("Icmp6InTimeExcds", ICMP6_MIB_INTIMEEXCDS),
104 SNMP_MIB_ITEM("Icmp6InParmProblems", ICMP6_MIB_INPARMPROBLEMS),
105 SNMP_MIB_ITEM("Icmp6InEchos", ICMP6_MIB_INECHOS),
106 SNMP_MIB_ITEM("Icmp6InEchoReplies", ICMP6_MIB_INECHOREPLIES),
107 SNMP_MIB_ITEM("Icmp6InGroupMembQueries", ICMP6_MIB_INGROUPMEMBQUERIES),
108 SNMP_MIB_ITEM("Icmp6InGroupMembResponses", ICMP6_MIB_INGROUPMEMBRESPONSES),
109 SNMP_MIB_ITEM("Icmp6InGroupMembReductions", ICMP6_MIB_INGROUPMEMBREDUCTIONS),
110 SNMP_MIB_ITEM("Icmp6InRouterSolicits", ICMP6_MIB_INROUTERSOLICITS),
111 SNMP_MIB_ITEM("Icmp6InRouterAdvertisements", ICMP6_MIB_INROUTERADVERTISEMENTS),
112 SNMP_MIB_ITEM("Icmp6InNeighborSolicits", ICMP6_MIB_INNEIGHBORSOLICITS),
113 SNMP_MIB_ITEM("Icmp6InNeighborAdvertisements", ICMP6_MIB_INNEIGHBORADVERTISEMENTS),
114 SNMP_MIB_ITEM("Icmp6InRedirects", ICMP6_MIB_INREDIRECTS),
115 SNMP_MIB_ITEM("Icmp6OutMsgs", ICMP6_MIB_OUTMSGS),
116 SNMP_MIB_ITEM("Icmp6OutDestUnreachs", ICMP6_MIB_OUTDESTUNREACHS),
117 SNMP_MIB_ITEM("Icmp6OutPktTooBigs", ICMP6_MIB_OUTPKTTOOBIGS),
118 SNMP_MIB_ITEM("Icmp6OutTimeExcds", ICMP6_MIB_OUTTIMEEXCDS),
119 SNMP_MIB_ITEM("Icmp6OutParmProblems", ICMP6_MIB_OUTPARMPROBLEMS),
120 SNMP_MIB_ITEM("Icmp6OutEchoReplies", ICMP6_MIB_OUTECHOREPLIES),
121 SNMP_MIB_ITEM("Icmp6OutRouterSolicits", ICMP6_MIB_OUTROUTERSOLICITS),
122 SNMP_MIB_ITEM("Icmp6OutNeighborSolicits", ICMP6_MIB_OUTNEIGHBORSOLICITS),
123 SNMP_MIB_ITEM("Icmp6OutNeighborAdvertisements", ICMP6_MIB_OUTNEIGHBORADVERTISEMENTS),
124 SNMP_MIB_ITEM("Icmp6OutRedirects", ICMP6_MIB_OUTREDIRECTS),
125 SNMP_MIB_ITEM("Icmp6OutGroupMembResponses", ICMP6_MIB_OUTGROUPMEMBRESPONSES),
126 SNMP_MIB_ITEM("Icmp6OutGroupMembReductions", ICMP6_MIB_OUTGROUPMEMBREDUCTIONS),
127 SNMP_MIB_SENTINEL
128};
129
130static struct snmp_mib snmp6_udp6_list[] = {
131 SNMP_MIB_ITEM("Udp6InDatagrams", UDP_MIB_INDATAGRAMS),
132 SNMP_MIB_ITEM("Udp6NoPorts", UDP_MIB_NOPORTS),
133 SNMP_MIB_ITEM("Udp6InErrors", UDP_MIB_INERRORS),
134 SNMP_MIB_ITEM("Udp6OutDatagrams", UDP_MIB_OUTDATAGRAMS),
135 SNMP_MIB_SENTINEL
136};
137
ba4e58ec
GR
138static struct snmp_mib snmp6_udplite6_list[] = {
139 SNMP_MIB_ITEM("UdpLite6InDatagrams", UDP_MIB_INDATAGRAMS),
140 SNMP_MIB_ITEM("UdpLite6NoPorts", UDP_MIB_NOPORTS),
141 SNMP_MIB_ITEM("UdpLite6InErrors", UDP_MIB_INERRORS),
142 SNMP_MIB_ITEM("UdpLite6OutDatagrams", UDP_MIB_OUTDATAGRAMS),
143 SNMP_MIB_SENTINEL
144};
145
1da177e4
LT
146static inline void
147snmp6_seq_show_item(struct seq_file *seq, void **mib, struct snmp_mib *itemlist)
148{
149 int i;
150 for (i=0; itemlist[i].name; i++)
1ab1457c 151 seq_printf(seq, "%-32s\t%lu\n", itemlist[i].name,
7f7d9a6b 152 snmp_fold_field(mib, itemlist[i].entry));
1da177e4
LT
153}
154
155static int snmp6_seq_show(struct seq_file *seq, void *v)
156{
157 struct inet6_dev *idev = (struct inet6_dev *)seq->private;
158
159 if (idev) {
160 seq_printf(seq, "%-32s\t%u\n", "ifIndex", idev->dev->ifindex);
a11d206d 161 snmp6_seq_show_item(seq, (void **)idev->stats.ipv6, snmp6_ipstats_list);
1da177e4
LT
162 snmp6_seq_show_item(seq, (void **)idev->stats.icmpv6, snmp6_icmp6_list);
163 } else {
164 snmp6_seq_show_item(seq, (void **)ipv6_statistics, snmp6_ipstats_list);
165 snmp6_seq_show_item(seq, (void **)icmpv6_statistics, snmp6_icmp6_list);
166 snmp6_seq_show_item(seq, (void **)udp_stats_in6, snmp6_udp6_list);
ba4e58ec 167 snmp6_seq_show_item(seq, (void **)udplite_stats_in6, snmp6_udplite6_list);
1da177e4
LT
168 }
169 return 0;
170}
171
172static int sockstat6_seq_open(struct inode *inode, struct file *file)
173{
174 return single_open(file, sockstat6_seq_show, NULL);
175}
176
9a32144e 177static const struct file_operations sockstat6_seq_fops = {
1da177e4
LT
178 .owner = THIS_MODULE,
179 .open = sockstat6_seq_open,
180 .read = seq_read,
181 .llseek = seq_lseek,
182 .release = single_release,
183};
184
185static int snmp6_seq_open(struct inode *inode, struct file *file)
186{
187 return single_open(file, snmp6_seq_show, PDE(inode)->data);
188}
189
9a32144e 190static const struct file_operations snmp6_seq_fops = {
1da177e4
LT
191 .owner = THIS_MODULE,
192 .open = snmp6_seq_open,
193 .read = seq_read,
194 .llseek = seq_lseek,
195 .release = single_release,
196};
197
198int snmp6_register_dev(struct inet6_dev *idev)
199{
200 struct proc_dir_entry *p;
201
202 if (!idev || !idev->dev)
203 return -EINVAL;
204
205 if (!proc_net_devsnmp6)
206 return -ENOENT;
207
208 p = create_proc_entry(idev->dev->name, S_IRUGO, proc_net_devsnmp6);
209 if (!p)
210 return -ENOMEM;
211
212 p->data = idev;
213 p->proc_fops = &snmp6_seq_fops;
214
215 idev->stats.proc_dir_entry = p;
216 return 0;
217}
218
219int snmp6_unregister_dev(struct inet6_dev *idev)
220{
221 if (!proc_net_devsnmp6)
222 return -ENOENT;
223 if (!idev || !idev->stats.proc_dir_entry)
224 return -EINVAL;
225 remove_proc_entry(idev->stats.proc_dir_entry->name,
226 proc_net_devsnmp6);
5632c515 227 idev->stats.proc_dir_entry = NULL;
1da177e4
LT
228 return 0;
229}
230
231int __init ipv6_misc_proc_init(void)
232{
233 int rc = 0;
234
457c4cbc 235 if (!proc_net_fops_create(&init_net, "snmp6", S_IRUGO, &snmp6_seq_fops))
1da177e4
LT
236 goto proc_snmp6_fail;
237
457c4cbc 238 proc_net_devsnmp6 = proc_mkdir("dev_snmp6", init_net.proc_net);
1da177e4
LT
239 if (!proc_net_devsnmp6)
240 goto proc_dev_snmp6_fail;
241
457c4cbc 242 if (!proc_net_fops_create(&init_net, "sockstat6", S_IRUGO, &sockstat6_seq_fops))
1da177e4
LT
243 goto proc_sockstat6_fail;
244out:
245 return rc;
246
247proc_sockstat6_fail:
457c4cbc 248 proc_net_remove(&init_net, "dev_snmp6");
1da177e4 249proc_dev_snmp6_fail:
457c4cbc 250 proc_net_remove(&init_net, "snmp6");
1da177e4
LT
251proc_snmp6_fail:
252 rc = -ENOMEM;
253 goto out;
254}
255
256void ipv6_misc_proc_exit(void)
257{
457c4cbc
EB
258 proc_net_remove(&init_net, "sockstat6");
259 proc_net_remove(&init_net, "dev_snmp6");
260 proc_net_remove(&init_net, "snmp6");
1da177e4
LT
261}
262