From af2e3380967d2728bf94c2bc915ec6009587f703 Mon Sep 17 00:00:00 2001 From: Hideaki Yoshifuji Date: Mon, 27 Oct 2003 11:11:07 -0800 Subject: [IPV6]: Fix inappropriate usage of inet{,6}_sk(). --- include/net/tcp.h | 33 +++++++++++++++++++++++++++++++++ net/ipv4/tcp_ipv4.c | 6 ------ net/ipv4/tcp_minisocks.c | 5 +++++ net/ipv6/addrconf.c | 37 +++++++++++++++++-------------------- 4 files changed, 55 insertions(+), 26 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index d4e9c07f86d0..2bfe64e2104b 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -219,6 +219,7 @@ struct tcp_tw_bucket { #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) struct in6_addr tw_v6_daddr; struct in6_addr tw_v6_rcv_saddr; + int tw_v6_ipv6only; #endif }; @@ -267,6 +268,38 @@ static __inline__ int tw_del_dead_node(struct tcp_tw_bucket *tw) #define tcptw_sk(__sk) ((struct tcp_tw_bucket *)(__sk)) +static inline const u32 tcp_v4_rcv_saddr(const struct sock *sk) +{ + return likely(sk->sk_state != TCP_TIME_WAIT) ? + inet_sk(sk)->rcv_saddr : tcptw_sk(sk)->tw_rcv_saddr; +} + +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +static inline const struct in6_addr *__tcp_v6_rcv_saddr(const struct sock *sk) +{ + return likely(sk->sk_state != TCP_TIME_WAIT) ? + &inet6_sk(sk)->rcv_saddr : &tcptw_sk(sk)->tw_v6_rcv_saddr; +} + +static inline const struct in6_addr *tcp_v6_rcv_saddr(const struct sock *sk) +{ + return sk->sk_family == AF_INET6 ? __tcp_v6_rcv_saddr(sk) : NULL; +} + +#define tcptw_sk_ipv6only(__sk) (tcptw_sk(__sk)->tw_v6_ipv6only) + +static inline int tcp_v6_ipv6only(const struct sock *sk) +{ + return likely(sk->sk_state != TCP_TIME_WAIT) ? + ipv6_only_sock(sk) : tcptw_sk_ipv6only(sk); +} +#else +# define __tcp_v6_rcv_saddr(__sk) NULL +# define tcp_v6_rcv_saddr(__sk) NULL +# define tcptw_sk_ipv6only(__sk) 0 +# define tcp_v6_ipv6only(__sk) 0 +#endif + extern kmem_cache_t *tcp_timewait_cachep; static inline void tcp_tw_put(struct tcp_tw_bucket *tw) diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 357727193da8..3d115974b3be 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -178,12 +178,6 @@ void tcp_bind_hash(struct sock *sk, struct tcp_bind_bucket *tb, tcp_sk(sk)->bind_hash = tb; } -static inline const u32 tcp_v4_rcv_saddr(const struct sock *sk) -{ - return likely(sk->sk_state != TCP_TIME_WAIT) ? - inet_sk(sk)->rcv_saddr : tcptw_sk(sk)->tw_rcv_saddr; -} - static inline int tcp_bind_conflict(struct sock *sk, struct tcp_bind_bucket *tb) { const u32 sk_rcv_saddr = tcp_v4_rcv_saddr(sk); diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index dda1546a7627..01e799c18c1c 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -368,6 +368,11 @@ void tcp_time_wait(struct sock *sk, int state, int timeo) ipv6_addr_copy(&tw->tw_v6_daddr, &np->daddr); ipv6_addr_copy(&tw->tw_v6_rcv_saddr, &np->rcv_saddr); + tw->tw_v6_ipv6only = np->ipv6only; + } else { + memset(&tw->tw_v6_daddr, 0, sizeof(tw->tw_v6_daddr)); + memset(&tw->tw_v6_rcv_saddr, 0, sizeof(tw->tw_v6_rcv_saddr)); + tw->tw_v6_ipv6only = 0; } #endif /* Linkage updates. */ diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index e1f2593b19f0..63914032a961 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -970,36 +970,33 @@ struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr, struct net_device * 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)) + const struct in6_addr *sk_rcv_saddr6 = &inet6_sk(sk)->rcv_saddr; + const struct in6_addr *sk2_rcv_saddr6 = tcp_v6_rcv_saddr(sk2); + u32 sk_rcv_saddr = inet_sk(sk)->rcv_saddr; + u32 sk2_rcv_saddr = tcp_v4_rcv_saddr(sk2); + int sk_ipv6only = ipv6_only_sock(sk); + int sk2_ipv6only = tcp_v6_ipv6only(sk2); + int addr_type = ipv6_addr_type(sk_rcv_saddr6); + int addr_type2 = sk2_rcv_saddr6 ? ipv6_addr_type(sk2_rcv_saddr6) : IPV6_ADDR_MAPPED; + + if (!sk2_rcv_saddr && !sk_ipv6only) 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)) + if (addr_type2 == IPV6_ADDR_ANY && + !(sk2_ipv6only && 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))) + !(sk_ipv6only && addr_type2 == IPV6_ADDR_MAPPED)) 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(sk2)->tw_v6_rcv_saddr))) + if (sk2_rcv_saddr6 && + !ipv6_addr_cmp(sk_rcv_saddr6, sk2_rcv_saddr6)) 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)) + !sk2_ipv6only && + (!sk2_rcv_saddr || !sk_rcv_saddr || sk_rcv_saddr == sk2_rcv_saddr)) return 1; return 0; -- cgit v1.2.3