Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 15 Apr 2020 13:06:55 +0000 (UTC)
From:      "Alexander V. Chernikov" <melifaro@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r359966 - head/sys/ofed/drivers/infiniband/core
Message-ID:  <202004151306.03FD6tho020326@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: melifaro
Date: Wed Apr 15 13:06:55 2020
New Revision: 359966
URL: https://svnweb.freebsd.org/changeset/base/359966

Log:
  Convert OFED rtable interactions to the new routing KPI.
  
  Reviewed by:	hselasky
  Differential Revision:	https://reviews.freebsd.org/D24387

Modified:
  head/sys/ofed/drivers/infiniband/core/ib_addr.c
  head/sys/ofed/drivers/infiniband/core/ib_cma.c

Modified: head/sys/ofed/drivers/infiniband/core/ib_addr.c
==============================================================================
--- head/sys/ofed/drivers/infiniband/core/ib_addr.c	Wed Apr 15 13:02:13 2020	(r359965)
+++ head/sys/ofed/drivers/infiniband/core/ib_addr.c	Wed Apr 15 13:06:55 2020	(r359966)
@@ -44,14 +44,17 @@ __FBSDID("$FreeBSD$");
 #include <linux/workqueue.h>
 #include <linux/module.h>
 #include <net/route.h>
+#include <net/route/nhop.h>
 #include <net/netevent.h>
 #include <rdma/ib_addr.h>
 #include <rdma/ib.h>
 
+#include <netinet/in_fib.h>
 #include <netinet/if_ether.h>
 #include <netinet/ip_var.h>
 #include <netinet6/scope6_var.h>
 #include <netinet6/in6_pcb.h>
+#include <netinet6/in6_fib.h>
 
 #include "core_priv.h"
 
