Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block
[pandora-kernel.git] / net / ipv6 / inet6_connection_sock.c
index 3516e6f..3a4d92b 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/in6.h>
 #include <linux/ipv6.h>
 #include <linux/jhash.h>
+#include <linux/slab.h>
 
 #include <net/addrconf.h>
 #include <net/inet_connection_sock.h>
@@ -41,11 +42,16 @@ int inet6_csk_bind_conflict(const struct sock *sk,
                if (sk != sk2 &&
                    (!sk->sk_bound_dev_if ||
                     !sk2->sk_bound_dev_if ||
-                    sk->sk_bound_dev_if == sk2->sk_bound_dev_if) &&
-                   (!sk->sk_reuse || !sk2->sk_reuse ||
-                    sk2->sk_state == TCP_LISTEN) &&
-                    ipv6_rcv_saddr_equal(sk, sk2))
-                       break;
+                    sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) {
+                       if ((!sk->sk_reuse || !sk2->sk_reuse ||
+                            sk2->sk_state == TCP_LISTEN) &&
+                            ipv6_rcv_saddr_equal(sk, sk2))
+                               break;
+                       else if (sk->sk_reuse && sk2->sk_reuse &&
+                               !ipv6_addr_any(inet6_rcv_saddr(sk)) &&
+                               ipv6_rcv_saddr_equal(sk, sk2))
+                               break;
+               }
        }
 
        return node != NULL;