aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/anycast.c
diff options
context:
space:
mode:
authorDaniel Lezcano <dlezcano@fr.ibm.com>2008-03-26 19:52:32 -0400
committerDavid S. Miller <davem@davemloft.net>2008-03-26 19:52:32 -0400
commit6ab57e7e7fa316552d0f94eaebf1def1d49f18da (patch)
tree5e0f5d2d9d302758a6c3bebd91ff0c11b110f5a1 /net/ipv6/anycast.c
parenta233352506be35aafd49c0ba8c88ca96ebde1c3d (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/anycast.c')
-rw-r--r--net/ipv6/anycast.c38
1 files changed, 22 insertions, 16 deletions
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 */
425int ipv6_chk_acast_addr(struct net_device *dev, struct in6_addr *addr) 428int 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
443struct ac6_iter_state { 447struct 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
552static int ac6_seq_open(struct inode *inode, struct file *file) 558static 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
558static const struct file_operations ac6_seq_fops = { 564static 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
566int __init ac6_proc_init(void) 572int 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
574void ac6_proc_exit(void) 580void 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