• Spencer Baugh's avatar
    RDMA/cma: fix IPv6 address resolution · 6c26a771
    Spencer Baugh authored
    Resolving a link-local IPv6 address with an unspecified source address
    was broken by commit 5462eddd, which prevented the IPv6 stack from
    learning the scope id of the link-local IPv6 address, causing random
    failures as the IP stack chose a random link to resolve the address on.
    
    This commit 5462eddd made us bail out of cma_check_linklocal early if
    the address passed in was not an IPv6 link-local address. On the address
    resolution path, the address passed in is the source address; if the
    source address is the unspecified address, which is not link-local, we
    will bail out early.
    
    This is mostly correct, but if the destination address is a link-local
    address, then we will be following a link-local route, and we'll need to
    tell the IPv6 stack what the scope id of the destination address is.
    This used to be done by last line of cma_check_linklocal, which is
    skipped when bailing out early:
    
    	dev_addr->bound_dev_if = sin6->sin6_scope_id;
    
    (In cma_bind_addr, the sin6_scope_id of the source address is set to the
    sin6_scope_id of the destination address, so this is correct)
    This line is required in turn for the following line, L279 of
    addr6_resolve, to actually inform the IPv6 stack of the scope id:
    
          fl6.flowi6_oif = addr->bound_dev_if;
    
    Since we can only know we are in this failure case when we have access
    to both the source IPv6 address and destination IPv6 address, we have to
    deal with this further up the stack. So detect this failure case in
    cma_bind_addr, and set bound_dev_if to the destination address scope id
    to correct it.
    Signed-off-by: default avatarSpencer Baugh <sbaugh@catern.com>
    Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
    6c26a771
cma.c 93.5 KB