Author: hselasky
Date: Fri Nov 17 15:46:45 2017
New Revision: 325943
URL: https://svnweb.freebsd.org/changeset/base/325943

Log:
  MFC r325615:
  Make sure the IPv6 scope ID gets zeroed when exchanging CMA messages in 
ibcore.
  Else the IPv6 address matching might fail. This change adds support for both
  embedded and non-embedded IPv6 scope IDs when passing a IPv6 link-local socket
  address to RDMA. Prior to this change only global IPv6 addresses would work
  with RDMA.
  
  Sponsored by: Mellanox Technologies

Modified:
  stable/10/sys/ofed/drivers/infiniband/core/cma.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/ofed/drivers/infiniband/core/cma.c
==============================================================================
--- stable/10/sys/ofed/drivers/infiniband/core/cma.c    Fri Nov 17 15:46:19 
2017        (r325942)
+++ stable/10/sys/ofed/drivers/infiniband/core/cma.c    Fri Nov 17 15:46:45 
2017        (r325943)
@@ -840,6 +840,17 @@ static int cma_get_net_info(void *hdr, enum rdma_port_
        return 0;
 }
 
+static void cma_ip6_clear_scope_id(struct in6_addr *addr)
+{
+       /* make sure link local scope ID gets zeroed */
+       if (IN6_IS_SCOPE_LINKLOCAL(addr) ||
+           IN6_IS_ADDR_MC_INTFACELOCAL(addr)) {
+               /* use byte-access to be alignment safe */
+               addr->s6_addr[2] = 0;
+               addr->s6_addr[3] = 0;
+       }
+}
+
 static void cma_save_net_info(struct rdma_addr *addr,
                              struct rdma_addr *listen_addr,
                              u8 ip_ver, __be16 port,
@@ -871,6 +882,7 @@ static void cma_save_net_info(struct rdma_addr *addr,
                ip6->sin6_port = listen6->sin6_port;
                ip6->sin6_len = sizeof(struct sockaddr_in6);
                ip6->sin6_scope_id = listen6->sin6_scope_id;
+               cma_ip6_clear_scope_id(&ip6->sin6_addr);
 
                ip6 = (struct sockaddr_in6 *) &addr->dst_addr;
                ip6->sin6_family = listen6->sin6_family;
@@ -878,6 +890,7 @@ static void cma_save_net_info(struct rdma_addr *addr,
                ip6->sin6_port = port;
                ip6->sin6_len = sizeof(struct sockaddr_in6);
                ip6->sin6_scope_id = listen6->sin6_scope_id;
+               cma_ip6_clear_scope_id(&ip6->sin6_addr);
                break;
        default:
                break;
@@ -1370,6 +1383,7 @@ static void cma_set_compare_data(enum rdma_port_space 
 #ifdef INET6
        case AF_INET6:
                ip6_addr = ((struct sockaddr_in6 *) addr)->sin6_addr;
+               cma_ip6_clear_scope_id(&ip6_addr);
                if (ps == RDMA_PS_SDP) {
                        sdp_set_ip_ver(sdp_data, 6);
                        sdp_set_ip_ver(sdp_mask, 0xF);
@@ -2563,6 +2577,8 @@ static int cma_format_hdr(void *hdr, enum rdma_port_sp
                        cma_hdr->src_addr.ip6 = src6->sin6_addr;
                        cma_hdr->dst_addr.ip6 = dst6->sin6_addr;
                        cma_hdr->port = src6->sin6_port;
+                       cma_ip6_clear_scope_id(&cma_hdr->src_addr.ip6);
+                       cma_ip6_clear_scope_id(&cma_hdr->dst_addr.ip6);
                        break;
                }
        }
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to