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

Commit 52eeeb84 authored by YOSHIFUJI Hideaki's avatar YOSHIFUJI Hideaki
Browse files

[IPV6]: Unify ip6_onlink() and ipip6_onlink().

Both are identical, let's create ipv6_chk_prefix() and use it
in both places.
parent 6294e000
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -71,6 +71,10 @@ extern int ipv6_chk_addr(struct net *net,
extern int			ipv6_chk_home_addr(struct net *net,
						   struct in6_addr *addr);
#endif

extern int			ipv6_chk_prefix(struct in6_addr *addr,
						struct net_device *dev);

extern struct inet6_ifaddr      *ipv6_get_ifaddr(struct net *net,
						 struct in6_addr *addr,
						 struct net_device *dev,
+25 −0
Original line number Diff line number Diff line
@@ -1249,6 +1249,31 @@ int ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr,
	return ifp != NULL;
}

int ipv6_chk_prefix(struct in6_addr *addr, struct net_device *dev)
{
	struct inet6_dev *idev;
	struct inet6_ifaddr *ifa;
	int	onlink;

	onlink = 0;
	rcu_read_lock();
	idev = __in6_dev_get(dev);
	if (idev) {
		read_lock_bh(&idev->lock);
		for (ifa = idev->addr_list; ifa; ifa = ifa->if_next) {
			onlink = ipv6_prefix_equal(addr, &ifa->addr,
						   ifa->prefix_len);
			if (onlink)
				break;
		}
		read_unlock_bh(&idev->lock);
	}
	rcu_read_unlock();
	return onlink;
}

EXPORT_SYMBOL(ipv6_chk_prefix);

struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, struct in6_addr *addr,
				     struct net_device *dev, int strict)
{
+1 −24
Original line number Diff line number Diff line
@@ -48,29 +48,6 @@ static int ipv6_dev_ac_dec(struct net_device *dev, struct in6_addr *addr);
/* Big ac list lock for all the sockets */
static DEFINE_RWLOCK(ipv6_sk_ac_lock);

static int
ip6_onlink(struct in6_addr *addr, struct net_device *dev)
{
	struct inet6_dev	*idev;
	struct inet6_ifaddr	*ifa;
	int	onlink;

	onlink = 0;
	rcu_read_lock();
	idev = __in6_dev_get(dev);
	if (idev) {
		read_lock_bh(&idev->lock);
		for (ifa=idev->addr_list; ifa; ifa=ifa->if_next) {
			onlink = ipv6_prefix_equal(addr, &ifa->addr,
						   ifa->prefix_len);
			if (onlink)
				break;
		}
		read_unlock_bh(&idev->lock);
	}
	rcu_read_unlock();
	return onlink;
}

/*
 *	socket join an anycast group
@@ -142,7 +119,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, struct in6_addr *addr)
	 * This obviates the need for propagating anycast routes while
	 * still allowing some non-router anycast participation.
	 */
	if (!ip6_onlink(addr, dev)) {
	if (!ipv6_chk_prefix(addr, dev)) {
		if (ishost)
			err = -EADDRNOTAVAIL;
		if (err)
+1 −26
Original line number Diff line number Diff line
@@ -344,31 +344,6 @@ ipip6_tunnel_del_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a)
	return 0;
}

/* copied directly from anycast.c */
static int
ipip6_onlink(struct in6_addr *addr, struct net_device *dev)
{
	struct inet6_dev	*idev;
	struct inet6_ifaddr	*ifa;
	int	onlink;

	onlink = 0;
	rcu_read_lock();
	idev = __in6_dev_get(dev);
	if (idev) {
		read_lock_bh(&idev->lock);
		for (ifa=idev->addr_list; ifa; ifa=ifa->if_next) {
			onlink = ipv6_prefix_equal(addr, &ifa->addr,
						   ifa->prefix_len);
			if (onlink)
				break;
		}
		read_unlock_bh(&idev->lock);
	}
	rcu_read_unlock();
	return onlink;
}

static int
isatap_chksrc(struct sk_buff *skb, struct iphdr *iph, struct ip_tunnel *t)
{
@@ -386,7 +361,7 @@ isatap_chksrc(struct sk_buff *skb, struct iphdr *iph, struct ip_tunnel *t)
		struct in6_addr *addr6 = &ipv6_hdr(skb)->saddr;
		if (ipv6_addr_is_isatap(addr6) &&
		    (addr6->s6_addr32[3] == iph->saddr) &&
		    ipip6_onlink(addr6, t->dev))
		    ipv6_chk_prefix(addr6, t->dev))
			skb->ndisc_nodetype = NDISC_NODETYPE_HOST;
		else
			ok = 0;