Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 26 Apr 2020 18:42:38 +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: r360349 - in head/sys: net netinet netinet6
Message-ID:  <202004261842.03QIgcfR088475@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: melifaro
Date: Sun Apr 26 18:42:38 2020
New Revision: 360349
URL: https://svnweb.freebsd.org/changeset/base/360349

Log:
  Convert debugnet to the new routing KPI.
  
  Introduce new fib[46]_lookup_debugnet() functions serving as a
  special interface for the crash-time operations. Underlying
  implementation will try to return lookup result if
  datastructures are not corrupted, avoding locking.
  
  Convert debugnet to use fib4_lookup_debugnet() and switch it
  to use nexthops instead of rtentries.
  
  Reviewed by:	cem
  Differential Revision:	https://reviews.freebsd.org/D24555

Modified:
  head/sys/net/debugnet.c
  head/sys/netinet/in_fib.c
  head/sys/netinet/in_fib.h
  head/sys/netinet6/in6_fib.c
  head/sys/netinet6/in6_fib.h

Modified: head/sys/net/debugnet.c
==============================================================================
--- head/sys/net/debugnet.c	Sun Apr 26 18:07:35 2020	(r360348)
+++ head/sys/net/debugnet.c	Sun Apr 26 18:42:38 2020	(r360349)
@@ -53,8 +53,11 @@ __FBSDID("$FreeBSD$");
 #include <net/if_dl.h>
 #include <net/if_types.h>
 #include <net/if_var.h>
+#include <net/route.h>
+#include <net/route/nhop.h>
 
 #include <netinet/in.h>
+#include <netinet/in_fib.h>
 #include <netinet/in_systm.h>
 #include <netinet/in_var.h>
 #include <netinet/ip.h>
