diff options
author | Daniel Lezcano <dlezcano@fr.ibm.com> | 2008-01-11 01:43:18 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:01:44 -0500 |
commit | bfeade087005278fc8cafe230b7658a4f40c5acb (patch) | |
tree | d9bbacab07552cc6c33f9f022a34af2391d9ecc1 /net/ipv6 | |
parent | 3c40090a0f5b69deecc5ca615f994957f949333d (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>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/addrconf.c | 6 | ||||
-rw-r--r-- | net/ipv6/af_inet6.c | 3 | ||||
-rw-r--r-- | net/ipv6/anycast.c | 2 | ||||
-rw-r--r-- | net/ipv6/datagram.c | 3 | ||||
-rw-r--r-- | net/ipv6/icmp.c | 2 | ||||
-rw-r--r-- | net/ipv6/ip6_tunnel.c | 8 | ||||
-rw-r--r-- | net/ipv6/ndisc.c | 2 | ||||
-rw-r--r-- | net/ipv6/raw.c | 3 |
8 files changed, 17 insertions, 12 deletions
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 | ||
1209 | int ipv6_chk_addr(struct in6_addr *addr, struct net_device *dev, int strict) | 1209 | int 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 | |||
1227 | EXPORT_SYMBOL(ipv6_chk_addr); | 1229 | EXPORT_SYMBOL(ipv6_chk_addr); |
1228 | 1230 | ||
1229 | static | 1231 | static |
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; |