aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/phonet/pn_dev.c2
-rw-r--r--net/phonet/socket.c96
2 files changed, 98 insertions, 0 deletions
diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c
index d0a429459370..947038ddd04c 100644
--- a/net/phonet/pn_dev.c
+++ b/net/phonet/pn_dev.c
@@ -373,6 +373,7 @@ int __init phonet_device_init(void)
373 if (err) 373 if (err)
374 return err; 374 return err;
375 375
376 proc_net_fops_create(&init_net, "pnresource", 0, &pn_res_seq_fops);
376 register_netdevice_notifier(&phonet_device_notifier); 377 register_netdevice_notifier(&phonet_device_notifier);
377 err = phonet_netlink_register(); 378 err = phonet_netlink_register();
378 if (err) 379 if (err)
@@ -385,6 +386,7 @@ void phonet_device_exit(void)
385 rtnl_unregister_all(PF_PHONET); 386 rtnl_unregister_all(PF_PHONET);
386 unregister_netdevice_notifier(&phonet_device_notifier); 387 unregister_netdevice_notifier(&phonet_device_notifier);
387 unregister_pernet_device(&phonet_net_ops); 388 unregister_pernet_device(&phonet_net_ops);
389 proc_net_remove(&init_net, "pnresource");
388} 390}
389 391
390int phonet_route_add(struct net_device *dev, u8 daddr) 392int phonet_route_add(struct net_device *dev, u8 daddr)
diff --git a/net/phonet/socket.c b/net/phonet/socket.c
index d4f41afc0583..6bf6e3c97d5c 100644
--- a/net/phonet/socket.c
+++ b/net/phonet/socket.c
@@ -654,3 +654,99 @@ void pn_sock_unbind_all_res(struct sock *sk)
654 match--; 654 match--;
655 } 655 }
656} 656}
657
658#ifdef CONFIG_PROC_FS
659static struct sock **pn_res_get_idx(struct seq_file *seq, loff_t pos)
660{
661 struct net *net = seq_file_net(seq);
662 unsigned i;
663
664 if (!net_eq(net, &init_net))
665 return NULL;
666
667 for (i = 0; i < 256; i++) {
668 if (pnres.sk[i] == NULL)
669 continue;
670 if (!pos)
671 return pnres.sk + i;
672 pos--;
673 }
674 return NULL;
675}
676
677static struct sock **pn_res_get_next(struct seq_file *seq, struct sock **sk)
678{
679 struct net *net = seq_file_net(seq);
680 unsigned i;
681
682 BUG_ON(!net_eq(net, &init_net));
683
684 for (i = (sk - pnres.sk) + 1; i < 256; i++)
685 if (pnres.sk[i])
686 return pnres.sk + i;
687 return NULL;
688}
689
690static void *pn_res_seq_start(struct seq_file *seq, loff_t *pos)
691 __acquires(resource_mutex)
692{
693 mutex_lock(&resource_mutex);
694 return *pos ? pn_res_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
695}
696
697static void *pn_res_seq_next(struct seq_file *seq, void *v, loff_t *pos)
698{
699 struct sock **sk;
700
701 if (v == SEQ_START_TOKEN)
702 sk = pn_res_get_idx(seq, 0);
703 else
704 sk = pn_res_get_next(seq, v);
705 (*pos)++;
706 return sk;
707}
708
709static void pn_res_seq_stop(struct seq_file *seq, void *v)
710 __releases(resource_mutex)
711{
712 mutex_unlock(&resource_mutex);
713}
714
715static int pn_res_seq_show(struct seq_file *seq, void *v)
716{
717 int len;
718
719 if (v == SEQ_START_TOKEN)
720 seq_printf(seq, "%s%n", "rs uid inode", &len);
721 else {
722 struct sock **psk = v;
723 struct sock *sk = *psk;
724
725 seq_printf(seq, "%02X %5d %lu%n",
726 psk - pnres.sk, sock_i_uid(sk), sock_i_ino(sk), &len);
727 }
728 seq_printf(seq, "%*s\n", 63 - len, "");
729 return 0;
730}
731
732static const struct seq_operations pn_res_seq_ops = {
733 .start = pn_res_seq_start,
734 .next = pn_res_seq_next,
735 .stop = pn_res_seq_stop,
736 .show = pn_res_seq_show,
737};
738
739static int pn_res_open(struct inode *inode, struct file *file)
740{
741 return seq_open_net(inode, file, &pn_res_seq_ops,
742 sizeof(struct seq_net_private));
743}
744
745const struct file_operations pn_res_seq_fops = {
746 .owner = THIS_MODULE,
747 .open = pn_res_open,
748 .read = seq_read,
749 .llseek = seq_lseek,
750 .release = seq_release_net,
751};
752#endif