Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 12 Dec 2018 10:56:54 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r341874 - stable/11/sys/ofed/drivers/infiniband/core
Message-ID:  <201812121056.wBCAusvA029780@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Wed Dec 12 10:56:53 2018
New Revision: 341874
URL: https://svnweb.freebsd.org/changeset/base/341874

Log:
  MFC r341530:
  ibcore: Fix loopback with rdma-cm.
  
  Trying to validate loopback fails because rtalloc1() resolves system
  local addresses to the loopback network interface, lo0. Fix this by
  explicitly checking for loopback during validation of the source
  and destination network address. If the source address belongs to
  a local network interface and is equal to the destination address,
  there is no need to run the destination address through rtalloc1().
  
  Sponsored by:   Mellanox Technologies

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

Modified: stable/11/sys/ofed/drivers/infiniband/core/ib_cma.c
==============================================================================
--- stable/11/sys/ofed/drivers/infiniband/core/ib_cma.c	Wed Dec 12 10:55:55 2018	(r341873)
+++ stable/11/sys/ofed/drivers/infiniband/core/ib_cma.c	Wed Dec 12 10:56:53 2018	(r341874)
@@ -1292,6 +1292,12 @@ static bool validate_ipv4_net_dev(struct net_device *n
 	dev_put(dst_dev);
 
 	/*
+	 * Check for loopback.
+	 */
+	if (saddr == daddr)
+		return true;
+
+	/*
 	 * Make sure the socket address length field
 	 * is set, else rtalloc1() will fail.
 	 */
@@ -1318,12 +1324,12 @@ static bool validate_ipv6_net_dev(struct net_device *n
 {
 #ifdef INET6
 	struct sockaddr_in6 src_tmp = *src_addr;
-	struct in6_addr in6_addr = dst_addr->sin6_addr;
+	struct sockaddr_in6 dst_tmp = *dst_addr;
 	struct net_device *dst_dev;
 	struct rtentry *rte;
 	bool ret;
 
-	dst_dev = ip6_dev_find(net_dev->if_vnet, in6_addr);
+	dst_dev = ip6_dev_find(net_dev->if_vnet, dst_tmp.sin6_addr);
 	if (dst_dev != net_dev) {
 		if (dst_dev != NULL)
 			dev_put(dst_dev);
@@ -1345,12 +1351,25 @@ static bool validate_ipv6_net_dev(struct net_device *n
 	src_tmp.sin6_scope_id = net_dev->if_index;
 	sa6_embedscope(&src_tmp, 0);
 
-	rte = rtalloc1((struct sockaddr *)&src_tmp, 1, 0);
-	if (rte != NULL) {
-		ret = (rte->rt_ifp == net_dev);
-		RTFREE_LOCKED(rte);
+	dst_tmp.sin6_scope_id = net_dev->if_index;
+	sa6_embedscope(&dst_tmp, 0);
+
+	/*
+	 * Check for loopback after scope ID
+	 * has been embedded:
+	 */
+	if (memcmp(&src_tmp.sin6_addr, &dst_tmp.sin6_addr,
+	    sizeof(dst_tmp.sin6_addr)) == 0) {
+		ret = true;
 	} else {
-		ret = false;
+		/* non-loopback case */
+		rte = rtalloc1((struct sockaddr *)&src_tmp, 1, 0);
+		if (rte != NULL) {
+			ret = (rte->rt_ifp == net_dev);
+			RTFREE_LOCKED(rte);
+		} else {
+			ret = false;
+		}
 	}
 	CURVNET_RESTORE();
 	return ret;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201812121056.wBCAusvA029780>