aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/proc.c')
-rw-r--r--net/ipv6/proc.c73
1 files changed, 61 insertions, 12 deletions
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index 199ef379e501..ca8b82f96fe5 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -35,16 +35,18 @@ static struct proc_dir_entry *proc_net_devsnmp6;
35 35
36static int sockstat6_seq_show(struct seq_file *seq, void *v) 36static int sockstat6_seq_show(struct seq_file *seq, void *v)
37{ 37{
38 struct net *net = seq->private;
39
38 seq_printf(seq, "TCP6: inuse %d\n", 40 seq_printf(seq, "TCP6: inuse %d\n",
39 sock_prot_inuse_get(&tcpv6_prot)); 41 sock_prot_inuse_get(net, &tcpv6_prot));
40 seq_printf(seq, "UDP6: inuse %d\n", 42 seq_printf(seq, "UDP6: inuse %d\n",
41 sock_prot_inuse_get(&udpv6_prot)); 43 sock_prot_inuse_get(net, &udpv6_prot));
42 seq_printf(seq, "UDPLITE6: inuse %d\n", 44 seq_printf(seq, "UDPLITE6: inuse %d\n",
43 sock_prot_inuse_get(&udplitev6_prot)); 45 sock_prot_inuse_get(net, &udplitev6_prot));
44 seq_printf(seq, "RAW6: inuse %d\n", 46 seq_printf(seq, "RAW6: inuse %d\n",
45 sock_prot_inuse_get(&rawv6_prot)); 47 sock_prot_inuse_get(net, &rawv6_prot));
46 seq_printf(seq, "FRAG6: inuse %d memory %d\n", 48 seq_printf(seq, "FRAG6: inuse %d memory %d\n",
47 ip6_frag_nqueues(&init_net), ip6_frag_mem(&init_net)); 49 ip6_frag_nqueues(net), ip6_frag_mem(net));
48 return 0; 50 return 0;
49} 51}
50 52
@@ -183,7 +185,32 @@ static int snmp6_seq_show(struct seq_file *seq, void *v)
183 185
184static int sockstat6_seq_open(struct inode *inode, struct file *file) 186static int sockstat6_seq_open(struct inode *inode, struct file *file)
185{ 187{
186 return single_open(file, sockstat6_seq_show, NULL); 188 int err;
189 struct net *net;
190
191 err = -ENXIO;
192 net = get_proc_net(inode);
193 if (net == NULL)
194 goto err_net;
195
196 err = single_open(file, sockstat6_seq_show, net);
197 if (err < 0)
198 goto err_open;
199
200 return 0;
201
202err_open:
203 put_net(net);
204err_net:
205 return err;
206}
207
208static int sockstat6_seq_release(struct inode *inode, struct file *file)
209{
210 struct net *net = ((struct seq_file *)file->private_data)->private;
211
212 put_net(net);
213 return single_release(inode, file);
187} 214}
188 215
189static const struct file_operations sockstat6_seq_fops = { 216static const struct file_operations sockstat6_seq_fops = {
@@ -191,7 +218,7 @@ static const struct file_operations sockstat6_seq_fops = {
191 .open = sockstat6_seq_open, 218 .open = sockstat6_seq_open,
192 .read = seq_read, 219 .read = seq_read,
193 .llseek = seq_lseek, 220 .llseek = seq_lseek,
194 .release = single_release, 221 .release = sockstat6_seq_release,
195}; 222};
196 223
197static int snmp6_seq_open(struct inode *inode, struct file *file) 224static int snmp6_seq_open(struct inode *inode, struct file *file)
@@ -214,6 +241,9 @@ int snmp6_register_dev(struct inet6_dev *idev)
214 if (!idev || !idev->dev) 241 if (!idev || !idev->dev)
215 return -EINVAL; 242 return -EINVAL;
216 243
244 if (dev_net(idev->dev) != &init_net)
245 return 0;
246
217 if (!proc_net_devsnmp6) 247 if (!proc_net_devsnmp6)
218 return -ENOENT; 248 return -ENOENT;
219 249
@@ -240,27 +270,45 @@ int snmp6_unregister_dev(struct inet6_dev *idev)
240 return 0; 270 return 0;
241} 271}
242 272
273static int ipv6_proc_init_net(struct net *net)
274{
275 if (!proc_net_fops_create(net, "sockstat6", S_IRUGO,
276 &sockstat6_seq_fops))
277 return -ENOMEM;
278 return 0;
279}
280
281static void ipv6_proc_exit_net(struct net *net)
282{
283 proc_net_remove(net, "sockstat6");
284}
285
286static struct pernet_operations ipv6_proc_ops = {
287 .init = ipv6_proc_init_net,
288 .exit = ipv6_proc_exit_net,
289};
290
243int __init ipv6_misc_proc_init(void) 291int __init ipv6_misc_proc_init(void)
244{ 292{
245 int rc = 0; 293 int rc = 0;
246 294
295 if (register_pernet_subsys(&ipv6_proc_ops))
296 goto proc_net_fail;
297
247 if (!proc_net_fops_create(&init_net, "snmp6", S_IRUGO, &snmp6_seq_fops)) 298 if (!proc_net_fops_create(&init_net, "snmp6", S_IRUGO, &snmp6_seq_fops))
248 goto proc_snmp6_fail; 299 goto proc_snmp6_fail;
249 300
250 proc_net_devsnmp6 = proc_mkdir("dev_snmp6", init_net.proc_net); 301 proc_net_devsnmp6 = proc_mkdir("dev_snmp6", init_net.proc_net);
251 if (!proc_net_devsnmp6) 302 if (!proc_net_devsnmp6)
252 goto proc_dev_snmp6_fail; 303 goto proc_dev_snmp6_fail;
253
254 if (!proc_net_fops_create(&init_net, "sockstat6", S_IRUGO, &sockstat6_seq_fops))
255 goto proc_sockstat6_fail;
256out: 304out:
257 return rc; 305 return rc;
258 306
259proc_sockstat6_fail:
260 proc_net_remove(&init_net, "dev_snmp6");
261proc_dev_snmp6_fail: 307proc_dev_snmp6_fail:
262 proc_net_remove(&init_net, "snmp6"); 308 proc_net_remove(&init_net, "snmp6");
263proc_snmp6_fail: 309proc_snmp6_fail:
310 unregister_pernet_subsys(&ipv6_proc_ops);
311proc_net_fail:
264 rc = -ENOMEM; 312 rc = -ENOMEM;
265 goto out; 313 goto out;
266} 314}
@@ -270,5 +318,6 @@ void ipv6_misc_proc_exit(void)
270 proc_net_remove(&init_net, "sockstat6"); 318 proc_net_remove(&init_net, "sockstat6");
271 proc_net_remove(&init_net, "dev_snmp6"); 319 proc_net_remove(&init_net, "dev_snmp6");
272 proc_net_remove(&init_net, "snmp6"); 320 proc_net_remove(&init_net, "snmp6");
321 unregister_pernet_subsys(&ipv6_proc_ops);
273} 322}
274 323