aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Lezcano <dlezcano@fr.ibm.com>2008-01-11 01:43:18 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:01:44 -0500
commitbfeade087005278fc8cafe230b7658a4f40c5acb (patch)
treed9bbacab07552cc6c33f9f022a34af2391d9ecc1
parent3c40090a0f5b69deecc5ca615f994957f949333d (diff)
[NETNS][IPV6]: inet6_addr - check ipv6 address per namespace
When a new address is added, we must check if the new address does not already exists. This patch makes this check to be aware of a network namespace, so the check will look if the address already exists for the specified network namespace. While the addresses are browsed, the addresses which do not belong to the namespace are discarded. 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>
-rw-r--r--include/net/addrconf.h4
-rw-r--r--net/ipv6/addrconf.c6
-rw-r--r--net/ipv6/af_inet6.c3
-rw-r--r--net/ipv6/anycast.c2
-rw-r--r--net/ipv6/datagram.c3
-rw-r--r--net/ipv6/icmp.c2
-rw-r--r--net/ipv6/ip6_tunnel.c8
-rw-r--r--net/ipv6/ndisc.c2
-rw-r--r--net/ipv6/raw.c3
-rw-r--r--net/sctp/ipv6.c5
10 files changed, 23 insertions, 15 deletions
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 1c3a5602990e..d1697b587a1a 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -59,9 +59,11 @@ extern int addrconf_add_ifaddr(void __user *arg);
59extern int addrconf_del_ifaddr(void __user *arg); 59extern int addrconf_del_ifaddr(void __user *arg);
60extern int addrconf_set_dstaddr(void __user *arg); 60extern int addrconf_set_dstaddr(void __user *arg);
61 61
62extern int ipv6_chk_addr(struct in6_addr *addr, 62extern int ipv6_chk_addr(struct net *net,
63 struct in6_addr *addr,
63 struct net_device *dev, 64 struct net_device *dev,
64 int strict); 65 int strict);
66
65#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) 67#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
66extern int ipv6_chk_home_addr(struct in6_addr *addr); 68extern int ipv6_chk_home_addr(struct in6_addr *addr);
67#endif 69#endif
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index d7b440343e97..f35c3df410df 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1206,13 +1206,16 @@ static int ipv6_count_addresses(struct inet6_dev *idev)
1206 return cnt; 1206 return cnt;
1207} 1207}
1208 1208
1209int ipv6_chk_addr(struct in6_addr *addr, struct net_device *dev, int strict) 1209int ipv6_chk_addr(struct net *net, struct in6_addr *addr,
1210 struct net_device *dev, int strict)
1210{ 1211{
1211 struct inet6_ifaddr * ifp; 1212 struct inet6_ifaddr * ifp;
1212 u8 hash = ipv6_addr_hash(addr); 1213 u8 hash = ipv6_addr_hash(addr);
1213 1214
1214 read_lock_bh(&addrconf_hash_lock); 1215 read_lock_bh(&addrconf_hash_lock);
1215 for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) { 1216 for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) {
1217 if (ifp->idev->dev->nd_net != net)
1218 continue;
1216 if (ipv6_addr_equal(&ifp->addr, addr) && 1219 if (ipv6_addr_equal(&ifp->addr, addr) &&
1217 !(ifp->flags&IFA_F_TENTATIVE)) { 1220 !(ifp->flags&IFA_F_TENTATIVE)) {
1218 if (dev == NULL || ifp->idev->dev == dev || 1221 if (dev == NULL || ifp->idev->dev == dev ||
@@ -1223,7 +1226,6 @@ int ipv6_chk_addr(struct in6_addr *addr, struct net_device *dev, int strict)
1223 read_unlock_bh(&addrconf_hash_lock); 1226 read_unlock_bh(&addrconf_hash_lock);
1224 return ifp != NULL; 1227 return ifp != NULL;
1225} 1228}
1226
1227EXPORT_SYMBOL(ipv6_chk_addr); 1229EXPORT_SYMBOL(ipv6_chk_addr);
1228 1230
1229static 1231static
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index ac8772dd968f..3150c4be3c0c 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -314,7 +314,8 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
314 */ 314 */
315 v4addr = LOOPBACK4_IPV6; 315 v4addr = LOOPBACK4_IPV6;
316 if (!(addr_type & IPV6_ADDR_MULTICAST)) { 316 if (!(addr_type & IPV6_ADDR_MULTICAST)) {
317 if (!ipv6_chk_addr(&addr->sin6_addr, dev, 0)) { 317 if (!ipv6_chk_addr(&init_net, &addr->sin6_addr,
318 dev, 0)) {
318 if (dev) 319 if (dev)
319 dev_put(dev); 320 dev_put(dev);
320 err = -EADDRNOTAVAIL; 321 err = -EADDRNOTAVAIL;
diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c
index 5c4190060e75..9c7f83fbc3a1 100644
--- a/net/ipv6/anycast.c
+++ b/net/ipv6/anycast.c
@@ -89,7 +89,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr)
89 return -EPERM; 89 return -EPERM;
90 if (ipv6_addr_is_multicast(addr)) 90 if (ipv6_addr_is_multicast(addr))
91 return -EINVAL; 91 return -EINVAL;
92 if (ipv6_chk_addr(addr, NULL, 0)) 92 if (ipv6_chk_addr(&init_net, addr, NULL, 0))
93 return -EINVAL; 93 return -EINVAL;
94 94
95 pac = sock_kmalloc(sk, sizeof(struct ipv6_ac_socklist), GFP_KERNEL); 95 pac = sock_kmalloc(sk, sizeof(struct ipv6_ac_socklist), GFP_KERNEL);
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index f49a06aa97de..94fa6ae77cfe 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -549,7 +549,8 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
549 return -ENODEV; 549 return -ENODEV;
550 } 550 }
551 } 551 }
552 if (!ipv6_chk_addr(&src_info->ipi6_addr, dev, 0)) { 552 if (!ipv6_chk_addr(&init_net, &src_info->ipi6_addr,
553 dev, 0)) {
553 if (dev) 554 if (dev)
554 dev_put(dev); 555 dev_put(dev);
555 err = -EINVAL; 556 err = -EINVAL;
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 5395afe55ca5..cbb5b9cf84ad 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -332,7 +332,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
332 */ 332 */
333 addr_type = ipv6_addr_type(&hdr->daddr); 333 addr_type = ipv6_addr_type(&hdr->daddr);
334 334
335 if (ipv6_chk_addr(&hdr->daddr, skb->dev, 0)) 335 if (ipv6_chk_addr(&init_net, &hdr->daddr, skb->dev, 0))
336 saddr = &hdr->daddr; 336 saddr = &hdr->daddr;
337 337
338 /* 338 /*
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 29b5321e39c3..425c9ae8b315 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -653,8 +653,8 @@ static inline int ip6_tnl_rcv_ctl(struct ip6_tnl *t)
653 ldev = dev_get_by_index(&init_net, p->link); 653 ldev = dev_get_by_index(&init_net, p->link);
654 654
655 if ((ipv6_addr_is_multicast(&p->laddr) || 655 if ((ipv6_addr_is_multicast(&p->laddr) ||
656 likely(ipv6_chk_addr(&p->laddr, ldev, 0))) && 656 likely(ipv6_chk_addr(&init_net, &p->laddr, ldev, 0))) &&
657 likely(!ipv6_chk_addr(&p->raddr, NULL, 0))) 657 likely(!ipv6_chk_addr(&init_net, &p->raddr, NULL, 0)))
658 ret = 1; 658 ret = 1;
659 659
660 if (ldev) 660 if (ldev)
@@ -788,12 +788,12 @@ static inline int ip6_tnl_xmit_ctl(struct ip6_tnl *t)
788 if (p->link) 788 if (p->link)
789 ldev = dev_get_by_index(&init_net, p->link); 789 ldev = dev_get_by_index(&init_net, p->link);
790 790
791 if (unlikely(!ipv6_chk_addr(&p->laddr, ldev, 0))) 791 if (unlikely(!ipv6_chk_addr(&init_net, &p->laddr, ldev, 0)))
792 printk(KERN_WARNING 792 printk(KERN_WARNING
793 "%s xmit: Local address not yet configured!\n", 793 "%s xmit: Local address not yet configured!\n",
794 p->name); 794 p->name);
795 else if (!ipv6_addr_is_multicast(&p->raddr) && 795 else if (!ipv6_addr_is_multicast(&p->raddr) &&
796 unlikely(ipv6_chk_addr(&p->raddr, NULL, 0))) 796 unlikely(ipv6_chk_addr(&init_net, &p->raddr, NULL, 0)))
797 printk(KERN_WARNING 797 printk(KERN_WARNING
798 "%s xmit: Routing loop! " 798 "%s xmit: Routing loop! "
799 "Remote address found on this node!\n", 799 "Remote address found on this node!\n",
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index b66a1f81bd83..e217d3ff00f3 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -653,7 +653,7 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
653 struct in6_addr *target = (struct in6_addr *)&neigh->primary_key; 653 struct in6_addr *target = (struct in6_addr *)&neigh->primary_key;
654 int probes = atomic_read(&neigh->probes); 654 int probes = atomic_read(&neigh->probes);
655 655
656 if (skb && ipv6_chk_addr(&ipv6_hdr(skb)->saddr, dev, 1)) 656 if (skb && ipv6_chk_addr(&init_net, &ipv6_hdr(skb)->saddr, dev, 1))
657 saddr = &ipv6_hdr(skb)->saddr; 657 saddr = &ipv6_hdr(skb)->saddr;
658 658
659 if ((probes -= neigh->parms->ucast_probes) < 0) { 659 if ((probes -= neigh->parms->ucast_probes) < 0) {
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 45a580e843dc..cb0b110a2ac8 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -298,7 +298,8 @@ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
298 v4addr = LOOPBACK4_IPV6; 298 v4addr = LOOPBACK4_IPV6;
299 if (!(addr_type & IPV6_ADDR_MULTICAST)) { 299 if (!(addr_type & IPV6_ADDR_MULTICAST)) {
300 err = -EADDRNOTAVAIL; 300 err = -EADDRNOTAVAIL;
301 if (!ipv6_chk_addr(&addr->sin6_addr, dev, 0)) { 301 if (!ipv6_chk_addr(&init_net, &addr->sin6_addr,
302 dev, 0)) {
302 if (dev) 303 if (dev)
303 dev_put(dev); 304 dev_put(dev);
304 goto out; 305 goto out;
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index bd04aed673cb..74f106a7a7e9 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -556,7 +556,7 @@ static int sctp_v6_available(union sctp_addr *addr, struct sctp_sock *sp)
556 if (!(type & IPV6_ADDR_UNICAST)) 556 if (!(type & IPV6_ADDR_UNICAST))
557 return 0; 557 return 0;
558 558
559 return ipv6_chk_addr(in6, NULL, 0); 559 return ipv6_chk_addr(&init_net, in6, NULL, 0);
560} 560}
561 561
562/* This function checks if the address is a valid address to be used for 562/* This function checks if the address is a valid address to be used for
@@ -858,7 +858,8 @@ static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr)
858 dev = dev_get_by_index(&init_net, addr->v6.sin6_scope_id); 858 dev = dev_get_by_index(&init_net, addr->v6.sin6_scope_id);
859 if (!dev) 859 if (!dev)
860 return 0; 860 return 0;
861 if (!ipv6_chk_addr(&addr->v6.sin6_addr, dev, 0)) { 861 if (!ipv6_chk_addr(&init_net, &addr->v6.sin6_addr,
862 dev, 0)) {
862 dev_put(dev); 863 dev_put(dev);
863 return 0; 864 return 0;
864 } 865 }