[NET]: Add a network namespace parameter to struct sock
[GitHub/mt8127/android_kernel_alcatel_ttab.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>
7f7d9a6b 26#include <net/ip.h>
1da177e4
LT
27#include <net/sock.h>
28#include <net/tcp.h>
29#include <net/transp_v6.h>
30#include <net/ipv6.h>
31
1da177e4
LT
32static struct proc_dir_entry *proc_net_devsnmp6;
33
34static int fold_prot_inuse(struct proto *proto)
35{
36 int res = 0;
37 int cpu;
38
6f912042 39 for_each_possible_cpu(cpu)
1da177e4
LT
40 res += proto->stats[cpu].inuse;
41
42 return res;
43}
44
45static int sockstat6_seq_show(struct seq_file *seq, void *v)
46{
47 seq_printf(seq, "TCP6: inuse %d\n",
48 fold_prot_inuse(&tcpv6_prot));
49 seq_printf(seq, "UDP6: inuse %d\n",
50 fold_prot_inuse(&udpv6_prot));
ba4e58ec 51 seq_printf(seq, "UDPLITE6: inuse %d\n",
1ab1457c 52 fold_prot_inuse(&udplitev6_prot));
1da177e4
LT
53 seq_printf(seq, "RAW6: inuse %d\n",
54 fold_prot_inuse(&rawv6_prot));
55 seq_printf(seq, "FRAG6: inuse %d memory %d\n",
56 ip6_frag_nqueues, atomic_read(&ip6_frag_mem));
57 return 0;
58}
59
60static struct snmp_mib snmp6_ipstats_list[] = {
61/* ipv6 mib according to RFC 2465 */
62 SNMP_MIB_ITEM("Ip6InReceives", IPSTATS_MIB_INRECEIVES),
63 SNMP_MIB_ITEM("Ip6InHdrErrors", IPSTATS_MIB_INHDRERRORS),
64 SNMP_MIB_ITEM("Ip6InTooBigErrors", IPSTATS_MIB_INTOOBIGERRORS),
65 SNMP_MIB_ITEM("Ip6InNoRoutes", IPSTATS_MIB_INNOROUTES),
66 SNMP_MIB_ITEM("Ip6InAddrErrors", IPSTATS_MIB_INADDRERRORS),
67 SNMP_MIB_ITEM("Ip6InUnknownProtos", IPSTATS_MIB_INUNKNOWNPROTOS),
68 SNMP_MIB_ITEM("Ip6InTruncatedPkts", IPSTATS_MIB_INTRUNCATEDPKTS),
69 SNMP_MIB_ITEM("Ip6InDiscards", IPSTATS_MIB_INDISCARDS),
70 SNMP_MIB_ITEM("Ip6InDelivers", IPSTATS_MIB_INDELIVERS),
71 SNMP_MIB_ITEM("Ip6OutForwDatagrams", IPSTATS_MIB_OUTFORWDATAGRAMS),
72 SNMP_MIB_ITEM("Ip6OutRequests", IPSTATS_MIB_OUTREQUESTS),
73 SNMP_MIB_ITEM("Ip6OutDiscards", IPSTATS_MIB_OUTDISCARDS),
74 SNMP_MIB_ITEM("Ip6OutNoRoutes", IPSTATS_MIB_OUTNOROUTES),
75 SNMP_MIB_ITEM("Ip6ReasmTimeout", IPSTATS_MIB_REASMTIMEOUT),
76 SNMP_MIB_ITEM("Ip6ReasmReqds", IPSTATS_MIB_REASMREQDS),
77 SNMP_MIB_ITEM("Ip6ReasmOKs", IPSTATS_MIB_REASMOKS),
78 SNMP_MIB_ITEM("Ip6ReasmFails", IPSTATS_MIB_REASMFAILS),
79 SNMP_MIB_ITEM("Ip6FragOKs", IPSTATS_MIB_FRAGOKS),
80 SNMP_MIB_ITEM("Ip6FragFails", IPSTATS_MIB_FRAGFAILS),
81 SNMP_MIB_ITEM("Ip6FragCreates", IPSTATS_MIB_FRAGCREATES),
82 SNMP_MIB_ITEM("Ip6InMcastPkts", IPSTATS_MIB_INMCASTPKTS),
83 SNMP_MIB_ITEM("Ip6OutMcastPkts", IPSTATS_MIB_OUTMCASTPKTS),
84 SNMP_MIB_SENTINEL
85};
86
87static struct snmp_mib snmp6_icmp6_list[] = {
88/* icmpv6 mib according to RFC 2466
89
90 Exceptions: {In|Out}AdminProhibs are removed, because I see
1ab1457c 91 no good reasons to account them separately
1da177e4
LT
92 of another dest.unreachs.
93 OutErrs is zero identically.
94 OutEchos too.
95 OutRouterAdvertisements too.
96 OutGroupMembQueries too.
97 */
98 SNMP_MIB_ITEM("Icmp6InMsgs", ICMP6_MIB_INMSGS),
99 SNMP_MIB_ITEM("Icmp6InErrors", ICMP6_MIB_INERRORS),
100 SNMP_MIB_ITEM("Icmp6InDestUnreachs", ICMP6_MIB_INDESTUNREACHS),
101 SNMP_MIB_ITEM("Icmp6InPktTooBigs", ICMP6_MIB_INPKTTOOBIGS),
102 SNMP_MIB_ITEM("Icmp6InTimeExcds", ICMP6_MIB_INTIMEEXCDS),
103 SNMP_MIB_ITEM("Icmp6InParmProblems", ICMP6_MIB_INPARMPROBLEMS),
104 SNMP_MIB_ITEM("Icmp6InEchos", ICMP6_MIB_INECHOS),
105 SNMP_MIB_ITEM("Icmp6InEchoReplies", ICMP6_MIB_INECHOREPLIES),
106 SNMP_MIB_ITEM("Icmp6InGroupMembQueries", ICMP6_MIB_INGROUPMEMBQUERIES),
107 SNMP_MIB_ITEM("Icmp6InGroupMembResponses", ICMP6_MIB_INGROUPMEMBRESPONSES),
108 SNMP_MIB_ITEM("Icmp6InGroupMembReductions", ICMP6_MIB_INGROUPMEMBREDUCTIONS),
109 SNMP_MIB_ITEM("Icmp6InRouterSolicits", ICMP6_MIB_INROUTERSOLICITS),
110 SNMP_MIB_ITEM("Icmp6InRouterAdvertisements", ICMP6_MIB_INROUTERADVERTISEMENTS),
111 SNMP_MIB_ITEM("Icmp6InNeighborSolicits", ICMP6_MIB_INNEIGHBORSOLICITS),
112 SNMP_MIB_ITEM("Icmp6InNeighborAdvertisements", ICMP6_MIB_INNEIGHBORADVERTISEMENTS),
113 SNMP_MIB_ITEM("Icmp6InRedirects", ICMP6_MIB_INREDIRECTS),
114 SNMP_MIB_ITEM("Icmp6OutMsgs", ICMP6_MIB_OUTMSGS),
115 SNMP_MIB_ITEM("Icmp6OutDestUnreachs", ICMP6_MIB_OUTDESTUNREACHS),
116 SNMP_MIB_ITEM("Icmp6OutPktTooBigs", ICMP6_MIB_OUTPKTTOOBIGS),
117 SNMP_MIB_ITEM("Icmp6OutTimeExcds", ICMP6_MIB_OUTTIMEEXCDS),
118 SNMP_MIB_ITEM("Icmp6OutParmProblems", ICMP6_MIB_OUTPARMPROBLEMS),
119 SNMP_MIB_ITEM("Icmp6OutEchoReplies", ICMP6_MIB_OUTECHOREPLIES),
120 SNMP_MIB_ITEM("Icmp6OutRouterSolicits", ICMP6_MIB_OUTROUTERSOLICITS),
121 SNMP_MIB_ITEM("Icmp6OutNeighborSolicits", ICMP6_MIB_OUTNEIGHBORSOLICITS),
122 SNMP_MIB_ITEM("Icmp6OutNeighborAdvertisements", ICMP6_MIB_OUTNEIGHBORADVERTISEMENTS),
123 SNMP_MIB_ITEM("Icmp6OutRedirects", ICMP6_MIB_OUTREDIRECTS),
124 SNMP_MIB_ITEM("Icmp6OutGroupMembResponses", ICMP6_MIB_OUTGROUPMEMBRESPONSES),
125 SNMP_MIB_ITEM("Icmp6OutGroupMembReductions", ICMP6_MIB_OUTGROUPMEMBREDUCTIONS),
126 SNMP_MIB_SENTINEL
127};
128
129static struct snmp_mib snmp6_udp6_list[] = {
130 SNMP_MIB_ITEM("Udp6InDatagrams", UDP_MIB_INDATAGRAMS),
131 SNMP_MIB_ITEM("Udp6NoPorts", UDP_MIB_NOPORTS),
132 SNMP_MIB_ITEM("Udp6InErrors", UDP_MIB_INERRORS),
133 SNMP_MIB_ITEM("Udp6OutDatagrams", UDP_MIB_OUTDATAGRAMS),
134 SNMP_MIB_SENTINEL
135};
136
ba4e58ec
GR
137static struct snmp_mib snmp6_udplite6_list[] = {
138 SNMP_MIB_ITEM("UdpLite6InDatagrams", UDP_MIB_INDATAGRAMS),
139 SNMP_MIB_ITEM("UdpLite6NoPorts", UDP_MIB_NOPORTS),
140 SNMP_MIB_ITEM("UdpLite6InErrors", UDP_MIB_INERRORS),
141 SNMP_MIB_ITEM("UdpLite6OutDatagrams", UDP_MIB_OUTDATAGRAMS),
142 SNMP_MIB_SENTINEL
143};
144
1da177e4
LT
145static inline void
146snmp6_seq_show_item(struct seq_file *seq, void **mib, struct snmp_mib *itemlist)
147{
148 int i;
149 for (i=0; itemlist[i].name; i++)
1ab1457c 150 seq_printf(seq, "%-32s\t%lu\n", itemlist[i].name,
7f7d9a6b 151 snmp_fold_field(mib, itemlist[i].entry));
1da177e4
LT
152}
153
154static int snmp6_seq_show(struct seq_file *seq, void *v)
155{
156 struct inet6_dev *idev = (struct inet6_dev *)seq->private;
157
158 if (idev) {
159 seq_printf(seq, "%-32s\t%u\n", "ifIndex", idev->dev->ifindex);
a11d206d 160 snmp6_seq_show_item(seq, (void **)idev->stats.ipv6, snmp6_ipstats_list);
1da177e4
LT
161 snmp6_seq_show_item(seq, (void **)idev->stats.icmpv6, snmp6_icmp6_list);
162 } else {
163 snmp6_seq_show_item(seq, (void **)ipv6_statistics, snmp6_ipstats_list);
164 snmp6_seq_show_item(seq, (void **)icmpv6_statistics, snmp6_icmp6_list);
165 snmp6_seq_show_item(seq, (void **)udp_stats_in6, snmp6_udp6_list);
ba4e58ec 166 snmp6_seq_show_item(seq, (void **)udplite_stats_in6, snmp6_udplite6_list);
1da177e4
LT
167 }
168 return 0;
169}
170
171static int sockstat6_seq_open(struct inode *inode, struct file *file)
172{
173 return single_open(file, sockstat6_seq_show, NULL);
174}
175
9a32144e 176static const struct file_operations sockstat6_seq_fops = {
1da177e4
LT
177 .owner = THIS_MODULE,
178 .open = sockstat6_seq_open,
179 .read = seq_read,
180 .llseek = seq_lseek,
181 .release = single_release,
182};
183
184static int snmp6_seq_open(struct inode *inode, struct file *file)
185{
186 return single_open(file, snmp6_seq_show, PDE(inode)->data);
187}
188
9a32144e 189static const struct file_operations snmp6_seq_fops = {
1da177e4
LT
190 .owner = THIS_MODULE,
191 .open = snmp6_seq_open,
192 .read = seq_read,
193 .llseek = seq_lseek,
194 .release = single_release,
195};
196
197int snmp6_register_dev(struct inet6_dev *idev)
198{
199 struct proc_dir_entry *p;
200
201 if (!idev || !idev->dev)
202 return -EINVAL;
203
204 if (!proc_net_devsnmp6)
205 return -ENOENT;
206
207 p = create_proc_entry(idev->dev->name, S_IRUGO, proc_net_devsnmp6);
208 if (!p)
209 return -ENOMEM;
210
211 p->data = idev;
212 p->proc_fops = &snmp6_seq_fops;
213
214 idev->stats.proc_dir_entry = p;
215 return 0;
216}
217
218int snmp6_unregister_dev(struct inet6_dev *idev)
219{
220 if (!proc_net_devsnmp6)
221 return -ENOENT;
222 if (!idev || !idev->stats.proc_dir_entry)
223 return -EINVAL;
224 remove_proc_entry(idev->stats.proc_dir_entry->name,
225 proc_net_devsnmp6);
5632c515 226 idev->stats.proc_dir_entry = NULL;
1da177e4
LT
227 return 0;
228}
229
230int __init ipv6_misc_proc_init(void)
231{
232 int rc = 0;
233
234 if (!proc_net_fops_create("snmp6", S_IRUGO, &snmp6_seq_fops))
235 goto proc_snmp6_fail;
236
237 proc_net_devsnmp6 = proc_mkdir("dev_snmp6", proc_net);
238 if (!proc_net_devsnmp6)
239 goto proc_dev_snmp6_fail;
240
241 if (!proc_net_fops_create("sockstat6", S_IRUGO, &sockstat6_seq_fops))
242 goto proc_sockstat6_fail;
243out:
244 return rc;
245
246proc_sockstat6_fail:
247 proc_net_remove("dev_snmp6");
248proc_dev_snmp6_fail:
249 proc_net_remove("snmp6");
250proc_snmp6_fail:
251 rc = -ENOMEM;
252 goto out;
253}
254
255void ipv6_misc_proc_exit(void)
256{
257 proc_net_remove("sockstat6");
258 proc_net_remove("dev_snmp6");
259 proc_net_remove("snmp6");
260}
261