@@ -275,11 +278,13 @@ static int addr4_resolve(struct sockaddr_in *src_in,
 	struct sockaddr_in dst_tmp = *dst_in;
 	in_port_t src_port;
 	struct sockaddr *saddr = NULL;
-	struct rtentry *rte;
+	struct nhop_object *nh;
 	struct ifnet *ifp;
 	int error;
 	int type;
 
+	NET_EPOCH_ASSERT();
+
 	/* set VNET, if any */
 	CURVNET_SET(addr->net);
 
@@ -293,8 +298,7 @@ static int addr4_resolve(struct sockaddr_in *src_in,
 		type |= ADDR_DST_ANY;
 
 	/*
-	 * Make sure the socket address length field
-	 * is set, else rtalloc1() will fail.
+	 * Make sure the socket address length field is set.
 	 */
 	dst_tmp.sin_len = sizeof(dst_tmp);
 
@@ -303,16 +307,11 @@ static int addr4_resolve(struct sockaddr_in *src_in,
 	case ADDR_VALID:
 	case ADDR_SRC_ANY:
 		/* regular destination route lookup */
-		rte = rtalloc1((struct sockaddr *)&dst_tmp, 1, 0);
-		if (rte == NULL) {
+		nh = fib4_lookup(RT_DEFAULT_FIB, dst_tmp.sin_addr,0,NHR_NONE,0);
+		if (nh == NULL) {
 			error = EHOSTUNREACH;
 			goto done;
-		} else if (rte->rt_ifp == NULL || RT_LINK_IS_UP(rte->rt_ifp) == 0) {
-			RTFREE_LOCKED(rte);
-			error = EHOSTUNREACH;
-			goto done;
 		}
-		RT_UNLOCK(rte);
 		break;
 	default:
 		error = ENETUNREACH;
@@ -332,14 +331,14 @@ static int addr4_resolve(struct sockaddr_in *src_in,
 		/* check source interface */
 		if (ifp == NULL) {
 			error = ENETUNREACH;
-			goto error_rt_free;
+			goto done;
 		} else if (ifp->if_flags & IFF_LOOPBACK) {
 			/*
 			 * Source address cannot be a loopback device.
 			 */
 			error = EHOSTUNREACH;
 			goto error_put_ifp;
-		} else if (rte->rt_ifp->if_flags & IFF_LOOPBACK) {
+		} else if (nh->nh_ifp->if_flags & IFF_LOOPBACK) {
 			if (memcmp(&src_in->sin_addr, &dst_in->sin_addr,
 			    sizeof(src_in->sin_addr))) {
 				/*
@@ -352,9 +351,9 @@ static int addr4_resolve(struct sockaddr_in *src_in,
 			}
 			/* get destination network interface from route */
 			dev_put(ifp);
-			ifp = rte->rt_ifp;
+			ifp = nh->nh_ifp;
 			dev_hold(ifp);
-		} else if (ifp != rte->rt_ifp) {
+		} else if (ifp != nh->nh_ifp) {
 			/*
 			 * Source and destination interfaces are
 			 * different.
@@ -365,13 +364,13 @@ static int addr4_resolve(struct sockaddr_in *src_in,
 		break;
 	case ADDR_SRC_ANY:
 		/* check for loopback device */
-		if (rte->rt_ifp->if_flags & IFF_LOOPBACK)
+		if (nh->nh_ifp->if_flags & IFF_LOOPBACK)
 			saddr = (struct sockaddr *)&dst_tmp;
 		else
-			saddr = rte->rt_ifa->ifa_addr;
+			saddr = nh->nh_ifa->ifa_addr;
 
 		/* get destination network interface from route */
-		ifp = rte->rt_ifp;
+		ifp = nh->nh_ifp;
 		dev_hold(ifp);
 		break;
 	default:
@@ -386,7 +385,7 @@ static int addr4_resolve(struct sockaddr_in *src_in,
 		    ifp->if_addrlen, MAX_ADDR_LEN);
 		error = 0;
 	} else if (IN_MULTICAST(ntohl(dst_tmp.sin_addr.s_addr))) {
-		bool is_gw = (rte->rt_flags & RTF_GATEWAY) != 0;
+		bool is_gw = (nh->nh_flags & NHF_GATEWAY) != 0;
 		error = addr_resolve_multi(edst, ifp, (struct sockaddr *)&dst_tmp);
 		if (error != 0)
 			goto error_put_ifp;
@@ -396,10 +395,10 @@ static int addr4_resolve(struct sockaddr_in *src_in,
 		memset(edst, 0, MAX_ADDR_LEN);
 		error = 0;
 	} else {
-		bool is_gw = (rte->rt_flags & RTF_GATEWAY) != 0;
+		bool is_gw = (nh->nh_flags & NHF_GATEWAY) != 0;
 		memset(edst, 0, MAX_ADDR_LEN);
 		error = arpresolve(ifp, is_gw, NULL, is_gw ?
-		    rte->rt_gateway : (const struct sockaddr *)&dst_tmp,
+		    &nh->gw_sa : (const struct sockaddr *)&dst_tmp,
 		    edst, NULL, NULL);
 		if (error != 0)
 			goto error_put_ifp;
@@ -416,17 +415,12 @@ static int addr4_resolve(struct sockaddr_in *src_in,
 		src_in->sin_port = src_port;	/* preserve port number */
 	}
 
-	if (rte != NULL)
-		RTFREE(rte);
-
 	*ifpp = ifp;
 
 	goto done;
 
 error_put_ifp:
 	dev_put(ifp);
-error_rt_free:
-	RTFREE(rte);
 done:
 	CURVNET_RESTORE();
 
@@ -460,11 +454,13 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
 	struct sockaddr_in6 dst_tmp = *dst_in;
 	in_port_t src_port;
 	struct sockaddr *saddr = NULL;
-	struct rtentry *rte;
+	struct nhop_object *nh;
 	struct ifnet *ifp;
 	int error;
 	int type;
 
+	NET_EPOCH_ASSERT();
+
 	/* set VNET, if any */
 	CURVNET_SET(addr->net);
 
@@ -478,14 +474,13 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
 		type |= ADDR_DST_ANY;
 
 	/*
-	 * Make sure the socket address length field
-	 * is set, else rtalloc1() will fail.
+	 * Make sure the socket address length field is set.
 	 */
 	dst_tmp.sin6_len = sizeof(dst_tmp);
 
 	/*
-	 * Make sure the scope ID gets embedded, else rtalloc1() will
-	 * resolve to the loopback interface.
+	 * Make sure the scope ID gets embedded, else nd6_resolve() will
+	 * not find the record.
 	 */
 	dst_tmp.sin6_scope_id = addr->bound_dev_if;
 	sa6_embedscope(&dst_tmp, 0);
@@ -502,16 +497,12 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
 		/* FALLTHROUGH */
 	case ADDR_SRC_ANY:
 		/* regular destination route lookup */
-		rte = rtalloc1((struct sockaddr *)&dst_tmp, 1, 0);
-		if (rte == NULL) {
+		nh = fib6_lookup(RT_DEFAULT_FIB, &dst_in->sin6_addr,
+		    addr->bound_dev_if, NHR_NONE, 0);
+		if (nh == NULL) {
 			error = EHOSTUNREACH;
 			goto done;
-		} else if (rte->rt_ifp == NULL || RT_LINK_IS_UP(rte->rt_ifp) == 0) {
-			RTFREE_LOCKED(rte);
-			error = EHOSTUNREACH;
-			goto done;
 		}
-		RT_UNLOCK(rte);
 		break;
 	default:
 		error = ENETUNREACH;
@@ -531,14 +522,14 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
 		/* check source interface */
 		if (ifp == NULL) {
 			error = ENETUNREACH;
-			goto error_rt_free;
+			goto done;
 		} else if (ifp->if_flags & IFF_LOOPBACK) {
 			/*
 			 * Source address cannot be a loopback device.
 			 */
 			error = EHOSTUNREACH;
 			goto error_put_ifp;
-		} else if (rte->rt_ifp->if_flags & IFF_LOOPBACK) {
+		} else if (nh->nh_ifp->if_flags & IFF_LOOPBACK) {
 			if (memcmp(&src_in->sin6_addr, &dst_in->sin6_addr,
 			    sizeof(src_in->sin6_addr))) {
 				/*
@@ -551,9 +542,9 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
 			}
 			/* get destination network interface from route */
 			dev_put(ifp);
-			ifp = rte->rt_ifp;
+			ifp = nh->nh_ifp;
 			dev_hold(ifp);
-		} else if (ifp != rte->rt_ifp) {
+		} else if (ifp != nh->nh_ifp) {
 			/*
 			 * Source and destination interfaces are
 			 * different.
@@ -564,13 +555,13 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
 		break;
 	case ADDR_SRC_ANY:
 		/* check for loopback device */
-		if (rte->rt_ifp->if_flags & IFF_LOOPBACK)
+		if (nh->nh_ifp->if_flags & IFF_LOOPBACK)
 			saddr = (struct sockaddr *)&dst_tmp;
 		else
-			saddr = rte->rt_ifa->ifa_addr;
+			saddr = nh->nh_ifa->ifa_addr;
 
 		/* get destination network interface from route */
-		ifp = rte->rt_ifp;
+		ifp = nh->nh_ifp;
 		dev_hold(ifp);
 		break;
 	default:
@@ -581,21 +572,21 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
 	 * Step 3 - resolve destination MAC address
 	 */
 	if (IN6_IS_ADDR_MULTICAST(&dst_tmp.sin6_addr)) {
-		bool is_gw = (rte->rt_flags & RTF_GATEWAY) != 0;
+		bool is_gw = (nh->nh_flags & NHF_GATEWAY) != 0;
 		error = addr_resolve_multi(edst, ifp,
 		    (struct sockaddr *)&dst_tmp);
 		if (error != 0)
 			goto error_put_ifp;
 		else if (is_gw)
 			addr->network = RDMA_NETWORK_IPV6;
-	} else if (rte->rt_ifp->if_flags & IFF_LOOPBACK) {
+	} else if (nh->nh_ifp->if_flags & IFF_LOOPBACK) {
 		memset(edst, 0, MAX_ADDR_LEN);
 		error = 0;
 	} else {
-		bool is_gw = (rte->rt_flags & RTF_GATEWAY) != 0;
+		bool is_gw = (nh->nh_flags & NHF_GATEWAY) != 0;
 		memset(edst, 0, MAX_ADDR_LEN);
 		error = nd6_resolve(ifp, is_gw, NULL, is_gw ?
-		    rte->rt_gateway : (const struct sockaddr *)&dst_tmp,
+		    &nh->gw_sa : (const struct sockaddr *)&dst_tmp,
 		    edst, NULL, NULL);
 		if (error != 0)
 			goto error_put_ifp;
@@ -612,17 +603,12 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
 		src_in->sin6_port = src_port;	/* preserve port number */
 	}
 
-	if (rte != NULL)
-		RTFREE(rte);
-
 	*ifpp = ifp;
 
 	goto done;
 
 error_put_ifp:
 	dev_put(ifp);
-error_rt_free:
-	RTFREE(rte);
 done:
 	CURVNET_RESTORE();
 

Modified: head/sys/ofed/drivers/infiniband/core/ib_cma.c
==============================================================================
--- head/sys/ofed/drivers/infiniband/core/ib_cma.c	Wed Apr 15 13:02:13 2020	(r359965)
+++ head/sys/ofed/drivers/infiniband/core/ib_cma.c	Wed Apr 15 13:06:55 2020	(r359966)
@@ -50,10 +50,14 @@ __FBSDID("$FreeBSD$");
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <net/route.h>
+#include <net/route/nhop.h>
 
 #include <net/tcp.h>
 #include <net/ipv6.h>
 
+#include <netinet/in_fib.h>
+
+#include <netinet6/in6_fib.h>
 #include <netinet6/scope6_var.h>
 #include <netinet6/ip6_var.h>
 
@@ -1351,11 +1355,10 @@ static bool validate_ipv4_net_dev(struct net_device *n
 				  const struct sockaddr_in *src_addr)
 {
 #ifdef INET
-	struct sockaddr_in src_tmp = *src_addr;
 	__be32 daddr = dst_addr->sin_addr.s_addr,
 	       saddr = src_addr->sin_addr.s_addr;
 	struct net_device *dst_dev;
-	struct rtentry *rte;
+	struct nhop_object *nh;
 	bool ret;
 
 	if (ipv4_is_multicast(saddr) || ipv4_is_lbcast(saddr) ||
@@ -1378,20 +1381,12 @@ static bool validate_ipv4_net_dev(struct net_device *n
 	if (saddr == daddr)
 		return true;
 
-	/*
-	 * Make sure the socket address length field
-	 * is set, else rtalloc1() will fail.
-	 */
-	src_tmp.sin_len = sizeof(src_tmp);
-
 	CURVNET_SET(net_dev->if_vnet);
-	rte = rtalloc1((struct sockaddr *)&src_tmp, 1, 0);
-	if (rte != NULL) {
-		ret = (rte->rt_ifp == net_dev);
-		RTFREE_LOCKED(rte);
-	} else {
+	nh = fib4_lookup(RT_DEFAULT_FIB, src_addr->sin_addr, 0, NHR_NONE, 0);
+	if (nh != NULL)
+		ret = (nh->nh_ifp == net_dev);
+	else
 		ret = false;
-	}
 	CURVNET_RESTORE();
 	return ret;
 #else
@@ -1407,7 +1402,7 @@ static bool validate_ipv6_net_dev(struct net_device *n
 	struct sockaddr_in6 src_tmp = *src_addr;
 	struct sockaddr_in6 dst_tmp = *dst_addr;
 	struct net_device *dst_dev;
-	struct rtentry *rte;
+	struct nhop_object *nh;
 	bool ret;
 
 	dst_dev = ip6_dev_find(net_dev->if_vnet, dst_tmp.sin6_addr,
@@ -1422,15 +1417,8 @@ static bool validate_ipv6_net_dev(struct net_device *n
 	CURVNET_SET(net_dev->if_vnet);
 
 	/*
-	 * Make sure the socket address length field
-	 * is set, else rtalloc1() will fail.
+	 * Make sure the scope ID gets embedded.
 	 */
-	src_tmp.sin6_len = sizeof(src_tmp);
-
-	/*
-	 * Make sure the scope ID gets embedded, else rtalloc1() will
-	 * resolve to the loopback interface.
-	 */
 	src_tmp.sin6_scope_id = net_dev->if_index;
 	sa6_embedscope(&src_tmp, 0);
 
@@ -1446,13 +1434,12 @@ static bool validate_ipv6_net_dev(struct net_device *n
 		ret = true;
 	} else {
 		/* non-loopback case */
-		rte = rtalloc1((struct sockaddr *)&src_tmp, 1, 0);
-		if (rte != NULL) {
-			ret = (rte->rt_ifp == net_dev);
-			RTFREE_LOCKED(rte);
-		} else {
+		nh = fib6_lookup(RT_DEFAULT_FIB, &src_addr->sin6_addr,
+		    net_dev->if_index, NHR_NONE, 0);
+		if (nh != NULL)
+			ret = (nh->nh_ifp == net_dev);
+		else
 			ret = false;
-		}
 	}
 	CURVNET_RESTORE();
 	return ret;
@@ -1512,6 +1499,7 @@ static struct net_device *cma_get_net_dev(struct ib_cm
 			*src_addr = (struct sockaddr *)&src_addr_storage;
 	struct net_device *net_dev;
 	const union ib_gid *gid = req->has_gid ? &req->local_gid : NULL;
+	struct epoch_tracker et;
 	int err;
 
 	err = cma_save_ip_info(listen_addr, src_addr, ib_event,
@@ -1530,10 +1518,13 @@ static struct net_device *cma_get_net_dev(struct ib_cm
 	if (!net_dev)
 		return ERR_PTR(-ENODEV);
 
+	NET_EPOCH_ENTER(et);
 	if (!validate_net_dev(net_dev, listen_addr, src_addr)) {
+		NET_EPOCH_EXIT(et);
 		dev_put(net_dev);
 		return ERR_PTR(-EHOSTUNREACH);
 	}
+	NET_EPOCH_EXIT(et);
 
 	return net_dev;
 }



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