Commit f013d688 authored by Hideaki Yoshifuji's avatar Hideaki Yoshifuji Committed by James Morris

[IPV6] put ipv6_rcv_saddr_equal() common place

parent 5d64e2aa
......@@ -68,6 +68,8 @@ extern int ipv6_dev_get_saddr(struct net_device *dev,
struct in6_addr *saddr,
int onlink);
extern int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *);
extern int ipv6_rcv_saddr_equal(const struct sock *sk,
const struct sock *sk2);
extern void addrconf_join_solict(struct net_device *dev,
struct in6_addr *addr);
extern void addrconf_leave_solict(struct net_device *dev,
......
......@@ -66,6 +66,7 @@
#include <net/ndisc.h>
#include <net/ip6_route.h>
#include <net/addrconf.h>
#include <net/tcp.h>
#include <net/ip.h>
#include <linux/if_tunnel.h>
#include <linux/rtnetlink.h>
......@@ -969,6 +970,43 @@ struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr, struct net_device *
return ifp;
}
int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
{
struct ipv6_pinfo *np = inet6_sk(sk);
int addr_type = ipv6_addr_type(&np->rcv_saddr);
if (!inet_sk(sk2)->rcv_saddr && !ipv6_only_sock(sk))
return 1;
if (sk2->sk_family == AF_INET6 &&
ipv6_addr_any(&inet6_sk(sk2)->rcv_saddr) &&
!(ipv6_only_sock(sk2) && addr_type == IPV6_ADDR_MAPPED))
return 1;
if (addr_type == IPV6_ADDR_ANY &&
(!ipv6_only_sock(sk) ||
!(sk2->sk_family == AF_INET6 ?
(ipv6_addr_type(&inet6_sk(sk2)->rcv_saddr) == IPV6_ADDR_MAPPED) :
1)))
return 1;
if (sk2->sk_family == AF_INET6 &&
!ipv6_addr_cmp(&np->rcv_saddr,
(sk2->sk_state != TCP_TIME_WAIT ?
&inet6_sk(sk2)->rcv_saddr :
&tcptw_sk(sk)->tw_v6_rcv_saddr)))
return 1;
if (addr_type == IPV6_ADDR_MAPPED &&
!ipv6_only_sock(sk2) &&
(!inet_sk(sk2)->rcv_saddr ||
!inet_sk(sk)->rcv_saddr ||
inet_sk(sk)->rcv_saddr == inet_sk(sk2)->rcv_saddr))
return 1;
return 0;
}
/* Gets referenced address, destroys ifaddr */
void addrconf_dad_failure(struct inet6_ifaddr *ifp)
......
......@@ -93,43 +93,6 @@ static __inline__ int tcp_v6_sk_hashfn(struct sock *sk)
return tcp_v6_hashfn(laddr, lport, faddr, fport);
}
static inline int ipv6_rcv_saddr_equal(struct sock *sk, struct sock *sk2)
{
struct ipv6_pinfo *np = inet6_sk(sk);
int addr_type = ipv6_addr_type(&np->rcv_saddr);
if (!inet_sk(sk2)->rcv_saddr && !ipv6_only_sock(sk))
return 1;
if (sk2->sk_family == AF_INET6 &&
ipv6_addr_any(&inet6_sk(sk2)->rcv_saddr) &&
!(ipv6_only_sock(sk2) && addr_type == IPV6_ADDR_MAPPED))
return 1;
if (addr_type == IPV6_ADDR_ANY &&
(!ipv6_only_sock(sk) ||
!(sk2->sk_family == AF_INET6 ?
(ipv6_addr_type(&inet6_sk(sk2)->rcv_saddr) == IPV6_ADDR_MAPPED) :
1)))
return 1;
if (sk2->sk_family == AF_INET6 &&
!ipv6_addr_cmp(&np->rcv_saddr,
(sk2->sk_state != TCP_TIME_WAIT ?
&inet6_sk(sk2)->rcv_saddr :
&((struct tcp_tw_bucket *)sk)->tw_v6_rcv_saddr)))
return 1;
if (addr_type == IPV6_ADDR_MAPPED &&
!ipv6_only_sock(sk2) &&
(!inet_sk(sk2)->rcv_saddr ||
!inet_sk(sk)->rcv_saddr ||
inet_sk(sk)->rcv_saddr == inet_sk(sk2)->rcv_saddr))
return 1;
return 0;
}
static inline int tcp_v6_bind_conflict(struct sock *sk,
struct tcp_bind_bucket *tb)
{
......
......@@ -59,43 +59,6 @@
DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6);
/* XXX This is identical to tcp_ipv6.c:ipv6_rcv_saddr_equal, put
* XXX it somewhere common. -DaveM
*/
static __inline__ int udv6_rcv_saddr_equal(struct sock *sk, struct sock *sk2)
{
struct ipv6_pinfo *np = inet6_sk(sk);
int addr_type = ipv6_addr_type(&np->rcv_saddr);
if (!inet_sk(sk2)->rcv_saddr && !ipv6_only_sock(sk))
return 1;
if (sk2->sk_family == AF_INET6 &&
ipv6_addr_any(&inet6_sk(sk2)->rcv_saddr) &&
!(ipv6_only_sock(sk2) && addr_type == IPV6_ADDR_MAPPED))
return 1;
if (addr_type == IPV6_ADDR_ANY &&
(!ipv6_only_sock(sk) ||
!(sk2->sk_family == AF_INET6 ?
(ipv6_addr_type(&inet6_sk(sk2)->rcv_saddr) == IPV6_ADDR_MAPPED) : 1)))
return 1;
if (sk2->sk_family == AF_INET6 &&
!ipv6_addr_cmp(&inet6_sk(sk)->rcv_saddr,
&inet6_sk(sk2)->rcv_saddr))
return 1;
if (addr_type == IPV6_ADDR_MAPPED &&
!ipv6_only_sock(sk2) &&
(!inet_sk(sk2)->rcv_saddr ||
!inet_sk(sk)->rcv_saddr ||
inet_sk(sk)->rcv_saddr == inet_sk(sk2)->rcv_saddr))
return 1;
return 0;
}
/* Grrr, addr_type already calculated by caller, but I don't want
* to add some silly "cookie" argument to this method just for that.
*/
......@@ -151,7 +114,7 @@ static int udp_v6_get_port(struct sock *sk, unsigned short snum)
sk2 != sk &&
sk2->sk_bound_dev_if == sk->sk_bound_dev_if &&
(!sk2->sk_reuse || !sk->sk_reuse) &&
udv6_rcv_saddr_equal(sk, sk2))
ipv6_rcv_saddr_equal(sk, sk2))
goto fail;
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment