* [Patch net-next] ipv6: separate out procfs code from mcast.c
@ 2013-04-23 7:07 Cong Wang
2013-04-23 7:11 ` David Miller
0 siblings, 1 reply; 13+ messages in thread
From: Cong Wang @ 2013-04-23 7:07 UTC (permalink / raw)
To: netdev; +Cc: David S. Miller, Hideaki YOSHIFUJI, Cong Wang
From: Cong Wang <amwang@redhat.com>
They well deserve a separated unit.
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
Signed-off-by: Cong Wang <amwang@redhat.com>
---
net/ipv6/Makefile | 2
net/ipv6/mcast.c | 370 -----------------------------------------------
net/ipv6/mcast_proc.c | 386 ++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 387 insertions(+), 371 deletions(-)
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index 309af19..157b5e7 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -19,7 +19,7 @@ ipv6-$(CONFIG_XFRM) += xfrm6_policy.o xfrm6_state.o xfrm6_input.o \
xfrm6_output.o
ipv6-$(CONFIG_NETFILTER) += netfilter.o
ipv6-$(CONFIG_IPV6_MULTIPLE_TABLES) += fib6_rules.o
-ipv6-$(CONFIG_PROC_FS) += proc.o
+ipv6-$(CONFIG_PROC_FS) += proc.o mcast_proc.o
ipv6-$(CONFIG_SYN_COOKIES) += syncookies.o
ipv6-objs += $(ipv6-y)
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index bfa6cc3..821665b 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -26,7 +26,6 @@
* - MLDv2 support
*/
-#include <linux/module.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/string.h>
@@ -41,8 +40,6 @@
#include <linux/if_arp.h>
#include <linux/route.h>
#include <linux/init.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
#include <linux/slab.h>
#include <net/mld.h>
@@ -2307,370 +2304,3 @@ void ipv6_mc_destroy_dev(struct inet6_dev *idev)
write_unlock_bh(&idev->lock);
}
-#ifdef CONFIG_PROC_FS
-struct igmp6_mc_iter_state {
- struct seq_net_private p;
- struct net_device *dev;
- struct inet6_dev *idev;
-};
-
-#define igmp6_mc_seq_private(seq) ((struct igmp6_mc_iter_state *)(seq)->private)
-
-static inline struct ifmcaddr6 *igmp6_mc_get_first(struct seq_file *seq)
-{
- struct ifmcaddr6 *im = NULL;
- struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
- struct net *net = seq_file_net(seq);
-
- state->idev = NULL;
- for_each_netdev_rcu(net, state->dev) {
- struct inet6_dev *idev;
- idev = __in6_dev_get(state->dev);
- if (!idev)
- continue;
- read_lock_bh(&idev->lock);
- im = idev->mc_list;
- if (im) {
- state->idev = idev;
- break;
- }
- read_unlock_bh(&idev->lock);
- }
- return im;
-}
-
-static struct ifmcaddr6 *igmp6_mc_get_next(struct seq_file *seq, struct ifmcaddr6 *im)
-{
- struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
-
- im = im->next;
- while (!im) {
- if (likely(state->idev != NULL))
- read_unlock_bh(&state->idev->lock);
-
- state->dev = next_net_device_rcu(state->dev);
- if (!state->dev) {
- state->idev = NULL;
- break;
- }
- state->idev = __in6_dev_get(state->dev);
- if (!state->idev)
- continue;
- read_lock_bh(&state->idev->lock);
- im = state->idev->mc_list;
- }
- return im;
-}
-
-static struct ifmcaddr6 *igmp6_mc_get_idx(struct seq_file *seq, loff_t pos)
-{
- struct ifmcaddr6 *im = igmp6_mc_get_first(seq);
- if (im)
- while (pos && (im = igmp6_mc_get_next(seq, im)) != NULL)
- --pos;
- return pos ? NULL : im;
-}
-
-static void *igmp6_mc_seq_start(struct seq_file *seq, loff_t *pos)
- __acquires(RCU)
-{
- rcu_read_lock();
- return igmp6_mc_get_idx(seq, *pos);
-}
-
-static void *igmp6_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
-{
- struct ifmcaddr6 *im = igmp6_mc_get_next(seq, v);
-
- ++*pos;
- return im;
-}
-
-static void igmp6_mc_seq_stop(struct seq_file *seq, void *v)
- __releases(RCU)
-{
- struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
-
- if (likely(state->idev != NULL)) {
- read_unlock_bh(&state->idev->lock);
- state->idev = NULL;
- }
- state->dev = NULL;
- rcu_read_unlock();
-}
-
-static int igmp6_mc_seq_show(struct seq_file *seq, void *v)
-{
- struct ifmcaddr6 *im = (struct ifmcaddr6 *)v;
- struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
-
- seq_printf(seq,
- "%-4d %-15s %pi6 %5d %08X %ld\n",
- state->dev->ifindex, state->dev->name,
- &im->mca_addr,
- im->mca_users, im->mca_flags,
- (im->mca_flags&MAF_TIMER_RUNNING) ?
- jiffies_to_clock_t(im->mca_timer.expires-jiffies) : 0);
- return 0;
-}
-
-static const struct seq_operations igmp6_mc_seq_ops = {
- .start = igmp6_mc_seq_start,
- .next = igmp6_mc_seq_next,
- .stop = igmp6_mc_seq_stop,
- .show = igmp6_mc_seq_show,
-};
-
-static int igmp6_mc_seq_open(struct inode *inode, struct file *file)
-{
- return seq_open_net(inode, file, &igmp6_mc_seq_ops,
- sizeof(struct igmp6_mc_iter_state));
-}
-
-static const struct file_operations igmp6_mc_seq_fops = {
- .owner = THIS_MODULE,
- .open = igmp6_mc_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release_net,
-};
-
-struct igmp6_mcf_iter_state {
- struct seq_net_private p;
- struct net_device *dev;
- struct inet6_dev *idev;
- struct ifmcaddr6 *im;
-};
-
-#define igmp6_mcf_seq_private(seq) ((struct igmp6_mcf_iter_state *)(seq)->private)
-
-static inline struct ip6_sf_list *igmp6_mcf_get_first(struct seq_file *seq)
-{
- struct ip6_sf_list *psf = NULL;
- struct ifmcaddr6 *im = NULL;
- struct igmp6_mcf_iter_state *state = igmp6_mcf_seq_private(seq);
- struct net *net = seq_file_net(seq);
-
- state->idev = NULL;
- state->im = NULL;
- for_each_netdev_rcu(net, state->dev) {
- struct inet6_dev *idev;
- idev = __in6_dev_get(state->dev);
- if (unlikely(idev == NULL))
- continue;
- read_lock_bh(&idev->lock);
- im = idev->mc_list;
- if (likely(im != NULL)) {
- spin_lock_bh(&im->mca_lock);
- psf = im->mca_sources;
- if (likely(psf != NULL)) {
- state->im = im;
- state->idev = idev;
- break;
- }
- spin_unlock_bh(&im->mca_lock);
- }
- read_unlock_bh(&idev->lock);
- }
- return psf;
-}
-
-static struct ip6_sf_list *igmp6_mcf_get_next(struct seq_file *seq, struct ip6_sf_list *psf)
-{
- struct igmp6_mcf_iter_state *state = igmp6_mcf_seq_private(seq);
-
- psf = psf->sf_next;
- while (!psf) {
- spin_unlock_bh(&state->im->mca_lock);
- state->im = state->im->next;
- while (!state->im) {
- if (likely(state->idev != NULL))
- read_unlock_bh(&state->idev->lock);
-
- state->dev = next_net_device_rcu(state->dev);
- if (!state->dev) {
- state->idev = NULL;
- goto out;
- }
- state->idev = __in6_dev_get(state->dev);
- if (!state->idev)
- continue;
- read_lock_bh(&state->idev->lock);
- state->im = state->idev->mc_list;
- }
- if (!state->im)
- break;
- spin_lock_bh(&state->im->mca_lock);
- psf = state->im->mca_sources;
- }
-out:
- return psf;
-}
-
-static struct ip6_sf_list *igmp6_mcf_get_idx(struct seq_file *seq, loff_t pos)
-{
- struct ip6_sf_list *psf = igmp6_mcf_get_first(seq);
- if (psf)
- while (pos && (psf = igmp6_mcf_get_next(seq, psf)) != NULL)
- --pos;
- return pos ? NULL : psf;
-}
-
-static void *igmp6_mcf_seq_start(struct seq_file *seq, loff_t *pos)
- __acquires(RCU)
-{
- rcu_read_lock();
- return *pos ? igmp6_mcf_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
-}
-
-static void *igmp6_mcf_seq_next(struct seq_file *seq, void *v, loff_t *pos)
-{
- struct ip6_sf_list *psf;
- if (v == SEQ_START_TOKEN)
- psf = igmp6_mcf_get_first(seq);
- else
- psf = igmp6_mcf_get_next(seq, v);
- ++*pos;
- return psf;
-}
-
-static void igmp6_mcf_seq_stop(struct seq_file *seq, void *v)
- __releases(RCU)
-{
- struct igmp6_mcf_iter_state *state = igmp6_mcf_seq_private(seq);
- if (likely(state->im != NULL)) {
- spin_unlock_bh(&state->im->mca_lock);
- state->im = NULL;
- }
- if (likely(state->idev != NULL)) {
- read_unlock_bh(&state->idev->lock);
- state->idev = NULL;
- }
- state->dev = NULL;
- rcu_read_unlock();
-}
-
-static int igmp6_mcf_seq_show(struct seq_file *seq, void *v)
-{
- struct ip6_sf_list *psf = (struct ip6_sf_list *)v;
- struct igmp6_mcf_iter_state *state = igmp6_mcf_seq_private(seq);
-
- if (v == SEQ_START_TOKEN) {
- seq_printf(seq,
- "%3s %6s "
- "%32s %32s %6s %6s\n", "Idx",
- "Device", "Multicast Address",
- "Source Address", "INC", "EXC");
- } else {
- seq_printf(seq,
- "%3d %6.6s %pi6 %pi6 %6lu %6lu\n",
- state->dev->ifindex, state->dev->name,
- &state->im->mca_addr,
- &psf->sf_addr,
- psf->sf_count[MCAST_INCLUDE],
- psf->sf_count[MCAST_EXCLUDE]);
- }
- return 0;
-}
-
-static const struct seq_operations igmp6_mcf_seq_ops = {
- .start = igmp6_mcf_seq_start,
- .next = igmp6_mcf_seq_next,
- .stop = igmp6_mcf_seq_stop,
- .show = igmp6_mcf_seq_show,
-};
-
-static int igmp6_mcf_seq_open(struct inode *inode, struct file *file)
-{
- return seq_open_net(inode, file, &igmp6_mcf_seq_ops,
- sizeof(struct igmp6_mcf_iter_state));
-}
-
-static const struct file_operations igmp6_mcf_seq_fops = {
- .owner = THIS_MODULE,
- .open = igmp6_mcf_seq_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release_net,
-};
-
-static int __net_init igmp6_proc_init(struct net *net)
-{
- int err;
-
- err = -ENOMEM;
- if (!proc_create("igmp6", S_IRUGO, net->proc_net, &igmp6_mc_seq_fops))
- goto out;
- if (!proc_create("mcfilter6", S_IRUGO, net->proc_net,
- &igmp6_mcf_seq_fops))
- goto out_proc_net_igmp6;
-
- err = 0;
-out:
- return err;
-
-out_proc_net_igmp6:
- remove_proc_entry("igmp6", net->proc_net);
- goto out;
-}
-
-static void __net_exit igmp6_proc_exit(struct net *net)
-{
- remove_proc_entry("mcfilter6", net->proc_net);
- remove_proc_entry("igmp6", net->proc_net);
-}
-#else
-static inline int igmp6_proc_init(struct net *net)
-{
- return 0;
-}
-static inline void igmp6_proc_exit(struct net *net)
-{
-}
-#endif
-
-static int __net_init igmp6_net_init(struct net *net)
-{
- int err;
-
- err = inet_ctl_sock_create(&net->ipv6.igmp_sk, PF_INET6,
- SOCK_RAW, IPPROTO_ICMPV6, net);
- if (err < 0) {
- pr_err("Failed to initialize the IGMP6 control socket (err %d)\n",
- err);
- goto out;
- }
-
- inet6_sk(net->ipv6.igmp_sk)->hop_limit = 1;
-
- err = igmp6_proc_init(net);
- if (err)
- goto out_sock_create;
-out:
- return err;
-
-out_sock_create:
- inet_ctl_sock_destroy(net->ipv6.igmp_sk);
- goto out;
-}
-
-static void __net_exit igmp6_net_exit(struct net *net)
-{
- inet_ctl_sock_destroy(net->ipv6.igmp_sk);
- igmp6_proc_exit(net);
-}
-
-static struct pernet_operations igmp6_net_ops = {
- .init = igmp6_net_init,
- .exit = igmp6_net_exit,
-};
-
-int __init igmp6_init(void)
-{
- return register_pernet_subsys(&igmp6_net_ops);
-}
-
-void igmp6_cleanup(void)
-{
- unregister_pernet_subsys(&igmp6_net_ops);
-}
diff --git a/net/ipv6/mcast_proc.c b/net/ipv6/mcast_proc.c
new file mode 100644
index 0000000..887af797
--- /dev/null
+++ b/net/ipv6/mcast_proc.c
@@ -0,0 +1,386 @@
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/socket.h>
+#include <linux/sockios.h>
+#include <linux/jiffies.h>
+#include <linux/times.h>
+#include <linux/net.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/route.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <net/mld.h>
+
+#include <net/net_namespace.h>
+#include <net/sock.h>
+
+#include <net/ipv6.h>
+#include <net/protocol.h>
+#include <net/if_inet6.h>
+#include <net/addrconf.h>
+#include <net/inet_common.h>
+
+struct igmp6_mc_iter_state {
+ struct seq_net_private p;
+ struct net_device *dev;
+ struct inet6_dev *idev;
+};
+
+#define igmp6_mc_seq_private(seq) ((struct igmp6_mc_iter_state *)(seq)->private)
+
+static inline struct ifmcaddr6 *igmp6_mc_get_first(struct seq_file *seq)
+{
+ struct ifmcaddr6 *im = NULL;
+ struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
+ struct net *net = seq_file_net(seq);
+
+ state->idev = NULL;
+ for_each_netdev_rcu(net, state->dev) {
+ struct inet6_dev *idev;
+ idev = __in6_dev_get(state->dev);
+ if (!idev)
+ continue;
+ read_lock_bh(&idev->lock);
+ im = idev->mc_list;
+ if (im) {
+ state->idev = idev;
+ break;
+ }
+ read_unlock_bh(&idev->lock);
+ }
+ return im;
+}
+
+static struct ifmcaddr6 *igmp6_mc_get_next(struct seq_file *seq, struct ifmcaddr6 *im)
+{
+ struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
+
+ im = im->next;
+ while (!im) {
+ if (likely(state->idev != NULL))
+ read_unlock_bh(&state->idev->lock);
+
+ state->dev = next_net_device_rcu(state->dev);
+ if (!state->dev) {
+ state->idev = NULL;
+ break;
+ }
+ state->idev = __in6_dev_get(state->dev);
+ if (!state->idev)
+ continue;
+ read_lock_bh(&state->idev->lock);
+ im = state->idev->mc_list;
+ }
+ return im;
+}
+
+static struct ifmcaddr6 *igmp6_mc_get_idx(struct seq_file *seq, loff_t pos)
+{
+ struct ifmcaddr6 *im = igmp6_mc_get_first(seq);
+ if (im)
+ while (pos && (im = igmp6_mc_get_next(seq, im)) != NULL)
+ --pos;
+ return pos ? NULL : im;
+}
+
+static void *igmp6_mc_seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(RCU)
+{
+ rcu_read_lock();
+ return igmp6_mc_get_idx(seq, *pos);
+}
+
+static void *igmp6_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct ifmcaddr6 *im = igmp6_mc_get_next(seq, v);
+
+ ++*pos;
+ return im;
+}
+
+static void igmp6_mc_seq_stop(struct seq_file *seq, void *v)
+ __releases(RCU)
+{
+ struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
+
+ if (likely(state->idev != NULL)) {
+ read_unlock_bh(&state->idev->lock);
+ state->idev = NULL;
+ }
+ state->dev = NULL;
+ rcu_read_unlock();
+}
+
+static int igmp6_mc_seq_show(struct seq_file *seq, void *v)
+{
+ struct ifmcaddr6 *im = (struct ifmcaddr6 *)v;
+ struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
+
+ seq_printf(seq,
+ "%-4d %-15s %pi6 %5d %08X %ld\n",
+ state->dev->ifindex, state->dev->name,
+ &im->mca_addr,
+ im->mca_users, im->mca_flags,
+ (im->mca_flags&MAF_TIMER_RUNNING) ?
+ jiffies_to_clock_t(im->mca_timer.expires-jiffies) : 0);
+ return 0;
+}
+
+static const struct seq_operations igmp6_mc_seq_ops = {
+ .start = igmp6_mc_seq_start,
+ .next = igmp6_mc_seq_next,
+ .stop = igmp6_mc_seq_stop,
+ .show = igmp6_mc_seq_show,
+};
+
+static int igmp6_mc_seq_open(struct inode *inode, struct file *file)
+{
+ return seq_open_net(inode, file, &igmp6_mc_seq_ops,
+ sizeof(struct igmp6_mc_iter_state));
+}
+
+static const struct file_operations igmp6_mc_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = igmp6_mc_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release_net,
+};
+
+struct igmp6_mcf_iter_state {
+ struct seq_net_private p;
+ struct net_device *dev;
+ struct inet6_dev *idev;
+ struct ifmcaddr6 *im;
+};
+
+#define igmp6_mcf_seq_private(seq) ((struct igmp6_mcf_iter_state *)(seq)->private)
+
+static inline struct ip6_sf_list *igmp6_mcf_get_first(struct seq_file *seq)
+{
+ struct ip6_sf_list *psf = NULL;
+ struct ifmcaddr6 *im = NULL;
+ struct igmp6_mcf_iter_state *state = igmp6_mcf_seq_private(seq);
+ struct net *net = seq_file_net(seq);
+
+ state->idev = NULL;
+ state->im = NULL;
+ for_each_netdev_rcu(net, state->dev) {
+ struct inet6_dev *idev;
+ idev = __in6_dev_get(state->dev);
+ if (unlikely(idev == NULL))
+ continue;
+ read_lock_bh(&idev->lock);
+ im = idev->mc_list;
+ if (likely(im != NULL)) {
+ spin_lock_bh(&im->mca_lock);
+ psf = im->mca_sources;
+ if (likely(psf != NULL)) {
+ state->im = im;
+ state->idev = idev;
+ break;
+ }
+ spin_unlock_bh(&im->mca_lock);
+ }
+ read_unlock_bh(&idev->lock);
+ }
+ return psf;
+}
+
+static struct ip6_sf_list *igmp6_mcf_get_next(struct seq_file *seq, struct ip6_sf_list *psf)
+{
+ struct igmp6_mcf_iter_state *state = igmp6_mcf_seq_private(seq);
+
+ psf = psf->sf_next;
+ while (!psf) {
+ spin_unlock_bh(&state->im->mca_lock);
+ state->im = state->im->next;
+ while (!state->im) {
+ if (likely(state->idev != NULL))
+ read_unlock_bh(&state->idev->lock);
+
+ state->dev = next_net_device_rcu(state->dev);
+ if (!state->dev) {
+ state->idev = NULL;
+ goto out;
+ }
+ state->idev = __in6_dev_get(state->dev);
+ if (!state->idev)
+ continue;
+ read_lock_bh(&state->idev->lock);
+ state->im = state->idev->mc_list;
+ }
+ if (!state->im)
+ break;
+ spin_lock_bh(&state->im->mca_lock);
+ psf = state->im->mca_sources;
+ }
+out:
+ return psf;
+}
+
+static struct ip6_sf_list *igmp6_mcf_get_idx(struct seq_file *seq, loff_t pos)
+{
+ struct ip6_sf_list *psf = igmp6_mcf_get_first(seq);
+ if (psf)
+ while (pos && (psf = igmp6_mcf_get_next(seq, psf)) != NULL)
+ --pos;
+ return pos ? NULL : psf;
+}
+
+static void *igmp6_mcf_seq_start(struct seq_file *seq, loff_t *pos)
+ __acquires(RCU)
+{
+ rcu_read_lock();
+ return *pos ? igmp6_mcf_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+}
+
+static void *igmp6_mcf_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct ip6_sf_list *psf;
+ if (v == SEQ_START_TOKEN)
+ psf = igmp6_mcf_get_first(seq);
+ else
+ psf = igmp6_mcf_get_next(seq, v);
+ ++*pos;
+ return psf;
+}
+
+static void igmp6_mcf_seq_stop(struct seq_file *seq, void *v)
+ __releases(RCU)
+{
+ struct igmp6_mcf_iter_state *state = igmp6_mcf_seq_private(seq);
+ if (likely(state->im != NULL)) {
+ spin_unlock_bh(&state->im->mca_lock);
+ state->im = NULL;
+ }
+ if (likely(state->idev != NULL)) {
+ read_unlock_bh(&state->idev->lock);
+ state->idev = NULL;
+ }
+ state->dev = NULL;
+ rcu_read_unlock();
+}
+
+static int igmp6_mcf_seq_show(struct seq_file *seq, void *v)
+{
+ struct ip6_sf_list *psf = (struct ip6_sf_list *)v;
+ struct igmp6_mcf_iter_state *state = igmp6_mcf_seq_private(seq);
+
+ if (v == SEQ_START_TOKEN) {
+ seq_printf(seq,
+ "%3s %6s "
+ "%32s %32s %6s %6s\n", "Idx",
+ "Device", "Multicast Address",
+ "Source Address", "INC", "EXC");
+ } else {
+ seq_printf(seq,
+ "%3d %6.6s %pi6 %pi6 %6lu %6lu\n",
+ state->dev->ifindex, state->dev->name,
+ &state->im->mca_addr,
+ &psf->sf_addr,
+ psf->sf_count[MCAST_INCLUDE],
+ psf->sf_count[MCAST_EXCLUDE]);
+ }
+ return 0;
+}
+
+static const struct seq_operations igmp6_mcf_seq_ops = {
+ .start = igmp6_mcf_seq_start,
+ .next = igmp6_mcf_seq_next,
+ .stop = igmp6_mcf_seq_stop,
+ .show = igmp6_mcf_seq_show,
+};
+
+static int igmp6_mcf_seq_open(struct inode *inode, struct file *file)
+{
+ return seq_open_net(inode, file, &igmp6_mcf_seq_ops,
+ sizeof(struct igmp6_mcf_iter_state));
+}
+
+static const struct file_operations igmp6_mcf_seq_fops = {
+ .owner = THIS_MODULE,
+ .open = igmp6_mcf_seq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release_net,
+};
+
+static int __net_init igmp6_proc_init(struct net *net)
+{
+ int err;
+
+ err = -ENOMEM;
+ if (!proc_create("igmp6", S_IRUGO, net->proc_net, &igmp6_mc_seq_fops))
+ goto out;
+ if (!proc_create("mcfilter6", S_IRUGO, net->proc_net,
+ &igmp6_mcf_seq_fops))
+ goto out_proc_net_igmp6;
+
+ err = 0;
+out:
+ return err;
+
+out_proc_net_igmp6:
+ remove_proc_entry("igmp6", net->proc_net);
+ goto out;
+}
+
+static void __net_exit igmp6_proc_exit(struct net *net)
+{
+ remove_proc_entry("mcfilter6", net->proc_net);
+ remove_proc_entry("igmp6", net->proc_net);
+}
+
+static int __net_init igmp6_net_init(struct net *net)
+{
+ int err;
+
+ err = inet_ctl_sock_create(&net->ipv6.igmp_sk, PF_INET6,
+ SOCK_RAW, IPPROTO_ICMPV6, net);
+ if (err < 0) {
+ pr_err("Failed to initialize the IGMP6 control socket (err %d)\n",
+ err);
+ goto out;
+ }
+
+ inet6_sk(net->ipv6.igmp_sk)->hop_limit = 1;
+
+ err = igmp6_proc_init(net);
+ if (err)
+ goto out_sock_create;
+out:
+ return err;
+
+out_sock_create:
+ inet_ctl_sock_destroy(net->ipv6.igmp_sk);
+ goto out;
+}
+
+static void __net_exit igmp6_net_exit(struct net *net)
+{
+ inet_ctl_sock_destroy(net->ipv6.igmp_sk);
+ igmp6_proc_exit(net);
+}
+
+static struct pernet_operations igmp6_net_ops = {
+ .init = igmp6_net_init,
+ .exit = igmp6_net_exit,
+};
+
+int __init igmp6_init(void)
+{
+ return register_pernet_subsys(&igmp6_net_ops);
+}
+
+void igmp6_cleanup(void)
+{
+ unregister_pernet_subsys(&igmp6_net_ops);
+}
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [Patch net-next] ipv6: separate out procfs code from mcast.c
2013-04-23 7:07 [Patch net-next] ipv6: separate out procfs code from mcast.c Cong Wang
@ 2013-04-23 7:11 ` David Miller
2013-04-23 7:15 ` Cong Wang
0 siblings, 1 reply; 13+ messages in thread
From: David Miller @ 2013-04-23 7:11 UTC (permalink / raw)
To: amwang; +Cc: netdev, yoshfuji
From: Cong Wang <amwang@redhat.com>
Date: Tue, 23 Apr 2013 15:07:00 +0800
> From: Cong Wang <amwang@redhat.com>
>
> They well deserve a separated unit.
>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
> Signed-off-by: Cong Wang <amwang@redhat.com>
Cong, I'm not even reading these patches.
You're on this idea that you can just keep the sysfs and procfs bits
of ipv6 modular, and make the rest of ipv6 statically linked into the
kernel.
I'm not going to facilitate nor take this seriously.
Sorry.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Patch net-next] ipv6: separate out procfs code from mcast.c
2013-04-23 7:11 ` David Miller
@ 2013-04-23 7:15 ` Cong Wang
2013-04-23 7:18 ` David Miller
0 siblings, 1 reply; 13+ messages in thread
From: Cong Wang @ 2013-04-23 7:15 UTC (permalink / raw)
To: David Miller; +Cc: netdev, yoshfuji
On Tue, 2013-04-23 at 03:11 -0400, David Miller wrote:
> From: Cong Wang <amwang@redhat.com>
> Date: Tue, 23 Apr 2013 15:07:00 +0800
>
> > From: Cong Wang <amwang@redhat.com>
> >
> > They well deserve a separated unit.
> >
> > Cc: "David S. Miller" <davem@davemloft.net>
> > Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
> > Signed-off-by: Cong Wang <amwang@redhat.com>
>
> Cong, I'm not even reading these patches.
>
> You're on this idea that you can just keep the sysfs and procfs bits
> of ipv6 modular, and make the rest of ipv6 statically linked into the
> kernel.
I am trying that only for mcast.c, not for the whole IPv6.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Patch net-next] ipv6: separate out procfs code from mcast.c
2013-04-23 7:15 ` Cong Wang
@ 2013-04-23 7:18 ` David Miller
2013-04-23 7:30 ` Cong Wang
0 siblings, 1 reply; 13+ messages in thread
From: David Miller @ 2013-04-23 7:18 UTC (permalink / raw)
To: amwang; +Cc: netdev, yoshfuji
From: Cong Wang <amwang@redhat.com>
Date: Tue, 23 Apr 2013 15:15:02 +0800
> On Tue, 2013-04-23 at 03:11 -0400, David Miller wrote:
>> From: Cong Wang <amwang@redhat.com>
>> Date: Tue, 23 Apr 2013 15:07:00 +0800
>>
>> > From: Cong Wang <amwang@redhat.com>
>> >
>> > They well deserve a separated unit.
>> >
>> > Cc: "David S. Miller" <davem@davemloft.net>
>> > Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
>> > Signed-off-by: Cong Wang <amwang@redhat.com>
>>
>> Cong, I'm not even reading these patches.
>>
>> You're on this idea that you can just keep the sysfs and procfs bits
>> of ipv6 modular, and make the rest of ipv6 statically linked into the
>> kernel.
>
> I am trying that only for mcast.c, not for the whole IPv6.
The multicast stuff does route lookups, how are you going to
accomplish this?
Besides you should move the statically-needed code into a new
file (mcast_core.c or something like that, following the existing
model and conventions for doing this) rather than the other way
around.
And that patch should be posted in a series with the user that
needs this (your vxlan ipv6 patches), not by itself.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Patch net-next] ipv6: separate out procfs code from mcast.c
2013-04-23 7:18 ` David Miller
@ 2013-04-23 7:30 ` Cong Wang
2013-04-23 7:36 ` David Miller
0 siblings, 1 reply; 13+ messages in thread
From: Cong Wang @ 2013-04-23 7:30 UTC (permalink / raw)
To: David Miller; +Cc: netdev, yoshfuji
On Tue, 2013-04-23 at 03:18 -0400, David Miller wrote:
> From: Cong Wang <amwang@redhat.com>
> Date: Tue, 23 Apr 2013 15:15:02 +0800
>
> > On Tue, 2013-04-23 at 03:11 -0400, David Miller wrote:
> >> From: Cong Wang <amwang@redhat.com>
> >> Date: Tue, 23 Apr 2013 15:07:00 +0800
> >>
> >> > From: Cong Wang <amwang@redhat.com>
> >> >
> >> > They well deserve a separated unit.
> >> >
> >> > Cc: "David S. Miller" <davem@davemloft.net>
> >> > Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
> >> > Signed-off-by: Cong Wang <amwang@redhat.com>
> >>
> >> Cong, I'm not even reading these patches.
> >>
> >> You're on this idea that you can just keep the sysfs and procfs bits
> >> of ipv6 modular, and make the rest of ipv6 statically linked into the
> >> kernel.
> >
> > I am trying that only for mcast.c, not for the whole IPv6.
>
> The multicast stuff does route lookups, how are you going to
> accomplish this?
This is hard to do, as in the email I replied to Stephen. So I prefer to
just add a Kconfig dependency, at least for now.
>
> Besides you should move the statically-needed code into a new
> file (mcast_core.c or something like that, following the existing
> model and conventions for doing this) rather than the other way
> around.
Yes, this is half-done and is also why I sent it alone rather than in
the VXLAN series.
Thanks.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Patch net-next] ipv6: separate out procfs code from mcast.c
2013-04-23 7:30 ` Cong Wang
@ 2013-04-23 7:36 ` David Miller
2013-04-23 7:41 ` Cong Wang
0 siblings, 1 reply; 13+ messages in thread
From: David Miller @ 2013-04-23 7:36 UTC (permalink / raw)
To: amwang; +Cc: netdev, yoshfuji
From: Cong Wang <amwang@redhat.com>
Date: Tue, 23 Apr 2013 15:30:20 +0800
> This is hard to do, as in the email I replied to Stephen. So I
> prefer to just add a Kconfig dependency, at least for now.
A Kconfig hack is exactly what I've told you is an unacceptable
solution.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Patch net-next] ipv6: separate out procfs code from mcast.c
2013-04-23 7:36 ` David Miller
@ 2013-04-23 7:41 ` Cong Wang
2013-04-23 12:33 ` Bjørn Mork
0 siblings, 1 reply; 13+ messages in thread
From: Cong Wang @ 2013-04-23 7:41 UTC (permalink / raw)
To: David Miller; +Cc: netdev, yoshfuji
On Tue, 2013-04-23 at 03:36 -0400, David Miller wrote:
> From: Cong Wang <amwang@redhat.com>
> Date: Tue, 23 Apr 2013 15:30:20 +0800
>
> > This is hard to do, as in the email I replied to Stephen. So I
> > prefer to just add a Kconfig dependency, at least for now.
>
> A Kconfig hack is exactly what I've told you is an unacceptable
> solution.
Please enlighten me for a third solution. :)
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Patch net-next] ipv6: separate out procfs code from mcast.c
2013-04-23 7:41 ` Cong Wang
@ 2013-04-23 12:33 ` Bjørn Mork
2013-04-23 16:13 ` Ben Hutchings
` (2 more replies)
0 siblings, 3 replies; 13+ messages in thread
From: Bjørn Mork @ 2013-04-23 12:33 UTC (permalink / raw)
To: Cong Wang; +Cc: David Miller, netdev, yoshfuji
Cong Wang <amwang@redhat.com> writes:
> On Tue, 2013-04-23 at 03:36 -0400, David Miller wrote:
>> From: Cong Wang <amwang@redhat.com>
>> Date: Tue, 23 Apr 2013 15:30:20 +0800
>>
>> > This is hard to do, as in the email I replied to Stephen. So I
>> > prefer to just add a Kconfig dependency, at least for now.
>>
>> A Kconfig hack is exactly what I've told you is an unacceptable
>> solution.
>
> Please enlighten me for a third solution. :)
This is an completely untested idea....
I note that vxlan_init_net requires a successful sock_create_kern().
That implies a request_module("net-pf-...") followed by try_module_get.
So if the sock_create_kern(PF_INET6, ..) succeeds then you *know* you
have IPv6. If it fails with -EAFNOSUPPORT, then you could fall back to
sock_create_kern(PF_INET, ..) and set a flag indicating that runtime
IPv6 support is disabled. Then use this flag to allow/deny configuring
any IPv6 destinations.
You may also have to protect the IPv6 modular symbols you use with
symbol_request() or similar to prevent vxlan from depending on IPv6. I
dunno...
If nothing else, I believe this is a crazy enough hack that David may
want to reconsider one of your other two solutions :)
Bjørn
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Patch net-next] ipv6: separate out procfs code from mcast.c
2013-04-23 12:33 ` Bjørn Mork
@ 2013-04-23 16:13 ` Ben Hutchings
2013-04-24 3:33 ` Cong Wang
2013-04-23 17:26 ` David Stevens
2013-04-24 3:29 ` Cong Wang
2 siblings, 1 reply; 13+ messages in thread
From: Ben Hutchings @ 2013-04-23 16:13 UTC (permalink / raw)
To: Bjørn Mork; +Cc: Cong Wang, David Miller, netdev, yoshfuji
On Tue, 2013-04-23 at 14:33 +0200, Bjørn Mork wrote:
> Cong Wang <amwang@redhat.com> writes:
>
> > On Tue, 2013-04-23 at 03:36 -0400, David Miller wrote:
> >> From: Cong Wang <amwang@redhat.com>
> >> Date: Tue, 23 Apr 2013 15:30:20 +0800
> >>
> >> > This is hard to do, as in the email I replied to Stephen. So I
> >> > prefer to just add a Kconfig dependency, at least for now.
> >>
> >> A Kconfig hack is exactly what I've told you is an unacceptable
> >> solution.
> >
> > Please enlighten me for a third solution. :)
>
> This is an completely untested idea....
>
> I note that vxlan_init_net requires a successful sock_create_kern().
> That implies a request_module("net-pf-...") followed by try_module_get.
>
> So if the sock_create_kern(PF_INET6, ..) succeeds then you *know* you
> have IPv6. If it fails with -EAFNOSUPPORT, then you could fall back to
> sock_create_kern(PF_INET, ..) and set a flag indicating that runtime
> IPv6 support is disabled. Then use this flag to allow/deny configuring
> any IPv6 destinations.
>
> You may also have to protect the IPv6 modular symbols you use with
> symbol_request() or similar to prevent vxlan from depending on IPv6. I
> dunno...
>
> If nothing else, I believe this is a crazy enough hack that David may
> want to reconsider one of your other two solutions :)
A more type-safe approach would be to define something like:
/* net/ipv6.h */
struct ipv6_mcast_ops {
...
};
extern const struct ipv6_mcast_ops *ipv6_mcast_ops;
/* net/ipv6/addrconf_core.c */
const struct ipv6_mcast_ops *ipv6_mcast_ops;
EXPORT_SYMBOL_GPL(ipv6_mcast_ops);
/* net/ipv6/af_inet6.c */
static const struct ipv6_mcast_ops ipv6_mcast_ops_impl = {
...
};
static int __init inet6_init(void)
{
...
ipv6_mcast_ops = &ipv6_mcast_ops_impl;
return 0;
...
}
static void __exit inet6_exit(void)
{
...
ipv6_mcast_ops = NULL;
...
}
Ben.
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Patch net-next] ipv6: separate out procfs code from mcast.c
2013-04-23 12:33 ` Bjørn Mork
2013-04-23 16:13 ` Ben Hutchings
@ 2013-04-23 17:26 ` David Stevens
2013-04-24 5:26 ` Cong Wang
2013-04-24 3:29 ` Cong Wang
2 siblings, 1 reply; 13+ messages in thread
From: David Stevens @ 2013-04-23 17:26 UTC (permalink / raw)
To: Bjørn Mork; +Cc: Cong Wang, David Miller, netdev, netdev-owner, yoshfuji
netdev-owner@vger.kernel.org wrote on 04/23/2013 08:33:57 AM:
> From: Bjørn Mork <bjorn@mork.no>
> Cong Wang <amwang@redhat.com> writes:
> I note that vxlan_init_net requires a successful sock_create_kern().
> That implies a request_module("net-pf-...") followed by try_module_get.
>
> So if the sock_create_kern(PF_INET6, ..) succeeds then you *know* you
> have IPv6. If it fails with -EAFNOSUPPORT, then you could fall back to
> sock_create_kern(PF_INET, ..) and set a flag indicating that runtime
> IPv6 support is disabled. Then use this flag to allow/deny configuring
> any IPv6 destinations.
BTW, another thing I thought of after I sent my patch comments -- you
also need to consider the state of net.ipv6.bindv6only. When v6 is
enabled, you use one socket for v4 and v6, but if bindv6only=1, you
actually need a separate socket for v4 receives. If you want to support
both v4 and v6 with bindv6only=1, you need two sockets. Or even if you
want to support v4-only VXLAN and the sysadmin has set bindv6only=1.
+-DLS
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Patch net-next] ipv6: separate out procfs code from mcast.c
2013-04-23 12:33 ` Bjørn Mork
2013-04-23 16:13 ` Ben Hutchings
2013-04-23 17:26 ` David Stevens
@ 2013-04-24 3:29 ` Cong Wang
2 siblings, 0 replies; 13+ messages in thread
From: Cong Wang @ 2013-04-24 3:29 UTC (permalink / raw)
To: Bjørn Mork; +Cc: David Miller, netdev, yoshfuji
On Tue, 2013-04-23 at 14:33 +0200, Bjørn Mork wrote:
> Cong Wang <amwang@redhat.com> writes:
>
> > On Tue, 2013-04-23 at 03:36 -0400, David Miller wrote:
> >> From: Cong Wang <amwang@redhat.com>
> >> Date: Tue, 23 Apr 2013 15:30:20 +0800
> >>
> >> > This is hard to do, as in the email I replied to Stephen. So I
> >> > prefer to just add a Kconfig dependency, at least for now.
> >>
> >> A Kconfig hack is exactly what I've told you is an unacceptable
> >> solution.
> >
> > Please enlighten me for a third solution. :)
>
> This is an completely untested idea....
>
> I note that vxlan_init_net requires a successful sock_create_kern().
> That implies a request_module("net-pf-...") followed by try_module_get.
>
> So if the sock_create_kern(PF_INET6, ..) succeeds then you *know* you
> have IPv6. If it fails with -EAFNOSUPPORT, then you could fall back to
> sock_create_kern(PF_INET, ..) and set a flag indicating that runtime
> IPv6 support is disabled. Then use this flag to allow/deny configuring
> any IPv6 destinations.
Excellent point! You are certainly right. I will give it a try.
>
> You may also have to protect the IPv6 modular symbols you use with
> symbol_request() or similar to prevent vxlan from depending on IPv6. I
> dunno...
>
This sounds a bit crazy.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Patch net-next] ipv6: separate out procfs code from mcast.c
2013-04-23 16:13 ` Ben Hutchings
@ 2013-04-24 3:33 ` Cong Wang
0 siblings, 0 replies; 13+ messages in thread
From: Cong Wang @ 2013-04-24 3:33 UTC (permalink / raw)
To: Ben Hutchings; +Cc: Bjørn Mork, David Miller, netdev, yoshfuji
On Tue, 2013-04-23 at 17:13 +0100, Ben Hutchings wrote:
>
> A more type-safe approach would be to define something like:
>
> /* net/ipv6.h */
> struct ipv6_mcast_ops {
> ...
> };
> extern const struct ipv6_mcast_ops *ipv6_mcast_ops;
>
> /* net/ipv6/addrconf_core.c */
> const struct ipv6_mcast_ops *ipv6_mcast_ops;
> EXPORT_SYMBOL_GPL(ipv6_mcast_ops);
>
> /* net/ipv6/af_inet6.c */
> static const struct ipv6_mcast_ops ipv6_mcast_ops_impl = {
> ...
> };
> static int __init inet6_init(void)
> {
> ...
> ipv6_mcast_ops = &ipv6_mcast_ops_impl;
> return 0;
> ...
> }
> static void __exit inet6_exit(void)
> {
> ...
> ipv6_mcast_ops = NULL;
> ...
> }
Yeah! That's a nice stub! I think this is the only doable and acceptable
solution so far.
Thanks a lot!
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Patch net-next] ipv6: separate out procfs code from mcast.c
2013-04-23 17:26 ` David Stevens
@ 2013-04-24 5:26 ` Cong Wang
0 siblings, 0 replies; 13+ messages in thread
From: Cong Wang @ 2013-04-24 5:26 UTC (permalink / raw)
To: David Stevens
Cc: Bjørn Mork, David Miller, netdev, netdev-owner, yoshfuji
On Tue, 2013-04-23 at 13:26 -0400, David Stevens wrote:
> BTW, another thing I thought of after I sent my patch comments -- you
> also need to consider the state of net.ipv6.bindv6only. When v6 is
> enabled, you use one socket for v4 and v6, but if bindv6only=1, you
> actually need a separate socket for v4 receives. If you want to support
> both v4 and v6 with bindv6only=1, you need two sockets. Or even if you
> want to support v4-only VXLAN and the sysadmin has set bindv6only=1.
>
Good point!
Actually the initial version of my patch did use two sockets for v4 and
v6. I am adding this to my TODO list.
Thanks!
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2013-04-24 5:27 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-04-23 7:07 [Patch net-next] ipv6: separate out procfs code from mcast.c Cong Wang
2013-04-23 7:11 ` David Miller
2013-04-23 7:15 ` Cong Wang
2013-04-23 7:18 ` David Miller
2013-04-23 7:30 ` Cong Wang
2013-04-23 7:36 ` David Miller
2013-04-23 7:41 ` Cong Wang
2013-04-23 12:33 ` Bjørn Mork
2013-04-23 16:13 ` Ben Hutchings
2013-04-24 3:33 ` Cong Wang
2013-04-23 17:26 ` David Stevens
2013-04-24 5:26 ` Cong Wang
2013-04-24 3:29 ` Cong Wang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).