On Wed, 2009-10-14 at 13:09 Jason Gunthorpe wrote:

> So, it tries to match the source addr to the addrs bound to the
> device, which is wrong - that isn't how the ip stack works.

> You can patch this up a little bit by fixing up addr_resolve_local to
> set sin6_scope_ip.

I found the bug in addr_resolve_local().  (more comments below)

--- addr.c.1759 2009-10-13 15:57:48.000000000 -0500
+++ addr.c.ip_local     2009-10-15 14:03:50.000000000 -0500
@@ -390,14 +390,17 @@ static int addr_resolve_local(struct soc
        case AF_INET6:
        {
                struct in6_addr *a;
+               int found = 0;
 
                for_each_netdev(&init_net, dev)
                        if (ipv6_chk_addr(&init_net,
                                          &((struct sockaddr_in6 *) 
dst_in)->sin6_addr,
-                                         dev, 1))
+                                         dev, 1)){
+                               found = 1;
                                break;
+                       }
 
-               if (!dev)
+               if (!found)
                        return -EADDRNOTAVAIL;
 
                a = &((struct sockaddr_in6 *) src_in)->sin6_addr;
@@ -406,6 +409,8 @@ static int addr_resolve_local(struct soc
                        src_in->sa_family = dst_in->sa_family;
                        ((struct sockaddr_in6 *) src_in)->sin6_addr =
                                ((struct sockaddr_in6 *) dst_in)->sin6_addr;
+                       ((struct sockaddr_in6 *) src_in)->sin6_scope_id =
+                                ((struct sockaddr_in6 *) 
dst_in)->sin6_scope_id;
                        ret = rdma_copy_addr(addr, dev, dev->dev_addr);
                } else if (ipv6_addr_loopback(a)) {
                        ret = rdma_translate_ip(dst_in, addr);


> But really the correct thing to do is to remove addr_resolve_local and
> place the source address into the struct flowi and use the result of
> the route lookup to bind to the source device, and set the source
> address if it is unset.

Sorry I don't get it..
Are you saying that ip6_route_output() will resolve the address even if
it is a link-local address bound to my own interface? Therefor
addr_resolve_local() is not needed.

--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to