aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRémi Denis-Courmont <remi.denis-courmont@nokia.com>2010-09-15 08:30:14 -0400
committerDavid S. Miller <davem@davemloft.net>2010-09-16 00:31:33 -0400
commit507215f8d04f9e61f38c975e61d93bcafd30815f (patch)
tree79a88610eaf8abcc3f160ca0ced0a1b4e72dfd80
parentb6a563b2af4ec5b0363cf89869ba234c0e2cd3da (diff)
Phonet: list subscribed resources via proc_fs
Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/phonet/pn_dev.h1
-rw-r--r--net/phonet/pn_dev.c2
-rw-r--r--net/phonet/socket.c96
3 files changed, 99 insertions, 0 deletions
diff --git a/include/net/phonet/pn_dev.h b/include/net/phonet/pn_dev.h
index 2d16783d5e20..13649eb57413 100644
--- a/include/net/phonet/pn_dev.h
+++ b/include/net/phonet/pn_dev.h
@@ -57,5 +57,6 @@ struct net_device *phonet_route_output(struct net *net, u8 daddr);
57#define PN_NO_ADDR 0xff 57#define PN_NO_ADDR 0xff
58 58
59extern const struct file_operations pn_sock_seq_fops; 59extern const struct file_operations pn_sock_seq_fops;
60extern const struct file_operations pn_res_seq_fops;
60 61
61#endif 62#endif
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