Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 26 Dec 2020 11:31:19 GMT
From:      "Alexander V. Chernikov" <melifaro@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 4e19e0d92ac6 - Use light-weight versions of routing lookup functions in ng_netflow.
Message-ID:  <202012261131.0BQBVJJN000626@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by melifaro:

URL: https://cgit.FreeBSD.org/src/commit/?id=4e19e0d92ac6dfa5d2df6d525922f1e60487a9cc

commit 4e19e0d92ac6dfa5d2df6d525922f1e60487a9cc
Author:     Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2020-12-26 11:07:30 +0000
Commit:     Alexander V. Chernikov <melifaro@FreeBSD.org>
CommitDate: 2020-12-26 11:27:38 +0000

    Use light-weight versions of routing lookup functions in ng_netflow.
    
    Use recently-added combination of `fib[46]_lookup_rt()` which
     returns rtentry & raw nexthop with `rt_get_inet[6]_plen()` which
     returns address/prefix length of prefix inside `rt`.
    
    Add `nhop_select_func()` wrapper around inlined `nhop_select()` to
     allow callers external to the routing subsystem select the proper
     nexthop from the multipath group without including internal headers.
    
    New calls does not require reference counting objects and reduce
     the amount of copied/processed rtentry data.
    
    Differential Revision: https://reviews.freebsd.org/D27675
---
 sys/net/route/nhop.h              |   1 +
 sys/net/route/nhop_ctl.c          |   7 ++
 sys/netgraph/netflow/netflow.c    | 164 +++++++++++++++-----------------------
 sys/netgraph/netflow/ng_netflow.c |  17 +++-
 4 files changed, 86 insertions(+), 103 deletions(-)

diff --git a/sys/net/route/nhop.h b/sys/net/route/nhop.h
index 3944d8946b07..8b5ac7ada072 100644
--- a/sys/net/route/nhop.h
+++ b/sys/net/route/nhop.h
@@ -181,6 +181,7 @@ uint32_t nhop_get_idx(const struct nhop_object *nh);
 enum nhop_type nhop_get_type(const struct nhop_object *nh);
 int nhop_get_rtflags(const struct nhop_object *nh);
 struct vnet *nhop_get_vnet(const struct nhop_object *nh);
+struct nhop_object *nhop_select_func(struct nhop_object *nh, uint32_t flowid);
 
 #endif /* _KERNEL */
 
diff --git a/sys/net/route/nhop_ctl.c b/sys/net/route/nhop_ctl.c
index 2b676663a782..542380afd64b 100644
--- a/sys/net/route/nhop_ctl.c
+++ b/sys/net/route/nhop_ctl.c
@@ -761,6 +761,13 @@ nhop_get_vnet(const struct nhop_object *nh)
 	return (nh->nh_priv->nh_vnet);
 }
 
+struct nhop_object *
+nhop_select_func(struct nhop_object *nh, uint32_t flowid)
+{
+
+	return (nhop_select(nh, flowid));
+}
+
 void
 nhops_update_ifmtu(struct rib_head *rh, struct ifnet *ifp, uint32_t mtu)
 {
diff --git a/sys/netgraph/netflow/netflow.c b/sys/netgraph/netflow/netflow.c
index 8e1bcddd6895..e9fb83773a4b 100644
--- a/sys/netgraph/netflow/netflow.c
+++ b/sys/netgraph/netflow/netflow.c
@@ -33,6 +33,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include "opt_inet.h"
 #include "opt_inet6.h"
 #include "opt_route.h"
 #include <sys/param.h>
@@ -51,14 +52,19 @@ __FBSDID("$FreeBSD$");
 #include <net/if_dl.h>
 #include <net/if_var.h>
 #include <net/route.h>
+#include <net/route/nhop.h>
+#include <net/route/route_ctl.h>
 #include <net/ethernet.h>
 #include <netinet/in.h>
+#include <netinet/in_fib.h>
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
 #include <netinet/ip6.h>
 #include <netinet/tcp.h>
 #include <netinet/udp.h>
 
+#include <netinet6/in6_fib.h>
+
 #include <netgraph/ng_message.h>
 #include <netgraph/netgraph.h>
 
@@ -100,8 +106,10 @@ MALLOC_DEFINE(M_NETFLOW_HASH, "netflow_hash", "NetFlow hash");
 static int export_add(item_p, struct flow_entry *);
 static int export_send(priv_p, fib_export_p, item_p, int);
 
+#ifdef INET
 static int hash_insert(priv_p, struct flow_hash_entry *, struct flow_rec *,
     int, uint8_t, uint8_t);
+#endif
 #ifdef INET6
 static int hash6_insert(priv_p, struct flow_hash_entry *, struct flow6_rec *,
     int, uint8_t, uint8_t);
@@ -151,18 +159,6 @@ ip6_hash(struct flow6_rec *r)
  	}
 }
 
