Hi Sasha, > -----Original Message----- > From: Sasha Levin <sashal@xxxxxxxxxx> > Sent: Thursday, May 30, 2019 5:32 AM > To: Parav Pandit <parav@xxxxxxxxxxxx> > Cc: stable-commits@xxxxxxxxxxxxxxx > Subject: Patch "RDMA/cma: Consider scope_id while binding to ipv6 ll address" > has been added to the 4.4-stable tree > > This is a note to let you know that I've just added the patch titled > > RDMA/cma: Consider scope_id while binding to ipv6 ll address > > to the 4.4-stable tree which can be found at: > http://www.kernel.org/git/?p=linux/kernel/git/stable/stable- > queue.git;a=summary > > The filename of the patch is: > rdma-cma-consider-scope_id-while-binding-to-ipv6-ll-.patch > and it can be found in the queue-4.4 subdirectory. > > If you, or anyone else, feels it should not be added to the stable tree, please let > <stable@xxxxxxxxxxxxxxx> know about it. > This patch depends on another patch [1] in same series. However, these two patches only make sense on the kernels which has commit [2]. Patch [2] is not available in 4.4, 4.9 and 4.14 kernels. Therefore, patch in this email should not be applied to 4.4, 4.9 and 4.14 kernel trees. [1] commit 823b23da71132b80d9f41ab667c68b112455f3b6 ("IB/core: Allow vlan link local address based RoCE GIDs") [2] 1060f86534147c2830db4bbc9dd849d1892a611b ("IB/{core/cm}: Fix generating a return AH for RoCEE") > > > commit 33963c60bb63145227c96a9593526841d7f74809 > Author: Parav Pandit <parav@xxxxxxxxxxxx> > Date: Wed Apr 10 11:23:04 2019 +0300 > > RDMA/cma: Consider scope_id while binding to ipv6 ll address > > [ Upstream commit 5d7ed2f27bbd482fd29e6b2e204b1a1ee8a0b268 ] > > When two netdev have same link local addresses (such as vlan and non > vlan), two rdma cm listen id should be able to bind to following different > addresses. > > listener-1: addr=lla, scope_id=A, port=X > listener-2: addr=lla, scope_id=B, port=X > > However while comparing the addresses only addr and port are considered, > due to which 2nd listener fails to listen. > > In below example of two listeners, 2nd listener is failing with address in > use error. > > $ rping -sv -a fe80::268a:7ff:feb3:d113%ens2f1 -p 4545& > > $ rping -sv -a fe80::268a:7ff:feb3:d113%ens2f1.200 -p 4545 > rdma_bind_addr: Address already in use > > To overcome this, consider the scope_ids as well which forms the accurate > IPv6 link local address. > > Signed-off-by: Parav Pandit <parav@xxxxxxxxxxxx> > Reviewed-by: Daniel Jurgens <danielj@xxxxxxxxxxxx> > Signed-off-by: Leon Romanovsky <leonro@xxxxxxxxxxxx> > Signed-off-by: Jason Gunthorpe <jgg@xxxxxxxxxxxx> > Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx> > > diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c > index 1454290078def..76e7eca35a110 100644 > --- a/drivers/infiniband/core/cma.c > +++ b/drivers/infiniband/core/cma.c > @@ -902,18 +902,31 @@ static inline int cma_any_addr(struct sockaddr > *addr) > return cma_zero_addr(addr) || cma_loopback_addr(addr); } > > -static int cma_addr_cmp(struct sockaddr *src, struct sockaddr *dst) > +static int cma_addr_cmp(const struct sockaddr *src, const struct > +sockaddr *dst) > { > if (src->sa_family != dst->sa_family) > return -1; > > switch (src->sa_family) { > case AF_INET: > - return ((struct sockaddr_in *) src)->sin_addr.s_addr != > - ((struct sockaddr_in *) dst)->sin_addr.s_addr; > - case AF_INET6: > - return ipv6_addr_cmp(&((struct sockaddr_in6 *) src)- > >sin6_addr, > - &((struct sockaddr_in6 *) dst)->sin6_addr); > + return ((struct sockaddr_in *)src)->sin_addr.s_addr != > + ((struct sockaddr_in *)dst)->sin_addr.s_addr; > + case AF_INET6: { > + struct sockaddr_in6 *src_addr6 = (struct sockaddr_in6 *)src; > + struct sockaddr_in6 *dst_addr6 = (struct sockaddr_in6 *)dst; > + bool link_local; > + > + if (ipv6_addr_cmp(&src_addr6->sin6_addr, > + &dst_addr6->sin6_addr)) > + return 1; > + link_local = ipv6_addr_type(&dst_addr6->sin6_addr) & > + IPV6_ADDR_LINKLOCAL; > + /* Link local must match their scope_ids */ > + return link_local ? (src_addr6->sin6_scope_id != > + dst_addr6->sin6_scope_id) : > + 0; > + } > + > default: > return ib_addr_cmp(&((struct sockaddr_ib *) src)->sib_addr, > &((struct sockaddr_ib *) dst)->sib_addr);