diff options
author | Daniel Lezcano <dlezcano@fr.ibm.com> | 2008-03-26 19:52:32 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-03-26 19:52:32 -0400 |
commit | 6ab57e7e7fa316552d0f94eaebf1def1d49f18da (patch) | |
tree | 5e0f5d2d9d302758a6c3bebd91ff0c11b110f5a1 /net/ipv6 | |
parent | a233352506be35aafd49c0ba8c88ca96ebde1c3d (diff) |
[NETNS][IPV6] anycast - handle several network namespace
Make use of the network namespace information to have this protocol to
handle several network namespace.
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
Signed-off-by: Benjamin Thery <benjamin.thery@bull.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/af_inet6.c | 12 | ||||
-rw-r--r-- | net/ipv6/anycast.c | 38 | ||||
-rw-r--r-- | net/ipv6/ndisc.c | 2 |
3 files changed, 29 insertions, 23 deletions
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 12f04e9d3e88..1731b0abf7f5 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -862,11 +862,16 @@ static int inet6_net_init(struct net *net) | |||
862 | err = tcp6_proc_init(net); | 862 | err = tcp6_proc_init(net); |
863 | if (err) | 863 | if (err) |
864 | goto proc_tcp6_fail; | 864 | goto proc_tcp6_fail; |
865 | err = ac6_proc_init(net); | ||
866 | if (err) | ||
867 | goto proc_ac6_fail; | ||
865 | out: | 868 | out: |
866 | #endif | 869 | #endif |
867 | return err; | 870 | return err; |
868 | 871 | ||
869 | #ifdef CONFIG_PROC_FS | 872 | #ifdef CONFIG_PROC_FS |
873 | proc_ac6_fail: | ||
874 | tcp6_proc_exit(net); | ||
870 | proc_tcp6_fail: | 875 | proc_tcp6_fail: |
871 | udp6_proc_exit(net); | 876 | udp6_proc_exit(net); |
872 | goto out; | 877 | goto out; |
@@ -878,6 +883,7 @@ static void inet6_net_exit(struct net *net) | |||
878 | #ifdef CONFIG_PROC_FS | 883 | #ifdef CONFIG_PROC_FS |
879 | udp6_proc_exit(net); | 884 | udp6_proc_exit(net); |
880 | tcp6_proc_exit(net); | 885 | tcp6_proc_exit(net); |
886 | ac6_proc_exit(net); | ||
881 | #endif | 887 | #endif |
882 | } | 888 | } |
883 | 889 | ||
@@ -965,9 +971,6 @@ static int __init inet6_init(void) | |||
965 | goto proc_udplite6_fail; | 971 | goto proc_udplite6_fail; |
966 | if (ipv6_misc_proc_init()) | 972 | if (ipv6_misc_proc_init()) |
967 | goto proc_misc6_fail; | 973 | goto proc_misc6_fail; |
968 | |||
969 | if (ac6_proc_init()) | ||
970 | goto proc_anycast6_fail; | ||
971 | if (if6_proc_init()) | 974 | if (if6_proc_init()) |
972 | goto proc_if6_fail; | 975 | goto proc_if6_fail; |
973 | #endif | 976 | #endif |
@@ -1039,8 +1042,6 @@ ip6_route_fail: | |||
1039 | #ifdef CONFIG_PROC_FS | 1042 | #ifdef CONFIG_PROC_FS |
1040 | if6_proc_exit(); | 1043 | if6_proc_exit(); |
1041 | proc_if6_fail: | 1044 | proc_if6_fail: |
1042 | ac6_proc_exit(); | ||
1043 | proc_anycast6_fail: | ||
1044 | ipv6_misc_proc_exit(); | 1045 | ipv6_misc_proc_exit(); |
1045 | proc_misc6_fail: | 1046 | proc_misc6_fail: |
1046 | udplite6_proc_exit(); | 1047 | udplite6_proc_exit(); |
@@ -1101,7 +1102,6 @@ static void __exit inet6_exit(void) | |||
1101 | 1102 | ||
1102 | /* Cleanup code parts. */ | 1103 | /* Cleanup code parts. */ |
1103 | if6_proc_exit(); | 1104 | if6_proc_exit(); |
1104 | ac6_proc_exit(); | ||
1105 | ipv6_misc_proc_exit(); | 1105 | ipv6_misc_proc_exit(); |
1106 | udplite6_proc_exit(); | 1106 | udplite6_proc_exit(); |
1107 | raw6_proc_exit(); | 1107 | raw6_proc_exit(); |
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c index 96868b994b37..463bd95d6b13 100644 --- a/net/ipv6/anycast.c +++ b/net/ipv6/anycast.c | |||
@@ -82,6 +82,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr) | |||
82 | struct net_device *dev = NULL; | 82 | struct net_device *dev = NULL; |
83 | struct inet6_dev *idev; | 83 | struct inet6_dev *idev; |
84 | struct ipv6_ac_socklist *pac; | 84 | struct ipv6_ac_socklist *pac; |
85 | struct net *net = sock_net(sk); | ||
85 | int ishost = !ipv6_devconf.forwarding; | 86 | int ishost = !ipv6_devconf.forwarding; |
86 | int err = 0; | 87 | int err = 0; |
87 | 88 | ||
@@ -89,7 +90,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr) | |||
89 | return -EPERM; | 90 | return -EPERM; |
90 | if (ipv6_addr_is_multicast(addr)) | 91 | if (ipv6_addr_is_multicast(addr)) |
91 | return -EINVAL; | 92 | return -EINVAL; |
92 | if (ipv6_chk_addr(&init_net, addr, NULL, 0)) | 93 | if (ipv6_chk_addr(net, addr, NULL, 0)) |
93 | return -EINVAL; | 94 | return -EINVAL; |
94 | 95 | ||
95 | pac = sock_kmalloc(sk, sizeof(struct ipv6_ac_socklist), GFP_KERNEL); | 96 | pac = sock_kmalloc(sk, sizeof(struct ipv6_ac_socklist), GFP_KERNEL); |
@@ -101,7 +102,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr) | |||
101 | if (ifindex == 0) { | 102 | if (ifindex == 0) { |
102 | struct rt6_info *rt; | 103 | struct rt6_info *rt; |
103 | 104 | ||
104 | rt = rt6_lookup(&init_net, addr, NULL, 0, 0); | 105 | rt = rt6_lookup(net, addr, NULL, 0, 0); |
105 | if (rt) { | 106 | if (rt) { |
106 | dev = rt->rt6i_dev; | 107 | dev = rt->rt6i_dev; |
107 | dev_hold(dev); | 108 | dev_hold(dev); |
@@ -112,10 +113,10 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr) | |||
112 | } else { | 113 | } else { |
113 | /* router, no matching interface: just pick one */ | 114 | /* router, no matching interface: just pick one */ |
114 | 115 | ||
115 | dev = dev_get_by_flags(&init_net, IFF_UP, IFF_UP|IFF_LOOPBACK); | 116 | dev = dev_get_by_flags(net, IFF_UP, IFF_UP|IFF_LOOPBACK); |
116 | } | 117 | } |
117 | } else | 118 | } else |
118 | dev = dev_get_by_index(&init_net, ifindex); | 119 | dev = dev_get_by_index(net, ifindex); |
119 | 120 | ||
120 | if (dev == NULL) { | 121 | if (dev == NULL) { |
121 | err = -ENODEV; | 122 | err = -ENODEV; |
@@ -176,6 +177,7 @@ int ipv6_sock_ac_drop(struct sock *sk, int ifindex, struct in6_addr *addr) | |||
176 | struct ipv6_pinfo *np = inet6_sk(sk); | 177 | struct ipv6_pinfo *np = inet6_sk(sk); |
177 | struct net_device *dev; | 178 | struct net_device *dev; |
178 | struct ipv6_ac_socklist *pac, *prev_pac; | 179 | struct ipv6_ac_socklist *pac, *prev_pac; |
180 | struct net *net = sock_net(sk); | ||
179 | 181 | ||
180 | write_lock_bh(&ipv6_sk_ac_lock); | 182 | write_lock_bh(&ipv6_sk_ac_lock); |
181 | prev_pac = NULL; | 183 | prev_pac = NULL; |
@@ -196,7 +198,7 @@ int ipv6_sock_ac_drop(struct sock *sk, int ifindex, struct in6_addr *addr) | |||
196 | 198 | ||
197 | write_unlock_bh(&ipv6_sk_ac_lock); | 199 | write_unlock_bh(&ipv6_sk_ac_lock); |
198 | 200 | ||
199 | dev = dev_get_by_index(&init_net, pac->acl_ifindex); | 201 | dev = dev_get_by_index(net, pac->acl_ifindex); |
200 | if (dev) { | 202 | if (dev) { |
201 | ipv6_dev_ac_dec(dev, &pac->acl_addr); | 203 | ipv6_dev_ac_dec(dev, &pac->acl_addr); |
202 | dev_put(dev); | 204 | dev_put(dev); |
@@ -210,6 +212,7 @@ void ipv6_sock_ac_close(struct sock *sk) | |||
210 | struct ipv6_pinfo *np = inet6_sk(sk); | 212 | struct ipv6_pinfo *np = inet6_sk(sk); |
211 | struct net_device *dev = NULL; | 213 | struct net_device *dev = NULL; |
212 | struct ipv6_ac_socklist *pac; | 214 | struct ipv6_ac_socklist *pac; |
215 | struct net *net = sock_net(sk); | ||
213 | int prev_index; | 216 | int prev_index; |
214 | 217 | ||
215 | write_lock_bh(&ipv6_sk_ac_lock); | 218 | write_lock_bh(&ipv6_sk_ac_lock); |
@@ -224,7 +227,7 @@ void ipv6_sock_ac_close(struct sock *sk) | |||
224 | if (pac->acl_ifindex != prev_index) { | 227 | if (pac->acl_ifindex != prev_index) { |
225 | if (dev) | 228 | if (dev) |
226 | dev_put(dev); | 229 | dev_put(dev); |
227 | dev = dev_get_by_index(&init_net, pac->acl_ifindex); | 230 | dev = dev_get_by_index(net, pac->acl_ifindex); |
228 | prev_index = pac->acl_ifindex; | 231 | prev_index = pac->acl_ifindex; |
229 | } | 232 | } |
230 | if (dev) | 233 | if (dev) |
@@ -422,14 +425,15 @@ static int ipv6_chk_acast_dev(struct net_device *dev, struct in6_addr *addr) | |||
422 | /* | 425 | /* |
423 | * check if given interface (or any, if dev==0) has this anycast address | 426 | * check if given interface (or any, if dev==0) has this anycast address |
424 | */ | 427 | */ |
425 | int ipv6_chk_acast_addr(struct net_device *dev, struct in6_addr *addr) | 428 | int ipv6_chk_acast_addr(struct net *net, struct net_device *dev, |
429 | struct in6_addr *addr) | ||
426 | { | 430 | { |
427 | int found = 0; | 431 | int found = 0; |
428 | 432 | ||
429 | if (dev) | 433 | if (dev) |
430 | return ipv6_chk_acast_dev(dev, addr); | 434 | return ipv6_chk_acast_dev(dev, addr); |
431 | read_lock(&dev_base_lock); | 435 | read_lock(&dev_base_lock); |
432 | for_each_netdev(&init_net, dev) | 436 | for_each_netdev(net, dev) |
433 | if (ipv6_chk_acast_dev(dev, addr)) { | 437 | if (ipv6_chk_acast_dev(dev, addr)) { |
434 | found = 1; | 438 | found = 1; |
435 | break; | 439 | break; |
@@ -441,6 +445,7 @@ int ipv6_chk_acast_addr(struct net_device *dev, struct in6_addr *addr) | |||
441 | 445 | ||
442 | #ifdef CONFIG_PROC_FS | 446 | #ifdef CONFIG_PROC_FS |
443 | struct ac6_iter_state { | 447 | struct ac6_iter_state { |
448 | struct seq_net_private p; | ||
444 | struct net_device *dev; | 449 | struct net_device *dev; |
445 | struct inet6_dev *idev; | 450 | struct inet6_dev *idev; |
446 | }; | 451 | }; |
@@ -451,9 +456,10 @@ static inline struct ifacaddr6 *ac6_get_first(struct seq_file *seq) | |||
451 | { | 456 | { |
452 | struct ifacaddr6 *im = NULL; | 457 | struct ifacaddr6 *im = NULL; |
453 | struct ac6_iter_state *state = ac6_seq_private(seq); | 458 | struct ac6_iter_state *state = ac6_seq_private(seq); |
459 | struct net *net = seq_file_net(seq); | ||
454 | 460 | ||
455 | state->idev = NULL; | 461 | state->idev = NULL; |
456 | for_each_netdev(&init_net, state->dev) { | 462 | for_each_netdev(net, state->dev) { |
457 | struct inet6_dev *idev; | 463 | struct inet6_dev *idev; |
458 | idev = in6_dev_get(state->dev); | 464 | idev = in6_dev_get(state->dev); |
459 | if (!idev) | 465 | if (!idev) |
@@ -551,8 +557,8 @@ static const struct seq_operations ac6_seq_ops = { | |||
551 | 557 | ||
552 | static int ac6_seq_open(struct inode *inode, struct file *file) | 558 | static int ac6_seq_open(struct inode *inode, struct file *file) |
553 | { | 559 | { |
554 | return seq_open_private(file, &ac6_seq_ops, | 560 | return seq_open_net(inode, file, &ac6_seq_ops, |
555 | sizeof(struct ac6_iter_state)); | 561 | sizeof(struct ac6_iter_state)); |
556 | } | 562 | } |
557 | 563 | ||
558 | static const struct file_operations ac6_seq_fops = { | 564 | static const struct file_operations ac6_seq_fops = { |
@@ -560,20 +566,20 @@ static const struct file_operations ac6_seq_fops = { | |||
560 | .open = ac6_seq_open, | 566 | .open = ac6_seq_open, |
561 | .read = seq_read, | 567 | .read = seq_read, |
562 | .llseek = seq_lseek, | 568 | .llseek = seq_lseek, |
563 | .release = seq_release_private, | 569 | .release = seq_release_net, |
564 | }; | 570 | }; |
565 | 571 | ||
566 | int __init ac6_proc_init(void) | 572 | int ac6_proc_init(struct net *net) |
567 | { | 573 | { |
568 | if (!proc_net_fops_create(&init_net, "anycast6", S_IRUGO, &ac6_seq_fops)) | 574 | if (!proc_net_fops_create(net, "anycast6", S_IRUGO, &ac6_seq_fops)) |
569 | return -ENOMEM; | 575 | return -ENOMEM; |
570 | 576 | ||
571 | return 0; | 577 | return 0; |
572 | } | 578 | } |
573 | 579 | ||
574 | void ac6_proc_exit(void) | 580 | void ac6_proc_exit(struct net *net) |
575 | { | 581 | { |
576 | proc_net_remove(&init_net, "anycast6"); | 582 | proc_net_remove(net, "anycast6"); |
577 | } | 583 | } |
578 | #endif | 584 | #endif |
579 | 585 | ||
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 79af57f586e8..b4d8e331432e 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -773,7 +773,7 @@ static void ndisc_recv_ns(struct sk_buff *skb) | |||
773 | return; | 773 | return; |
774 | } | 774 | } |
775 | 775 | ||
776 | if (ipv6_chk_acast_addr(dev, &msg->target) || | 776 | if (ipv6_chk_acast_addr(dev_net(dev), dev, &msg->target) || |
777 | (idev->cnf.forwarding && | 777 | (idev->cnf.forwarding && |
778 | (ipv6_devconf.proxy_ndp || idev->cnf.proxy_ndp) && | 778 | (ipv6_devconf.proxy_ndp || idev->cnf.proxy_ndp) && |
779 | (pneigh = pneigh_lookup(&nd_tbl, dev_net(dev), | 779 | (pneigh = pneigh_lookup(&nd_tbl, dev_net(dev), |