]> git.hungrycats.org Git - linux/commitdiff
[IPV6]: Fix inappropriate usage of inet{,6}_sk().
authorHideaki Yoshifuji <yoshfuji@linux-ipv6.org>
Mon, 27 Oct 2003 19:11:07 +0000 (11:11 -0800)
committerHideaki Yoshifuji <yoshfuji@linux-ipv6.org>
Mon, 27 Oct 2003 19:11:07 +0000 (11:11 -0800)
include/net/tcp.h
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_minisocks.c
net/ipv6/addrconf.c

index d4e9c07f86d02b045ee2eefb044108ecf22a228e..2bfe64e2104b3475d29d719b22f0d9169de276c9 100644 (file)
@@ -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)
index 357727193da872d8827e9fdcd04061c5402cfd34..3d115974b3be38a9ec4f734105370624569fd1c6 100644 (file)
@@ -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);
index dda1546a762789a06513d857198135ff2df7401f..01e799c18c1c24669693d215b5dd462c5db828a3 100644 (file)
@@ -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. */
index e1f2593b19f0314f805b72b81fb7b81680f8d63f..63914032a9615f7419b13dbcd7a15259d9dbe191 100644 (file)
@@ -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;