-static inline int
-ip6_masklen(struct in6_addr *saddr, struct rt_addrinfo *info)
-{
-	const int nbits = sizeof(*saddr) * NBBY;
-	int mlen;
-
-	if (info->rti_addrs & RTA_NETMASK)
-		bit_count((bitstr_t *)saddr, 0, nbits, &mlen);
-	else
-		mlen = nbits;
-	return (mlen);
-}
 #endif
 
 /*
@@ -320,14 +316,12 @@ ng_netflow_copyinfo(priv_p priv, struct ng_netflow_info *i)
  * as this was done in previous version. Need to test & profile
  * to be sure.
  */
+#ifdef INET
 static int
 hash_insert(priv_p priv, struct flow_hash_entry *hsh, struct flow_rec *r,
 	int plen, uint8_t flags, uint8_t tcp_flags)
 {
 	struct flow_entry *fle;
-	struct sockaddr_in sin, sin_mask;
-	struct sockaddr_dl rt_gateway;
-	struct rt_addrinfo info;
 
 	mtx_assert(&hsh->mtx, MA_OWNED);
 
@@ -354,57 +348,37 @@ hash_insert(priv_p priv, struct flow_hash_entry *hsh, struct flow_rec *r,
 	 * fill in out_ifx, dst_mask, nexthop, and dst_as in future releases.
 	 */
 	if ((flags & NG_NETFLOW_CONF_NODSTLOOKUP) == 0) {
-		bzero(&sin, sizeof(sin));
-		sin.sin_len = sizeof(struct sockaddr_in);
-		sin.sin_family = AF_INET;
-		sin.sin_addr = fle->f.r.r_dst;
-
-		rt_gateway.sdl_len = sizeof(rt_gateway);
-		sin_mask.sin_len = sizeof(struct sockaddr_in);
-		bzero(&info, sizeof(info));
-
-		info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&rt_gateway;
-		info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&sin_mask;
-
-		if (rib_lookup_info(r->fib, (struct sockaddr *)&sin, NHR_REF, 0,
-		    &info) == 0) {
-			fle->f.fle_o_ifx = info.rti_ifp->if_index;
-
-			if (info.rti_flags & RTF_GATEWAY &&
-			    rt_gateway.sdl_family == AF_INET)
-				fle->f.next_hop =
-				    ((struct sockaddr_in *)&rt_gateway)->sin_addr;
-
-			if (info.rti_addrs & RTA_NETMASK)
-				fle->f.dst_mask = bitcount32(sin_mask.sin_addr.s_addr);
-			else if (info.rti_flags & RTF_HOST)
-				/* Give up. We can't determine mask :( */
-				fle->f.dst_mask = 32;
-
-			rib_free_info(&info);
+		struct rtentry *rt;
+		struct route_nhop_data rnd;
+
+		rt = fib4_lookup_rt(r->fib, fle->f.r.r_dst, 0, NHR_NONE, &rnd);
+		if (rt != NULL) {
+			struct in_addr addr;
+			uint32_t scopeid;
+			struct nhop_object *nh = nhop_select_func(rnd.rnd_nhop, 0);
+			int plen;
+
+			rt_get_inet_prefix_plen(rt, &addr, &plen, &scopeid);
+			fle->f.fle_o_ifx = nh->nh_ifp->if_index;
+			if (nh->gw_sa.sa_len == AF_INET)
+				fle->f.next_hop = nh->gw4_sa.sin_addr;
+			fle->f.dst_mask = plen;
 		}
 	}
 
 	/* Do route lookup on source address, to fill in src_mask. */
 	if ((flags & NG_NETFLOW_CONF_NOSRCLOOKUP) == 0) {
-		bzero(&sin, sizeof(sin));
-		sin.sin_len = sizeof(struct sockaddr_in);
-		sin.sin_family = AF_INET;
-		sin.sin_addr = fle->f.r.r_src;
-
-		sin_mask.sin_len = sizeof(struct sockaddr_in);
-		bzero(&info, sizeof(info));
-
-		info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&sin_mask;
-
-		if (rib_lookup_info(r->fib, (struct sockaddr *)&sin, 0, 0,
-		    &info) == 0) {
-			if (info.rti_addrs & RTA_NETMASK)
-				fle->f.src_mask =
-				    bitcount32(sin_mask.sin_addr.s_addr);
-			else if (info.rti_flags & RTF_HOST)
-				/* Give up. We can't determine mask :( */
-				fle->f.src_mask = 32;
+		struct rtentry *rt;
+		struct route_nhop_data rnd;
+
+		rt = fib4_lookup_rt(r->fib, fle->f.r.r_src, 0, NHR_NONE, &rnd);
+		if (rt != NULL) {
+			struct in_addr addr;
+			uint32_t scopeid;
+			int plen;
+
+			rt_get_inet_prefix_plen(rt, &addr, &plen, &scopeid);
+			fle->f.src_mask = plen;
 		}
 	}
 
@@ -413,6 +387,7 @@ hash_insert(priv_p priv, struct flow_hash_entry *hsh, struct flow_rec *r,
 
 	return (0);
 }
+#endif
 
 #ifdef INET6
 static int
@@ -420,9 +395,6 @@ hash6_insert(priv_p priv, struct flow_hash_entry *hsh6, struct flow6_rec *r,
 	int plen, uint8_t flags, uint8_t tcp_flags)
 {
 	struct flow6_entry *fle6;
-	struct sockaddr_in6 sin6, sin6_mask;
-	struct sockaddr_dl rt_gateway;
-	struct rt_addrinfo info;
 
 	mtx_assert(&hsh6->mtx, MA_OWNED);
 
@@ -450,50 +422,38 @@ hash6_insert(priv_p priv, struct flow_hash_entry *hsh6, struct flow6_rec *r,
 	 * fill in out_ifx, dst_mask, nexthop, and dst_as in future releases.
 	 */
 	if ((flags & NG_NETFLOW_CONF_NODSTLOOKUP) == 0) {
-		bzero(&sin6, sizeof(struct sockaddr_in6));
-		sin6.sin6_len = sizeof(struct sockaddr_in6);
-		sin6.sin6_family = AF_INET6;
-		sin6.sin6_addr = r->dst.r_dst6;
-
-		rt_gateway.sdl_len = sizeof(rt_gateway);
-		sin6_mask.sin6_len = sizeof(struct sockaddr_in6);
-		bzero(&info, sizeof(info));
-
-		info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&rt_gateway;
-		info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&sin6_mask;
-
-		if (rib_lookup_info(r->fib, (struct sockaddr *)&sin6, NHR_REF,
-		    0, &info) == 0) {
-			fle6->f.fle_o_ifx = info.rti_ifp->if_index;
-
-			if (info.rti_flags & RTF_GATEWAY &&
-			    rt_gateway.sdl_family == AF_INET6)
-				fle6->f.n.next_hop6 =
-				    ((struct sockaddr_in6 *)&rt_gateway)->sin6_addr;
-
-			fle6->f.dst_mask =
-			    ip6_masklen(&sin6_mask.sin6_addr, &info);
-
-			rib_free_info(&info);
+		struct rtentry *rt;
+		struct route_nhop_data rnd;
+
+		rt = fib6_lookup_rt(r->fib, &fle6->f.r.dst.r_dst6, 0, NHR_NONE, &rnd);
+		if (rt != NULL) {
+			struct in6_addr addr;
+			uint32_t scopeid;
+			struct nhop_object *nh = nhop_select_func(rnd.rnd_nhop, 0);
+			int plen;
+
+			rt_get_inet6_prefix_plen(rt, &addr, &plen, &scopeid);
+			fle6->f.fle_o_ifx = nh->nh_ifp->if_index;
+			if (nh->gw_sa.sa_len == AF_INET6)
+				fle6->f.n.next_hop6 = nh->gw6_sa.sin6_addr;
+			fle6->f.dst_mask = plen;
 		}
 	}
 
 	if ((flags & NG_NETFLOW_CONF_NOSRCLOOKUP) == 0) {
 		/* Do route lookup on source address, to fill in src_mask. */
-		bzero(&sin6, sizeof(struct sockaddr_in6));
-		sin6.sin6_len = sizeof(struct sockaddr_in6);
-		sin6.sin6_family = AF_INET6;
-		sin6.sin6_addr = r->src.r_src6;
-
-		sin6_mask.sin6_len = sizeof(struct sockaddr_in6);
-		bzero(&info, sizeof(info));
+		struct rtentry *rt;
+		struct route_nhop_data rnd;
 
-		info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&sin6_mask;
+		rt = fib6_lookup_rt(r->fib, &fle6->f.r.src.r_src6, 0, NHR_NONE, &rnd);
+		if (rt != NULL) {
+			struct in6_addr addr;
+			uint32_t scopeid;
+			int plen;
 
-		if (rib_lookup_info(r->fib, (struct sockaddr *)&sin6, 0, 0,
-		    &info) == 0)
-			fle6->f.src_mask =
-			    ip6_masklen(&sin6_mask.sin6_addr, &info);
+			rt_get_inet6_prefix_plen(rt, &addr, &plen, &scopeid);
+			fle6->f.src_mask = plen;
+		}
 	}
 
 	/* Push new flow at the and of hash. */
@@ -682,6 +642,7 @@ ng_netflow_cache_flush(priv_p priv)
 	ng_netflow_v9_cache_flush(priv);
 }
 
+#ifdef INET
 /* Insert packet from into flow cache. */
 int
 ng_netflow_flow_add(priv_p priv, fib_export_p fe, struct ip *ip,
@@ -808,6 +769,7 @@ ng_netflow_flow_add(priv_p priv, fib_export_p fe, struct ip *ip,
 
 	return (error);
 }
+#endif
 
 #ifdef INET6
 /* Insert IPv6 packet from into flow cache. */
diff --git a/sys/netgraph/netflow/ng_netflow.c b/sys/netgraph/netflow/ng_netflow.c
index 6180fe573b60..187e18a3130e 100644
--- a/sys/netgraph/netflow/ng_netflow.c
+++ b/sys/netgraph/netflow/ng_netflow.c
@@ -33,6 +33,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include "opt_inet.h"
 #include "opt_inet6.h"
 #include "opt_route.h"
 
@@ -700,12 +701,14 @@ ng_netflow_rcvdata (hook_p hook, item_p item)
 		/* Make sure this is IP frame. */
 		etype = ntohs(eh->ether_type);
 		switch (etype) {
+#ifdef INET
 		case ETHERTYPE_IP:
 			M_CHECK(sizeof(struct ip));
 			eh = mtod(m, struct ether_header *);
 			ip = (struct ip *)(eh + 1);
 			l3_off = sizeof(struct ether_header);
 			break;
+#endif
 #ifdef INET6
 		case ETHERTYPE_IPV6:
 			/*
@@ -730,9 +733,11 @@ ng_netflow_rcvdata (hook_p hook, item_p item)
 			l3_off = sizeof(struct ether_vlan_header);
 
 			if (etype == ETHERTYPE_IP) {
+#ifdef INET
 				M_CHECK(sizeof(struct ip));
 				ip = (struct ip *)(evh + 1);
 				break;
+#endif
 #ifdef INET6
 			} else if (etype == ETHERTYPE_IPV6) {
 				M_CHECK(sizeof(struct ip6_hdr));
@@ -760,6 +765,9 @@ ng_netflow_rcvdata (hook_p hook, item_p item)
 			M_CHECK(sizeof(struct ip6_hdr) - sizeof(struct ip));
 			ip6 = mtod(m, struct ip6_hdr *);
 		}
+#endif
+#ifndef INET
+		ip = NULL;
 #endif
 		break;
 	default:
@@ -935,11 +943,16 @@ loopend:
 		fe = priv_to_fib(priv, fib);
 	}
 
+#ifdef INET
 	if (ip != NULL)
 		error = ng_netflow_flow_add(priv, fe, ip, upper_ptr,
 		    upper_proto, flags, src_if_index);
-#ifdef INET6		
-	else if (ip6 != NULL)
+#endif
+#if defined(INET6) && defined(INET)
+	else
+#endif
+#ifdef INET6
+	if (ip6 != NULL)
 		error = ng_netflow_flow6_add(priv, fe, ip6, upper_ptr,
 		    upper_proto, flags, src_if_index);
 #endif



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