diff options
-rw-r--r-- | net/ipv4/igmp.c | 49 |
1 files changed, 40 insertions, 9 deletions
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index f92733e15c9f..9eb6219af615 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -2275,6 +2275,7 @@ int ip_check_mc(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u16 p | |||
2275 | 2275 | ||
2276 | #if defined(CONFIG_PROC_FS) | 2276 | #if defined(CONFIG_PROC_FS) |
2277 | struct igmp_mc_iter_state { | 2277 | struct igmp_mc_iter_state { |
2278 | struct seq_net_private p; | ||
2278 | struct net_device *dev; | 2279 | struct net_device *dev; |
2279 | struct in_device *in_dev; | 2280 | struct in_device *in_dev; |
2280 | }; | 2281 | }; |
@@ -2283,11 +2284,12 @@ struct igmp_mc_iter_state { | |||
2283 | 2284 | ||
2284 | static inline struct ip_mc_list *igmp_mc_get_first(struct seq_file *seq) | 2285 | static inline struct ip_mc_list *igmp_mc_get_first(struct seq_file *seq) |
2285 | { | 2286 | { |
2287 | struct net *net = seq_file_net(seq); | ||
2286 | struct ip_mc_list *im = NULL; | 2288 | struct ip_mc_list *im = NULL; |
2287 | struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq); | 2289 | struct igmp_mc_iter_state *state = igmp_mc_seq_private(seq); |
2288 | 2290 | ||
2289 | state->in_dev = NULL; | 2291 | state->in_dev = NULL; |
2290 | for_each_netdev(&init_net, state->dev) { | 2292 | for_each_netdev(net, state->dev) { |
2291 | struct in_device *in_dev; | 2293 | struct in_device *in_dev; |
2292 | in_dev = in_dev_get(state->dev); | 2294 | in_dev = in_dev_get(state->dev); |
2293 | if (!in_dev) | 2295 | if (!in_dev) |
@@ -2408,7 +2410,7 @@ static const struct seq_operations igmp_mc_seq_ops = { | |||
2408 | 2410 | ||
2409 | static int igmp_mc_seq_open(struct inode *inode, struct file *file) | 2411 | static int igmp_mc_seq_open(struct inode *inode, struct file *file) |
2410 | { | 2412 | { |
2411 | return seq_open_private(file, &igmp_mc_seq_ops, | 2413 | return seq_open_net(inode, file, &igmp_mc_seq_ops, |
2412 | sizeof(struct igmp_mc_iter_state)); | 2414 | sizeof(struct igmp_mc_iter_state)); |
2413 | } | 2415 | } |
2414 | 2416 | ||
@@ -2417,10 +2419,11 @@ static const struct file_operations igmp_mc_seq_fops = { | |||
2417 | .open = igmp_mc_seq_open, | 2419 | .open = igmp_mc_seq_open, |
2418 | .read = seq_read, | 2420 | .read = seq_read, |
2419 | .llseek = seq_lseek, | 2421 | .llseek = seq_lseek, |
2420 | .release = seq_release_private, | 2422 | .release = seq_release_net, |
2421 | }; | 2423 | }; |
2422 | 2424 | ||
2423 | struct igmp_mcf_iter_state { | 2425 | struct igmp_mcf_iter_state { |
2426 | struct seq_net_private p; | ||
2424 | struct net_device *dev; | 2427 | struct net_device *dev; |
2425 | struct in_device *idev; | 2428 | struct in_device *idev; |
2426 | struct ip_mc_list *im; | 2429 | struct ip_mc_list *im; |
@@ -2430,13 +2433,14 @@ struct igmp_mcf_iter_state { | |||
2430 | 2433 | ||
2431 | static inline struct ip_sf_list *igmp_mcf_get_first(struct seq_file *seq) | 2434 | static inline struct ip_sf_list *igmp_mcf_get_first(struct seq_file *seq) |
2432 | { | 2435 | { |
2436 | struct net *net = seq_file_net(seq); | ||
2433 | struct ip_sf_list *psf = NULL; | 2437 | struct ip_sf_list *psf = NULL; |
2434 | struct ip_mc_list *im = NULL; | 2438 | struct ip_mc_list *im = NULL; |
2435 | struct igmp_mcf_iter_state *state = igmp_mcf_seq_private(seq); | 2439 | struct igmp_mcf_iter_state *state = igmp_mcf_seq_private(seq); |
2436 | 2440 | ||
2437 | state->idev = NULL; | 2441 | state->idev = NULL; |
2438 | state->im = NULL; | 2442 | state->im = NULL; |
2439 | for_each_netdev(&init_net, state->dev) { | 2443 | for_each_netdev(net, state->dev) { |
2440 | struct in_device *idev; | 2444 | struct in_device *idev; |
2441 | idev = in_dev_get(state->dev); | 2445 | idev = in_dev_get(state->dev); |
2442 | if (unlikely(idev == NULL)) | 2446 | if (unlikely(idev == NULL)) |
@@ -2567,7 +2571,7 @@ static const struct seq_operations igmp_mcf_seq_ops = { | |||
2567 | 2571 | ||
2568 | static int igmp_mcf_seq_open(struct inode *inode, struct file *file) | 2572 | static int igmp_mcf_seq_open(struct inode *inode, struct file *file) |
2569 | { | 2573 | { |
2570 | return seq_open_private(file, &igmp_mcf_seq_ops, | 2574 | return seq_open_net(inode, file, &igmp_mcf_seq_ops, |
2571 | sizeof(struct igmp_mcf_iter_state)); | 2575 | sizeof(struct igmp_mcf_iter_state)); |
2572 | } | 2576 | } |
2573 | 2577 | ||
@@ -2576,14 +2580,41 @@ static const struct file_operations igmp_mcf_seq_fops = { | |||
2576 | .open = igmp_mcf_seq_open, | 2580 | .open = igmp_mcf_seq_open, |
2577 | .read = seq_read, | 2581 | .read = seq_read, |
2578 | .llseek = seq_lseek, | 2582 | .llseek = seq_lseek, |
2579 | .release = seq_release_private, | 2583 | .release = seq_release_net, |
2580 | }; | 2584 | }; |
2581 | 2585 | ||
2582 | int __init igmp_mc_proc_init(void) | 2586 | static int igmp_net_init(struct net *net) |
2583 | { | 2587 | { |
2584 | proc_net_fops_create(&init_net, "igmp", S_IRUGO, &igmp_mc_seq_fops); | 2588 | struct proc_dir_entry *pde; |
2585 | proc_net_fops_create(&init_net, "mcfilter", S_IRUGO, &igmp_mcf_seq_fops); | 2589 | |
2590 | pde = proc_net_fops_create(net, "igmp", S_IRUGO, &igmp_mc_seq_fops); | ||
2591 | if (!pde) | ||
2592 | goto out_igmp; | ||
2593 | pde = proc_net_fops_create(net, "mcfilter", S_IRUGO, &igmp_mcf_seq_fops); | ||
2594 | if (!pde) | ||
2595 | goto out_mcfilter; | ||
2586 | return 0; | 2596 | return 0; |
2597 | |||
2598 | out_mcfilter: | ||
2599 | proc_net_remove(net, "igmp"); | ||
2600 | out_igmp: | ||
2601 | return -ENOMEM; | ||
2602 | } | ||
2603 | |||
2604 | static void igmp_net_exit(struct net *net) | ||
2605 | { | ||
2606 | proc_net_remove(net, "mcfilter"); | ||
2607 | proc_net_remove(net, "igmp"); | ||
2608 | } | ||
2609 | |||
2610 | static struct pernet_operations igmp_net_ops = { | ||
2611 | .init = igmp_net_init, | ||
2612 | .exit = igmp_net_exit, | ||
2613 | }; | ||
2614 | |||
2615 | int __init igmp_mc_proc_init(void) | ||
2616 | { | ||
2617 | return register_pernet_subsys(&igmp_net_ops); | ||
2587 | } | 2618 | } |
2588 | #endif | 2619 | #endif |
2589 | 2620 | ||