Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bfeade08 authored by Daniel Lezcano's avatar Daniel Lezcano Committed by David S. Miller
Browse files

[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: default avatarDaniel Lezcano <dlezcano@fr.ibm.com>
Signed-off-by: default avatarBenjamin Thery <benjamin.thery@bull.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3c40090a
Loading
Loading
Loading
Loading
+3 −1
Original line number Original line Diff line number Diff line
@@ -59,9 +59,11 @@ extern int addrconf_add_ifaddr(void __user *arg);
extern int			addrconf_del_ifaddr(void __user *arg);
extern int			addrconf_del_ifaddr(void __user *arg);
extern int			addrconf_set_dstaddr(void __user *arg);
extern int			addrconf_set_dstaddr(void __user *arg);


extern int			ipv6_chk_addr(struct in6_addr *addr,
extern int			ipv6_chk_addr(struct net *net,
					      struct in6_addr *addr,
					      struct net_device *dev,
					      struct net_device *dev,
					      int strict);
					      int strict);

#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
extern int			ipv6_chk_home_addr(struct in6_addr *addr);
extern int			ipv6_chk_home_addr(struct in6_addr *addr);
#endif
#endif
+4 −2
Original line number Original line Diff line number Diff line
@@ -1206,13 +1206,16 @@ static int ipv6_count_addresses(struct inet6_dev *idev)
	return cnt;
	return cnt;
}
}


int ipv6_chk_addr(struct in6_addr *addr, struct net_device *dev, int strict)
int ipv6_chk_addr(struct net *net, struct in6_addr *addr,
		  struct net_device *dev, int strict)
{
{
	struct inet6_ifaddr * ifp;
	struct inet6_ifaddr * ifp;
	u8 hash = ipv6_addr_hash(addr);
	u8 hash = ipv6_addr_hash(addr);


	read_lock_bh(&addrconf_hash_lock);
	read_lock_bh(&addrconf_hash_lock);
	for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) {
	for(ifp = inet6_addr_lst[hash]; ifp; ifp=ifp->lst_next) {
		if (ifp->idev->dev->nd_net != net)
			continue;
		if (ipv6_addr_equal(&ifp->addr, addr) &&
		if (ipv6_addr_equal(&ifp->addr, addr) &&
		    !(ifp->flags&IFA_F_TENTATIVE)) {
		    !(ifp->flags&IFA_F_TENTATIVE)) {
			if (dev == NULL || ifp->idev->dev == dev ||
			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)
	read_unlock_bh(&addrconf_hash_lock);
	read_unlock_bh(&addrconf_hash_lock);
	return ifp != NULL;
	return ifp != NULL;
}
}

EXPORT_SYMBOL(ipv6_chk_addr);
EXPORT_SYMBOL(ipv6_chk_addr);


static
static
+2 −1
Original line number Original line Diff line number Diff line
@@ -314,7 +314,8 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
			 */
			 */
			v4addr = LOOPBACK4_IPV6;
			v4addr = LOOPBACK4_IPV6;
			if (!(addr_type & IPV6_ADDR_MULTICAST))	{
			if (!(addr_type & IPV6_ADDR_MULTICAST))	{
				if (!ipv6_chk_addr(&addr->sin6_addr, dev, 0)) {
				if (!ipv6_chk_addr(&init_net, &addr->sin6_addr,
						   dev, 0)) {
					if (dev)
					if (dev)
						dev_put(dev);
						dev_put(dev);
					err = -EADDRNOTAVAIL;
					err = -EADDRNOTAVAIL;
+1 −1
Original line number Original line Diff line number Diff line
@@ -89,7 +89,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr)
		return -EPERM;
		return -EPERM;
	if (ipv6_addr_is_multicast(addr))
	if (ipv6_addr_is_multicast(addr))
		return -EINVAL;
		return -EINVAL;
	if (ipv6_chk_addr(addr, NULL, 0))
	if (ipv6_chk_addr(&init_net, addr, NULL, 0))
		return -EINVAL;
		return -EINVAL;


	pac = sock_kmalloc(sk, sizeof(struct ipv6_ac_socklist), GFP_KERNEL);
	pac = sock_kmalloc(sk, sizeof(struct ipv6_ac_socklist), GFP_KERNEL);
+2 −1
Original line number Original line Diff line number Diff line
@@ -549,7 +549,8 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
						return -ENODEV;
						return -ENODEV;
				}
				}
			}
			}
			if (!ipv6_chk_addr(&src_info->ipi6_addr, dev, 0)) {
			if (!ipv6_chk_addr(&init_net, &src_info->ipi6_addr,
					   dev, 0)) {
				if (dev)
				if (dev)
					dev_put(dev);
					dev_put(dev);
				err = -EINVAL;
				err = -EINVAL;
Loading