[ewg] Re: [PATCH] link-local address fix for rdma_resolve_addr
Jason Gunthorpe
jgunthorpe at obsidianresearch.com
Tue Oct 13 16:12:34 PDT 2009
On Tue, Oct 13, 2009 at 03:09:40PM -0700, David J. Wilder wrote:
> Here is a patch to addr6_resolve_remote() to correctly handle link-local address.
> It should cover all the conditions Jason described.
Looks pretty good to me, definitely on the right track.
Hmm..
Actually, upon comparing to tcp_ipv6.c, I'd say one more behavior is
necessary. The code in tcp_ipv6 allows the destination to not specify
a scope id if an interface has already been set. Looks like the two
ways to set an interface ID are to use bind() or SO_BINDTODEVICE..
Specifying a source address to RDMA CM is similar to bind(), so if the
source address is link local it must specify a sin6_scope_id and the
dest address can specify 0, or the same value.
How af_inet6 handles bind():
if (addr_type & IPV6_ADDR_LINKLOCAL) {
if (addr_len >= sizeof(struct sockaddr_in6) &&
addr->sin6_scope_id) {
/* Override any existing binding, if another one
* is supplied by user.
*/
sk->sk_bound_dev_if = addr->sin6_scope_id;
}
/* Binding to link-local address requires an interface */
if (!sk->sk_bound_dev_if) {
err = -EINVAL;
goto out;
}
dev = dev_get_by_index(net, sk->sk_bound_dev_if);
if (!dev) {
err = -ENODEV;
goto out;
}
}
How tcp_ipv6 checks the destination address:
if (addr_type&IPV6_ADDR_LINKLOCAL) {
if (addr_len >= sizeof(struct sockaddr_in6) &&
usin->sin6_scope_id) {
/* If interface is set while binding, indices
* must coincide.
*/
if (sk->sk_bound_dev_if &&
sk->sk_bound_dev_if != usin->sin6_scope_id)
return -EINVAL;
sk->sk_bound_dev_if = usin->sin6_scope_id;
}
/* Connect to link-local address requires an interface */
if (!sk->sk_bound_dev_if)
return -EINVAL;
}
Jason
More information about the ewg
mailing list