@@ -644,8 +647,8 @@ debugnet_connect(const struct debugnet_conn_params *dc
 	if (pcb->dp_client == INADDR_ANY || pcb->dp_gateway == INADDR_ANY ||
 	    pcb->dp_ifp == NULL) {
 		struct sockaddr_in dest_sin, *gw_sin, *local_sin;
-		struct rtentry *dest_rt;
 		struct ifnet *rt_ifp;
+		struct nhop_object *nh;
 
 		memset(&dest_sin, 0, sizeof(dest_sin));
 		dest_sin = (struct sockaddr_in) {
@@ -655,29 +658,29 @@ debugnet_connect(const struct debugnet_conn_params *dc
 		};
 
 		CURVNET_SET(vnet0);
-		dest_rt = rtalloc1((struct sockaddr *)&dest_sin, 0,
-		    RTF_RNH_LOCKED);
+		nh = fib4_lookup_debugnet(RT_DEFAULT_FIB, dest_sin.sin_addr, 0,
+		    NHR_NONE);
 		CURVNET_RESTORE();
 
-		if (dest_rt == NULL) {
+		if (nh == NULL) {
 			printf("%s: Could not get route for that server.\n",
 			    __func__);
 			error = ENOENT;
 			goto cleanup;
 		}
 
-		if (dest_rt->rt_gateway->sa_family == AF_INET)
-			gw_sin = (struct sockaddr_in *)dest_rt->rt_gateway;
+		if (nh->gw_sa.sa_family == AF_INET)
+			gw_sin = &nh->gw4_sa;
 		else {
-			if (dest_rt->rt_gateway->sa_family == AF_LINK)
+			if (nh->gw_sa.sa_family == AF_LINK)
 				DNETDEBUG("Destination address is on link.\n");
 			gw_sin = NULL;
 		}
 
-		MPASS(dest_rt->rt_ifa->ifa_addr->sa_family == AF_INET);
-		local_sin = (struct sockaddr_in *)dest_rt->rt_ifa->ifa_addr;
+		MPASS(nh->nh_ifa->ifa_addr->sa_family == AF_INET);
+		local_sin = (struct sockaddr_in *)nh->nh_ifa->ifa_addr;
 
-		rt_ifp = dest_rt->rt_ifp;
+		rt_ifp = nh->nh_ifp;
 
 		if (pcb->dp_client == INADDR_ANY)
 			pcb->dp_client = local_sin->sin_addr.s_addr;
@@ -685,8 +688,6 @@ debugnet_connect(const struct debugnet_conn_params *dc
 			pcb->dp_gateway = gw_sin->sin_addr.s_addr;
 		if (pcb->dp_ifp == NULL)
 			pcb->dp_ifp = rt_ifp;
-
-		RTFREE_LOCKED(dest_rt);
 	}
 
 	ifp = pcb->dp_ifp;

Modified: head/sys/netinet/in_fib.c
==============================================================================
--- head/sys/netinet/in_fib.c	Sun Apr 26 18:07:35 2020	(r360348)
+++ head/sys/netinet/in_fib.c	Sun Apr 26 18:42:38 2020	(r360349)
@@ -361,4 +361,46 @@ fib4_check_urpf(uint32_t fibnum, struct in_addr dst, u
 	return (0);
 }
 
+struct nhop_object *
+fib4_lookup_debugnet(uint32_t fibnum, struct in_addr dst, uint32_t scopeid,
+    uint32_t flags)
+{
+	struct rib_head *rh;
+	struct radix_node *rn;
+	struct rtentry *rt;
+	struct nhop_object *nh;
+
+	KASSERT((fibnum < rt_numfibs), ("fib4_lookup_debugnet: bad fibnum"));
+	rh = rt_tables_get_rnh(fibnum, AF_INET);
+	if (rh == NULL)
+		return (NULL);
+
+	/* Prepare lookup key */
+	struct sockaddr_in sin4;
+	memset(&sin4, 0, sizeof(sin4));
+	sin4.sin_family = AF_INET;
+	sin4.sin_len = sizeof(struct sockaddr_in);
+	sin4.sin_addr = dst;
+
+	nh = NULL;
+	/* unlocked lookup */
+	rn = rh->rnh_matchaddr((void *)&sin4, &rh->head);
+	if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) {
+		rt = RNTORT(rn);
+#ifdef RADIX_MPATH
+		if (rt_mpath_next(rt) != NULL)
+			rt = rt_mpath_selectrte(rt, 0);
+#endif
+		nh = rt->rt_nhop;
+		/* Ensure route & ifp is UP */
+		if (RT_LINK_IS_UP(nh->nh_ifp)) {
+			if (flags & NHR_REF)
+				nhop_ref_object(nh);
+			return (nh);
+		}
+	}
+
+	return (NULL);
+}
+
 #endif

Modified: head/sys/netinet/in_fib.h
==============================================================================
--- head/sys/netinet/in_fib.h	Sun Apr 26 18:07:35 2020	(r360348)
+++ head/sys/netinet/in_fib.h	Sun Apr 26 18:42:38 2020	(r360349)
@@ -75,5 +75,7 @@ struct nhop_object *fib4_lookup(uint32_t fibnum, struc
     uint32_t scopeid, uint32_t flags, uint32_t flowid);
 int fib4_check_urpf(uint32_t fibnum, struct in_addr dst, uint32_t scopeid,
     uint32_t flags, const struct ifnet *src_if);
+struct nhop_object *fib4_lookup_debugnet(uint32_t fibnum, struct in_addr dst,
+    uint32_t scopeid, uint32_t flags);
 #endif
 

Modified: head/sys/netinet6/in6_fib.c
==============================================================================
--- head/sys/netinet6/in6_fib.c	Sun Apr 26 18:07:35 2020	(r360348)
+++ head/sys/netinet6/in6_fib.c	Sun Apr 26 18:42:38 2020	(r360349)
@@ -397,5 +397,46 @@ fib6_check_urpf(uint32_t fibnum, const struct in6_addr
 	return (0);
 }
 
+struct nhop_object *
+fib6_lookup_debugnet(uint32_t fibnum, const struct in6_addr *dst6,
+    uint32_t scopeid, uint32_t flags)
+{
+	struct rib_head *rh;
+	struct radix_node *rn;
+	struct rtentry *rt;
+	struct nhop_object *nh;
+	struct sockaddr_in6 sin6;
+
+	KASSERT((fibnum < rt_numfibs), ("fib6_lookup: bad fibnum"));
+	rh = rt_tables_get_rnh(fibnum, AF_INET6);
+	if (rh == NULL)
+		return (NULL);
+
+	/* TODO: radix changes */
+	//addr = *dst6;
+	/* Prepare lookup key */
+	memset(&sin6, 0, sizeof(sin6));
+	sin6.sin6_len = sizeof(struct sockaddr_in6);
+	sin6.sin6_addr = *dst6;
+
+	/* Assume scopeid is valid and embed it directly */
+	if (IN6_IS_SCOPE_LINKLOCAL(dst6))
+		sin6.sin6_addr.s6_addr16[1] = htons(scopeid & 0xffff);
+
+	rn = rh->rnh_matchaddr((void *)&sin6, &rh->head);
+	if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) {
+		rt = RNTORT(rn);
+		nh = rt->rt_nhop;
+		/* Ensure route & ifp is UP */
+		if (RT_LINK_IS_UP(nh->nh_ifp)) {
+			if (flags & NHR_REF)
+				nhop_ref_object(nh);
+			return (nh);
+		}
+	}
+
+	return (NULL);
+}
+
 #endif
 

Modified: head/sys/netinet6/in6_fib.h
==============================================================================
--- head/sys/netinet6/in6_fib.h	Sun Apr 26 18:07:35 2020	(r360348)
+++ head/sys/netinet6/in6_fib.h	Sun Apr 26 18:42:38 2020	(r360349)
@@ -64,5 +64,7 @@ struct nhop_object *fib6_lookup(uint32_t fibnum,
     uint32_t flowid);
 int fib6_check_urpf(uint32_t fibnum, const struct in6_addr *dst6,
     uint32_t scopeid, uint32_t flags, const struct ifnet *src_if);
+struct nhop_object *fib6_lookup_debugnet(uint32_t fibnum,
+    const struct in6_addr *dst6, uint32_t scopeid, uint32_t flags);
 #endif
 



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