Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 2 Jul 2020 21:04:09 +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: r362900 - in head/sys: net netinet netinet6 netpfil/ipfw netpfil/ipfw/nat64
Message-ID:  <202007022104.062L49Oo089298@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: melifaro
Date: Thu Jul  2 21:04:08 2020
New Revision: 362900
URL: https://svnweb.freebsd.org/changeset/base/362900

Log:
  Complete conversions from fib<4|6>_lookup_nh_<basic|ext> to fib<4|6>_lookup().
  
  fib[46]_lookup_nh_ represents pre-epoch generation of fib api, providing less guarantees
   over pointer validness and requiring on-stack data copying.
  
  With no callers remaining, remove fib[46]_lookup_nh_ functions.
  
  Submitted by:	Neel Chauhan <neel AT neelc DOT org>
  Differential Revision:	https://reviews.freebsd.org/D25445

Modified:
  head/sys/net/if_stf.c
  head/sys/netinet/if_ether.c
  head/sys/netinet/in_fib.c
  head/sys/netinet/in_fib.h
  head/sys/netinet/in_mcast.c
  head/sys/netinet/ip_options.c
  head/sys/netinet6/icmp6.c
  head/sys/netinet6/in6.c
  head/sys/netinet6/in6_fib.c
  head/sys/netinet6/in6_fib.h
  head/sys/netinet6/in6_mcast.c
  head/sys/netinet6/in6_src.c
  head/sys/netpfil/ipfw/ip_fw2.c
  head/sys/netpfil/ipfw/ip_fw_table_algo.c
  head/sys/netpfil/ipfw/nat64/nat64_translate.c

Modified: head/sys/net/if_stf.c
==============================================================================
--- head/sys/net/if_stf.c	Thu Jul  2 18:42:43 2020	(r362899)
+++ head/sys/net/if_stf.c	Thu Jul  2 21:04:08 2020	(r362900)
@@ -97,6 +97,7 @@
 #include <net/if_var.h>
 #include <net/if_clone.h>
 #include <net/route.h>
+#include <net/route/nhop.h>
 #include <net/netisr.h>
 #include <net/if_types.h>
 #include <net/vnet.h>
@@ -568,12 +569,14 @@ stf_checkaddr4(struct stf_softc *sc, struct in_addr *i
 	 * perform ingress filter
 	 */
 	if (sc && (STF2IFP(sc)->if_flags & IFF_LINK2) == 0 && inifp) {
-		struct nhop4_basic nh4;
+		struct nhop_object *nh;
 
-		if (fib4_lookup_nh_basic(sc->sc_fibnum, *in, 0, 0, &nh4) != 0)
+		NET_EPOCH_ASSERT();
+		nh = fib4_lookup(sc->sc_fibnum, *in, 0, 0, 0);
+		if (nh == NULL)
 			return (-1);
 
-		if (nh4.nh_ifp != inifp)
+		if (nh->nh_ifp != inifp)
 			return (-1);
 	}
 

Modified: head/sys/netinet/if_ether.c
==============================================================================
--- head/sys/netinet/if_ether.c	Thu Jul  2 18:42:43 2020	(r362899)
+++ head/sys/netinet/if_ether.c	Thu Jul  2 21:04:08 2020	(r362900)
@@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$");
 #include <net/netisr.h>
 #include <net/ethernet.h>
 #include <net/route.h>
+#include <net/route/nhop.h>
 #include <net/vnet.h>
 
 #include <netinet/in.h>
@@ -804,7 +805,7 @@ in_arpinput(struct mbuf *m)
 	int carped;
 	struct sockaddr_in sin;
 	struct sockaddr *dst;
-	struct nhop4_basic nh4;
+	struct nhop_object *nh;
 	uint8_t linkhdr[LLE_MAX_LINKHDR];
 	struct route ro;
 	size_t linkhdrsize;
@@ -1065,8 +1066,9 @@ reply:
 			if (!V_arp_proxyall)
 				goto drop;
 
-			if (fib4_lookup_nh_basic(ifp->if_fib, itaddr, 0, 0,
-			    &nh4) != 0)
+			NET_EPOCH_ASSERT();
+			nh = fib4_lookup(ifp->if_fib, itaddr, 0, 0, 0);
+			if (nh == NULL)
 				goto drop;
 
 			/*
@@ -1074,7 +1076,7 @@ reply:
 			 * as this one came out of, or we'll get into a fight
 			 * over who claims what Ether address.
 			 */
-			if (nh4.nh_ifp == ifp)
+			if (nh->nh_ifp == ifp)
 				goto drop;
 
 			(void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);
@@ -1087,10 +1089,10 @@ reply:
 			 * wrong network.
 			 */
 
-			if (fib4_lookup_nh_basic(ifp->if_fib, isaddr, 0, 0,
-			    &nh4) != 0)
+			nh = fib4_lookup(ifp->if_fib, isaddr, 0, 0, 0);
+			if (nh == NULL)
 				goto drop;
-			if (nh4.nh_ifp != ifp) {
+			if (nh->nh_ifp != ifp) {
 				ARP_LOG(LOG_INFO, "proxy: ignoring request"
 				    " from %s via %s\n",
 				    inet_ntoa_r(isaddr, addrbuf),

Modified: head/sys/netinet/in_fib.c
==============================================================================
--- head/sys/netinet/in_fib.c	Thu Jul  2 18:42:43 2020	(r362899)
+++ head/sys/netinet/in_fib.c	Thu Jul  2 21:04:08 2020	(r362900)
@@ -66,165 +66,6 @@ __FBSDID("$FreeBSD$");
 /* Verify struct route compatiblity */
 /* Assert 'struct route_in' is compatible with 'struct route' */
 CHK_STRUCT_ROUTE_COMPAT(struct route_in, ro_dst4);
-static void fib4_rte_to_nh_basic(struct nhop_object *nh, struct in_addr dst,
-    uint32_t flags, struct nhop4_basic *pnh4);
-static void fib4_rte_to_nh_extended(struct nhop_object *nh, struct in_addr dst,
-    uint32_t flags, struct nhop4_extended *pnh4);
-
-
-static void
-fib4_rte_to_nh_basic(struct nhop_object *nh, struct in_addr dst,
-    uint32_t flags, struct nhop4_basic *pnh4)
-{
-
-	if ((flags & NHR_IFAIF) != 0)
-		pnh4->nh_ifp = nh->nh_ifa->ifa_ifp;
-	else
-		pnh4->nh_ifp = nh->nh_ifp;
-	pnh4->nh_mtu = nh->nh_mtu;
-	if (nh->nh_flags & NHF_GATEWAY)
-		pnh4->nh_addr = nh->gw4_sa.sin_addr;
-	else
-		pnh4->nh_addr = dst;
-	/* Set flags */
-	pnh4->nh_flags = nh->nh_flags;
-	/* TODO: Handle RTF_BROADCAST here */
-}
-
-static void
-fib4_rte_to_nh_extended(struct nhop_object *nh, struct in_addr dst,
-    uint32_t flags, struct nhop4_extended *pnh4)
-{
-
-	if ((flags & NHR_IFAIF) != 0)
-		pnh4->nh_ifp = nh->nh_ifa->ifa_ifp;
-	else
-		pnh4->nh_ifp = nh->nh_ifp;
-	pnh4->nh_mtu = nh->nh_mtu;
-	if (nh->nh_flags & NHF_GATEWAY)
-		pnh4->nh_addr = nh->gw4_sa.sin_addr;
-	else
-		pnh4->nh_addr = dst;
-	/* Set flags */
-	pnh4->nh_flags = nh->nh_flags;
-	pnh4->nh_ia = ifatoia(nh->nh_ifa);
-	pnh4->nh_src = IA_SIN(pnh4->nh_ia)->sin_addr;
-}
-
-/*
- * Performs IPv4 route table lookup on @dst. Returns 0 on success.
- * Stores nexthop info provided @pnh4 structure.
- * Note that
- * - nh_ifp cannot be safely dereferenced
- * - nh_ifp represents logical transmit interface (rt_ifp) (e.g. if
- *   looking up address on interface "ix0" pointer to "lo0" interface
- *   will be returned instead of "ix0")
- * - nh_ifp represents "address" interface if NHR_IFAIF flag is passed
- * - howewer mtu from "transmit" interface will be returned.
- */
-int
-fib4_lookup_nh_basic(uint32_t fibnum, struct in_addr dst, uint32_t flags,
-    uint32_t flowid, struct nhop4_basic *pnh4)
-{
-	RIB_RLOCK_TRACKER;
-	struct rib_head *rh;
-	struct radix_node *rn;
-	struct sockaddr_in sin;
-	struct nhop_object *nh;
-
-	KASSERT((fibnum < rt_numfibs), ("fib4_lookup_nh_basic: bad fibnum"));
-	rh = rt_tables_get_rnh(fibnum, AF_INET);
-	if (rh == NULL)
-		return (ENOENT);
-
-	/* Prepare lookup key */
-	memset(&sin, 0, sizeof(sin));
-	sin.sin_len = sizeof(struct sockaddr_in);
-	sin.sin_addr = dst;
-
-	RIB_RLOCK(rh);
-	rn = rh->rnh_matchaddr((void *)&sin, &rh->head);
-	if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) {
-		nh = RNTORT(rn)->rt_nhop;
-		/* Ensure route & ifp is UP */
-		if (RT_LINK_IS_UP(nh->nh_ifp)) {
-			fib4_rte_to_nh_basic(nh, dst, flags, pnh4);
-			RIB_RUNLOCK(rh);
-
-			return (0);
-		}
-	}
-	RIB_RUNLOCK(rh);
-
-	return (ENOENT);
-}
-
-/*
- * Performs IPv4 route table lookup on @dst. Returns 0 on success.
- * Stores extende nexthop info provided @pnh4 structure.
- * Note that
- * - nh_ifp cannot be safely dereferenced unless NHR_REF is specified.
- * - in that case you need to call fib4_free_nh_ext()
- * - nh_ifp represents logical transmit interface (rt_ifp) (e.g. if
- *   looking up address of interface "ix0" pointer to "lo0" interface
- *   will be returned instead of "ix0")
- * - nh_ifp represents "address" interface if NHR_IFAIF flag is passed
- * - howewer mtu from "transmit" interface will be returned.
- */
-int
-fib4_lookup_nh_ext(uint32_t fibnum, struct in_addr dst, uint32_t flags,
-    uint32_t flowid, struct nhop4_extended *pnh4)
-{
-	RIB_RLOCK_TRACKER;
-	struct rib_head *rh;
-	struct radix_node *rn;
-	struct sockaddr_in sin;
-	struct rtentry *rte;
-	struct nhop_object *nh;
-
-	KASSERT((fibnum < rt_numfibs), ("fib4_lookup_nh_ext: bad fibnum"));
-	rh = rt_tables_get_rnh(fibnum, AF_INET);
-	if (rh == NULL)
-		return (ENOENT);
-
-	/* Prepare lookup key */
-	memset(&sin, 0, sizeof(sin));
-	sin.sin_len = sizeof(struct sockaddr_in);
-	sin.sin_addr = dst;
-
-	RIB_RLOCK(rh);
-	rn = rh->rnh_matchaddr((void *)&sin, &rh->head);
-	if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) {
-		rte = RNTORT(rn);
-#ifdef RADIX_MPATH
-		rte = rt_mpath_select(rte, flowid);
-		if (rte == NULL) {
-			RIB_RUNLOCK(rh);
-			return (ENOENT);
-		}
-#endif
-		nh = rte->rt_nhop;
-		/* Ensure route & ifp is UP */
-		if (RT_LINK_IS_UP(nh->nh_ifp)) {
-			fib4_rte_to_nh_extended(nh, dst, flags, pnh4);
-			if ((flags & NHR_REF) != 0) {
-				/* TODO: lwref on egress ifp's ? */
-			}
-			RIB_RUNLOCK(rh);
-
-			return (0);
-		}
-	}
-	RIB_RUNLOCK(rh);
-
-	return (ENOENT);
-}
-
-void
-fib4_free_nh_ext(uint32_t fibnum, struct nhop4_extended *pnh4)
-{
-
-}
 
 /*
  * Looks up path in fib @fibnum specified by @dst.

Modified: head/sys/netinet/in_fib.h
==============================================================================
--- head/sys/netinet/in_fib.h	Thu Jul  2 18:42:43 2020	(r362899)
+++ head/sys/netinet/in_fib.h	Thu Jul  2 21:04:08 2020	(r362900)
@@ -45,32 +45,6 @@ struct route_in {
 	struct sockaddr_in ro_dst4;
 };
 
-/* Basic nexthop info used for uRPF/mtu checks */
-struct nhop4_basic {
-	struct ifnet	*nh_ifp;	/* Logical egress interface */
-	uint16_t	nh_mtu;		/* nexthop mtu */
-	uint16_t	nh_flags;	/* nhop flags */
-	struct in_addr	nh_addr;	/* GW/DST IPv4 address */
-};
-
-/* Extended nexthop info used for control protocols */
-struct nhop4_extended {
-	struct ifnet	*nh_ifp;	/* Logical egress interface */
-	struct in_ifaddr *nh_ia;	/* Associated address */
-	uint16_t	nh_mtu;		/* nexthop mtu */
-	uint16_t	nh_flags;	/* nhop flags */
-	uint8_t		spare[4];
-	struct in_addr	nh_addr;	/* GW/DST IPv4 address */
-	struct in_addr	nh_src;		/* default source IPv4 address */
-	uint64_t	spare2;
-};
-
-int fib4_lookup_nh_basic(uint32_t fibnum, struct in_addr dst, uint32_t flags,
-    uint32_t flowid, struct nhop4_basic *pnh4);
-int fib4_lookup_nh_ext(uint32_t fibnum, struct in_addr dst, uint32_t flags,
-    uint32_t flowid, struct nhop4_extended *pnh4);
-void fib4_free_nh_ext(uint32_t fibnum, struct nhop4_extended *pnh4);
-
 struct nhop_object *fib4_lookup(uint32_t fibnum, struct in_addr dst,
     uint32_t scopeid, uint32_t flags, uint32_t flowid);
 int fib4_check_urpf(uint32_t fibnum, struct in_addr dst, uint32_t scopeid,

Modified: head/sys/netinet/in_mcast.c
==============================================================================
--- head/sys/netinet/in_mcast.c	Thu Jul  2 18:42:43 2020	(r362899)
+++ head/sys/netinet/in_mcast.c	Thu Jul  2 21:04:08 2020	(r362900)
@@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
 #include <net/if_var.h>
 #include <net/if_dl.h>
 #include <net/route.h>
+#include <net/route/nhop.h>
 #include <net/vnet.h>
 
 #include <net/ethernet.h>
@@ -1902,7 +1903,7 @@ inp_lookup_mcast_ifp(const struct inpcb *inp,
 {
 	struct rm_priotracker in_ifa_tracker;
 	struct ifnet *ifp;
-	struct nhop4_basic nh4;
+	struct nhop_object *nh;
 	uint32_t fibnum;
 
 	KASSERT(gsin->sin_family == AF_INET, ("%s: not AF_INET", __func__));
@@ -1916,8 +1917,9 @@ inp_lookup_mcast_ifp(const struct inpcb *inp,
 		IN_IFADDR_RUNLOCK(&in_ifa_tracker);
 	} else {
 		fibnum = inp ? inp->inp_inc.inc_fibnum : 0;
-		if (fib4_lookup_nh_basic(fibnum, gsin->sin_addr, 0, 0, &nh4)==0)
-			ifp = nh4.nh_ifp;
+		nh = fib4_lookup(fibnum, gsin->sin_addr, 0, 0, 0);
+		if (nh != NULL)
+			ifp = nh->nh_ifp;
 		else {
 			struct in_ifaddr *ia;
 			struct ifnet *mifp;
@@ -2726,6 +2728,7 @@ inp_setmoptions(struct inpcb *inp, struct sockopt *sop
 {
 	struct ip_moptions	*imo;
 	int			 error;
+	struct epoch_tracker	et;
 
 	error = 0;
 
@@ -2832,7 +2835,9 @@ inp_setmoptions(struct inpcb *inp, struct sockopt *sop
 	case IP_ADD_SOURCE_MEMBERSHIP:
 	case MCAST_JOIN_GROUP:
 	case MCAST_JOIN_SOURCE_GROUP:
+		NET_EPOCH_ENTER(et);
 		error = inp_join_group(inp, sopt);
+		NET_EPOCH_EXIT(et);
 		break;
 
 	case IP_DROP_MEMBERSHIP:

Modified: head/sys/netinet/ip_options.c
==============================================================================
--- head/sys/netinet/ip_options.c	Thu Jul  2 18:42:43 2020	(r362899)
+++ head/sys/netinet/ip_options.c	Thu Jul  2 21:04:08 2020	(r362900)
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
 #include <net/if_var.h>
 #include <net/if_dl.h>
 #include <net/route.h>
+#include <net/route/nhop.h>
 #include <net/netisr.h>
 #include <net/vnet.h>
 
@@ -107,7 +108,7 @@ ip_dooptions(struct mbuf *m, int pass)
 	int opt, optlen, cnt, off, code, type = ICMP_PARAMPROB, forward = 0;
 	struct in_addr *sin, dst;
 	uint32_t ntime;
-	struct nhop4_extended nh_ext;
+	struct nhop_object *nh;
 	struct	sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET };
 
 	NET_EPOCH_ASSERT();
@@ -254,11 +255,12 @@ dropit:
 				    sizeof(struct in_addr));
 			} else {
 				/* XXX MRT 0 for routing */
-				if (fib4_lookup_nh_ext(M_GETFIB(m),
-				    ipaddr.sin_addr, 0, 0, &nh_ext) != 0)
+				nh = fib4_lookup(M_GETFIB(m), ipaddr.sin_addr,
+				     0, NHR_NONE, 0);
+				if (nh == NULL)
 					goto bad;
 
-				memcpy(cp + off, &nh_ext.nh_src,
+				memcpy(cp + off, &(IA_SIN(nh->nh_ifa)->sin_addr),
 				    sizeof(struct in_addr));
 			}
 
@@ -299,9 +301,9 @@ dropit:
 			if ((ia = (INA)ifa_ifwithaddr((SA)&ipaddr)) != NULL) {
 				memcpy(cp + off, &(IA_SIN(ia)->sin_addr),
 				    sizeof(struct in_addr));
-			} else if (fib4_lookup_nh_ext(M_GETFIB(m),
-			    ipaddr.sin_addr, 0, 0, &nh_ext) == 0) {
-				memcpy(cp + off, &nh_ext.nh_src,
+			} else if ((nh = fib4_lookup(M_GETFIB(m),
+			    ipaddr.sin_addr, 0, NHR_NONE, 0)) != NULL) {
+				memcpy(cp + off, &(IA_SIN(nh->nh_ifa)->sin_addr),
 				    sizeof(struct in_addr));
 			} else {
 				type = ICMP_UNREACH;

Modified: head/sys/netinet6/icmp6.c
==============================================================================
--- head/sys/netinet6/icmp6.c	Thu Jul  2 18:42:43 2020	(r362899)
+++ head/sys/netinet6/icmp6.c	Thu Jul  2 21:04:08 2020	(r362900)
@@ -2270,13 +2270,17 @@ icmp6_redirect_input(struct mbuf *m, int off)
 	}
     {
 	/* ip6->ip6_src must be equal to gw for icmp6->icmp6_reddst */
-	struct nhop6_basic nh6;
+	struct nhop_object *nh;
 	struct in6_addr kdst;
 	uint32_t scopeid;
 
 	in6_splitscope(&reddst6, &kdst, &scopeid);
-	if (fib6_lookup_nh_basic(ifp->if_fib, &kdst, scopeid, 0, 0,&nh6)==0){
-		if ((nh6.nh_flags & NHF_GATEWAY) == 0) {
+	NET_EPOCH_ASSERT();
+	nh = fib6_lookup(ifp->if_fib, &kdst, scopeid, 0, 0);
+	if (nh == NULL) {
+		struct in6_addr nh_addr;
+		nh_addr = ifatoia6(nh->nh_ifa)->ia_addr.sin6_addr;
+		if ((nh->nh_flags & NHF_GATEWAY) == 0) {
 			nd6log((LOG_ERR,
 			    "ICMP6 redirect rejected; no route "
 			    "with inet6 gateway found for redirect dst: %s\n",
@@ -2285,19 +2289,16 @@ icmp6_redirect_input(struct mbuf *m, int off)
 		}
 
 		/*
-		 * Embed scope zone id into next hop address, since
-		 * fib6_lookup_nh_basic() returns address without embedded
-		 * scope zone id.
+		 * Embed scope zone id into next hop address.
 		 */
-		if (in6_setscope(&nh6.nh_addr, m->m_pkthdr.rcvif, NULL))
-			goto freeit;
+		nh_addr = nh->gw6_sa.sin6_addr;
 
-		if (IN6_ARE_ADDR_EQUAL(&src6, &nh6.nh_addr) == 0) {
+		if (IN6_ARE_ADDR_EQUAL(&src6, &nh_addr) == 0) {
 			nd6log((LOG_ERR,
 			    "ICMP6 redirect rejected; "
 			    "not equal to gw-for-src=%s (must be same): "
 			    "%s\n",
-			    ip6_sprintf(ip6buf, &nh6.nh_addr),
+			    ip6_sprintf(ip6buf, &nh_addr),
 			    icmp6_redirect_diag(&src6, &reddst6, &redtgt6)));
 			goto bad;
 		}

Modified: head/sys/netinet6/in6.c
==============================================================================
--- head/sys/netinet6/in6.c	Thu Jul  2 18:42:43 2020	(r362899)
+++ head/sys/netinet6/in6.c	Thu Jul  2 21:04:08 2020	(r362900)
@@ -91,6 +91,7 @@ __FBSDID("$FreeBSD$");
 #include <net/if_var.h>
 #include <net/if_types.h>
 #include <net/route.h>
+#include <net/route/nhop.h>
 #include <net/if_dl.h>
 #include <net/vnet.h>
 
@@ -2141,10 +2142,9 @@ in6_lltable_rtcheck(struct ifnet *ifp,
 		    const struct sockaddr *l3addr)
 {
 	const struct sockaddr_in6 *sin6;
-	struct nhop6_basic nh6;
+	struct nhop_object *nh;
 	struct in6_addr dst;
 	uint32_t scopeid;
-	int error;
 	char ip6buf[INET6_ADDRSTRLEN];
 	int fibnum;
 
@@ -2155,8 +2155,8 @@ in6_lltable_rtcheck(struct ifnet *ifp,
 	sin6 = (const struct sockaddr_in6 *)l3addr;
 	in6_splitscope(&sin6->sin6_addr, &dst, &scopeid);
 	fibnum = V_rt_add_addr_allfibs ? RT_DEFAULT_FIB : ifp->if_fib;
-	error = fib6_lookup_nh_basic(fibnum, &dst, scopeid, 0, 0, &nh6);
-	if (error != 0 || (nh6.nh_flags & NHF_GATEWAY) || nh6.nh_ifp != ifp) {
+	nh = fib6_lookup(fibnum, &dst, scopeid, NHR_NONE, 0);
+	if (nh && ((nh->nh_flags & NHF_GATEWAY) || nh->nh_ifp != ifp)) {
 		struct ifaddr *ifa;
 		/*
 		 * Create an ND6 cache for an IPv6 neighbor

Modified: head/sys/netinet6/in6_fib.c
==============================================================================
--- head/sys/netinet6/in6_fib.c	Thu Jul  2 18:42:43 2020	(r362899)
+++ head/sys/netinet6/in6_fib.c	Thu Jul  2 21:04:08 2020	(r362900)
@@ -70,186 +70,8 @@ __FBSDID("$FreeBSD$");
 #include <net/if_types.h>
 
 #ifdef INET6
-static void fib6_rte_to_nh_extended(const struct nhop_object *nh,
-    const struct in6_addr *dst, uint32_t flags, struct nhop6_extended *pnh6);
-static void fib6_rte_to_nh_basic(const struct nhop_object *nh, const struct in6_addr *dst,
-    uint32_t flags, struct nhop6_basic *pnh6);
 
-#define	ifatoia6(ifa)	((struct in6_ifaddr *)(ifa))
-
 CHK_STRUCT_ROUTE_COMPAT(struct route_in6, ro_dst);
-
-
-
-static void
-fib6_rte_to_nh_basic(const struct nhop_object *nh, const struct in6_addr *dst,
-    uint32_t flags, struct nhop6_basic *pnh6)
-{
-
-	/* Do explicit nexthop zero unless we're copying it */
-	memset(pnh6, 0, sizeof(*pnh6));
-
-	if ((flags & NHR_IFAIF) != 0)
-		pnh6->nh_ifp = nh->nh_aifp;
-	else
-		pnh6->nh_ifp = nh->nh_ifp;
-
-	pnh6->nh_mtu = nh->nh_mtu;
-	if (nh->nh_flags & NHF_GATEWAY) {
-		/* Return address with embedded scope. */
-		pnh6->nh_addr = nh->gw6_sa.sin6_addr;
-	} else
-		pnh6->nh_addr = *dst;
-	/* Set flags */
-	pnh6->nh_flags = nh->nh_flags;
-}
-
-static void
-fib6_rte_to_nh_extended(const struct nhop_object *nh, const struct in6_addr *dst,
-    uint32_t flags, struct nhop6_extended *pnh6)
-{
-
-	/* Do explicit nexthop zero unless we're copying it */
-	memset(pnh6, 0, sizeof(*pnh6));
-
-	if ((flags & NHR_IFAIF) != 0)
-		pnh6->nh_ifp = nh->nh_aifp;
-	else
-		pnh6->nh_ifp = nh->nh_ifp;
-
-	pnh6->nh_mtu = nh->nh_mtu;
-	if (nh->nh_flags & NHF_GATEWAY) {
-		/* Return address with embedded scope. */
-		pnh6->nh_addr = nh->gw6_sa.sin6_addr;
-	} else
-		pnh6->nh_addr = *dst;
-	/* Set flags */
-	pnh6->nh_flags = nh->nh_flags;
-	pnh6->nh_ia = ifatoia6(nh->nh_ifa);
-}
-
-/*
- * Performs IPv6 route table lookup on @dst. Returns 0 on success.
- * Stores basic nexthop info into provided @pnh6 structure.
- * Note that
- * - nh_ifp represents logical transmit interface (rt_ifp) by default
- * - nh_ifp represents "address" interface if NHR_IFAIF flag is passed
- * - mtu from logical transmit interface will be returned.
- * - nh_ifp cannot be safely dereferenced
- * - nh_ifp represents rt_ifp (e.g. if looking up address on
- *   interface "ix0" pointer to "ix0" interface will be returned instead
- *   of "lo0")
- * - howewer mtu from "transmit" interface will be returned.
- * - scope will be embedded in nh_addr
- */
-int
-fib6_lookup_nh_basic(uint32_t fibnum, const struct in6_addr *dst, uint32_t scopeid,
-    uint32_t flags, uint32_t flowid, struct nhop6_basic *pnh6)
-{
-	RIB_RLOCK_TRACKER;
-	struct rib_head *rh;
-	struct radix_node *rn;
-	struct sockaddr_in6 sin6;
-	struct nhop_object *nh;
-
-	KASSERT((fibnum < rt_numfibs), ("fib6_lookup_nh_basic: bad fibnum"));
-	rh = rt_tables_get_rnh(fibnum, AF_INET6);
-	if (rh == NULL)
-		return (ENOENT);
-
-	/* Prepare lookup key */
-	memset(&sin6, 0, sizeof(sin6));
-	sin6.sin6_addr = *dst;
-	sin6.sin6_len = sizeof(struct sockaddr_in6);
-	/* Assume scopeid is valid and embed it directly */
-	if (IN6_IS_SCOPE_LINKLOCAL(dst))
-		sin6.sin6_addr.s6_addr16[1] = htons(scopeid & 0xffff);
-
-	RIB_RLOCK(rh);
-	rn = rh->rnh_matchaddr((void *)&sin6, &rh->head);
-	if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) {
-		nh = RNTORT(rn)->rt_nhop;
-		/* Ensure route & ifp is UP */
-		if (RT_LINK_IS_UP(nh->nh_ifp)) {
-			fib6_rte_to_nh_basic(nh, &sin6.sin6_addr, flags, pnh6);
-			RIB_RUNLOCK(rh);
-			return (0);
-		}
-	}
-	RIB_RUNLOCK(rh);
-
-	return (ENOENT);
-}
-
-/*
- * Performs IPv6 route table lookup on @dst. Returns 0 on success.
- * Stores extended nexthop info into provided @pnh6 structure.
- * Note that
- * - nh_ifp cannot be safely dereferenced unless NHR_REF is specified.
- * - in that case you need to call fib6_free_nh_ext()
- * - nh_ifp represents logical transmit interface (rt_ifp) by default
- * - nh_ifp represents "address" interface if NHR_IFAIF flag is passed
- * - mtu from logical transmit interface will be returned.
- * - scope will be embedded in nh_addr
- */
-int
-fib6_lookup_nh_ext(uint32_t fibnum, const struct in6_addr *dst,uint32_t scopeid,
-    uint32_t flags, uint32_t flowid, struct nhop6_extended *pnh6)
-{
-	RIB_RLOCK_TRACKER;
-	struct rib_head *rh;
-	struct radix_node *rn;
-	struct sockaddr_in6 sin6;
-	struct rtentry *rte;
-	struct nhop_object *nh;
-
-	KASSERT((fibnum < rt_numfibs), ("fib6_lookup_nh_ext: bad fibnum"));
-	rh = rt_tables_get_rnh(fibnum, AF_INET6);
-	if (rh == NULL)
-		return (ENOENT);
-
-	/* Prepare lookup key */
-	memset(&sin6, 0, sizeof(sin6));
-	sin6.sin6_len = sizeof(struct sockaddr_in6);
-	sin6.sin6_addr = *dst;
-	/* Assume scopeid is valid and embed it directly */
-	if (IN6_IS_SCOPE_LINKLOCAL(dst))
-		sin6.sin6_addr.s6_addr16[1] = htons(scopeid & 0xffff);
-
-	RIB_RLOCK(rh);
-	rn = rh->rnh_matchaddr((void *)&sin6, &rh->head);
-	if (rn != NULL && ((rn->rn_flags & RNF_ROOT) == 0)) {
-		rte = RNTORT(rn);
-#ifdef RADIX_MPATH
-		rte = rt_mpath_select(rte, flowid);
-		if (rte == NULL) {
-			RIB_RUNLOCK(rh);
-			return (ENOENT);
-		}
-#endif
-		nh = rte->rt_nhop;
-		/* Ensure route & ifp is UP */
-		if (RT_LINK_IS_UP(nh->nh_ifp)) {
-			fib6_rte_to_nh_extended(nh, &sin6.sin6_addr, flags,
-			    pnh6);
-			if ((flags & NHR_REF) != 0) {
-				/* TODO: Do lwref on egress ifp's */
-			}
-			RIB_RUNLOCK(rh);
-
-			return (0);
-		}
-	}
-	RIB_RUNLOCK(rh);
-
-	return (ENOENT);
-}
-
-void
-fib6_free_nh_ext(uint32_t fibnum, struct nhop6_extended *pnh6)
-{
-
-}
 
 /*
  * Looks up path in fib @fibnum specified by @dst.

Modified: head/sys/netinet6/in6_fib.h
==============================================================================
--- head/sys/netinet6/in6_fib.h	Thu Jul  2 18:42:43 2020	(r362899)
+++ head/sys/netinet6/in6_fib.h	Thu Jul  2 21:04:08 2020	(r362900)
@@ -32,33 +32,6 @@
 #ifndef _NETINET6_IN6_FIB_H_
 #define	_NETINET6_IN6_FIB_H_
 
-/* Basic nexthop info used for uRPF/mtu checks */
-struct nhop6_basic {
-	struct ifnet	*nh_ifp;	/* Logical egress interface */
-	uint16_t	nh_mtu;		/* nexthop mtu */
-	uint16_t	nh_flags;	/* nhop flags */
-	uint8_t		spare[4];
-	struct in6_addr	nh_addr;	/* GW/DST IPv4 address */
-};
-
-/* Extended nexthop info used for control protocols. */
-struct nhop6_extended {
-	struct ifnet	*nh_ifp;	/* Logical egress interface */
-	struct in6_ifaddr *nh_ia;	/* Associated address. */
-	uint16_t	nh_mtu;		/* nexthop mtu */
-	uint16_t	nh_flags;	/* nhop flags */
-	uint8_t		spare[4];
-	struct in6_addr	nh_addr;	/* GW/DST IPv6 address */
-	uint64_t	spare2[1];
-};
-
-int fib6_lookup_nh_basic(uint32_t fibnum, const struct in6_addr *dst,
-    uint32_t scopeid, uint32_t flags, uint32_t flowid,struct nhop6_basic *pnh6);
-int fib6_lookup_nh_ext(uint32_t fibnum, const struct in6_addr *dst,
-    uint32_t scopeid, uint32_t flags, uint32_t flowid,
-    struct nhop6_extended *pnh6);
-void fib6_free_nh_ext(uint32_t fibnum, struct nhop6_extended *pnh6);
-
 struct nhop_object *fib6_lookup(uint32_t fibnum,
     const struct in6_addr *dst6, uint32_t scopeid, uint32_t flags,
     uint32_t flowid);

Modified: head/sys/netinet6/in6_mcast.c
==============================================================================
--- head/sys/netinet6/in6_mcast.c	Thu Jul  2 18:42:43 2020	(r362899)
+++ head/sys/netinet6/in6_mcast.c	Thu Jul  2 21:04:08 2020	(r362900)
@@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
 #include <net/if_var.h>
 #include <net/if_dl.h>
 #include <net/route.h>
+#include <net/route/nhop.h>
 #include <net/vnet.h>
 
 #include <netinet/in.h>
@@ -1829,7 +1830,7 @@ static struct ifnet *
 in6p_lookup_mcast_ifp(const struct inpcb *inp,
     const struct sockaddr_in6 *gsin6)
 {
-	struct nhop6_basic	nh6;
+	struct nhop_object	*nh;
 	struct in6_addr		dst;
 	uint32_t		scopeid;
 	uint32_t		fibnum;
@@ -1841,10 +1842,9 @@ in6p_lookup_mcast_ifp(const struct inpcb *inp,
 
 	in6_splitscope(&gsin6->sin6_addr, &dst, &scopeid);
 	fibnum = inp ? inp->inp_inc.inc_fibnum : RT_DEFAULT_FIB;
-	if (fib6_lookup_nh_basic(fibnum, &dst, scopeid, 0, 0, &nh6) != 0)
-		return (NULL);
+	nh = fib6_lookup(fibnum, &dst, scopeid, 0, 0);
 
-	return (nh6.nh_ifp);
+	return (nh ? nh->nh_ifp : NULL);
 }
 
 /*

Modified: head/sys/netinet6/in6_src.c
==============================================================================
--- head/sys/netinet6/in6_src.c	Thu Jul  2 18:42:43 2020	(r362899)
+++ head/sys/netinet6/in6_src.c	Thu Jul  2 21:04:08 2020	(r362900)
@@ -916,15 +916,16 @@ in6_selecthlim(struct inpcb *inp, struct ifnet *ifp)
 	else if (ifp)
 		return (ND_IFINFO(ifp)->chlim);
 	else if (inp && !IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
-		struct nhop6_basic nh6;
+		struct nhop_object *nh;
 		struct in6_addr dst;
 		uint32_t fibnum, scopeid;
 		int hlim;
 
 		fibnum = inp->inp_inc.inc_fibnum;
 		in6_splitscope(&inp->in6p_faddr, &dst, &scopeid);
-		if (fib6_lookup_nh_basic(fibnum, &dst, scopeid, 0, 0, &nh6)==0){
-			hlim = ND_IFINFO(nh6.nh_ifp)->chlim;
+		nh = fib6_lookup(fibnum, &dst, scopeid, 0, 0);
+		if (nh != NULL) {
+			hlim = ND_IFINFO(nh->nh_ifp)->chlim;
 			return (hlim);
 		}
 	}

Modified: head/sys/netpfil/ipfw/ip_fw2.c
==============================================================================
--- head/sys/netpfil/ipfw/ip_fw2.c	Thu Jul  2 18:42:43 2020	(r362899)
+++ head/sys/netpfil/ipfw/ip_fw2.c	Thu Jul  2 21:04:08 2020	(r362900)
@@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$");
 #include <net/if.h>
 #include <net/if_var.h>
 #include <net/route.h>
+#include <net/route/nhop.h>
 #include <net/pfil.h>
 #include <net/vnet.h>
 
@@ -466,9 +467,10 @@ verify_path(struct in_addr src, struct ifnet *ifp, u_i
 #if defined(USERSPACE) || !defined(__FreeBSD__)
 	return 0;
 #else
-	struct nhop4_basic nh4;
+	struct nhop_object *nh;
 
-	if (fib4_lookup_nh_basic(fib, src, NHR_IFAIF, 0, &nh4) != 0)
+	nh = fib4_lookup(fib, src, 0, NHR_NONE, 0);
+	if (nh == NULL)
 		return (0);
 
 	/*
@@ -478,15 +480,15 @@ verify_path(struct in_addr src, struct ifnet *ifp, u_i
 	 * routing entry (via lo0) for our own address
 	 * may exist, so we need to handle routing assymetry.
 	 */
-	if (ifp != NULL && ifp != nh4.nh_ifp)
+	if (ifp != NULL && ifp != nh->nh_aifp)
 		return (0);
 
 	/* if no ifp provided, check if rtentry is not default route */
-	if (ifp == NULL && (nh4.nh_flags & NHF_DEFAULT) != 0)
+	if (ifp == NULL && (nh->nh_flags & NHF_DEFAULT) != 0)
 		return (0);
 
 	/* or if this is a blackhole/reject route */
-	if (ifp == NULL && (nh4.nh_flags & (NHF_REJECT|NHF_BLACKHOLE)) != 0)
+	if (ifp == NULL && (nh->nh_flags & (NHF_REJECT|NHF_BLACKHOLE)) != 0)
 		return (0);
 
 	/* found valid route */
@@ -805,24 +807,25 @@ ipfw_localip6(struct in6_addr *in6)
 static int
 verify_path6(struct in6_addr *src, struct ifnet *ifp, u_int fib)
 {
-	struct nhop6_basic nh6;
+	struct nhop_object *nh;
 
 	if (IN6_IS_SCOPE_LINKLOCAL(src))
 		return (1);
 
-	if (fib6_lookup_nh_basic(fib, src, 0, NHR_IFAIF, 0, &nh6) != 0)
+	nh = fib6_lookup(fib, src, 0, NHR_NONE, 0);
+	if (nh == NULL)
 		return (0);
 
 	/* If ifp is provided, check for equality with route table. */
-	if (ifp != NULL && ifp != nh6.nh_ifp)
+	if (ifp != NULL && ifp != nh->nh_aifp)
 		return (0);
 
 	/* if no ifp provided, check if rtentry is not default route */
-	if (ifp == NULL && (nh6.nh_flags & NHF_DEFAULT) != 0)
+	if (ifp == NULL && (nh->nh_flags & NHF_DEFAULT) != 0)
 		return (0);
 
 	/* or if this is a blackhole/reject route */
-	if (ifp == NULL && (nh6.nh_flags & (NHF_REJECT|NHF_BLACKHOLE)) != 0)
+	if (ifp == NULL && (nh->nh_flags & (NHF_REJECT|NHF_BLACKHOLE)) != 0)
 		return (0);
 
 	/* found valid route */

Modified: head/sys/netpfil/ipfw/ip_fw_table_algo.c
==============================================================================
--- head/sys/netpfil/ipfw/ip_fw_table_algo.c	Thu Jul  2 18:42:43 2020	(r362899)
+++ head/sys/netpfil/ipfw/ip_fw_table_algo.c	Thu Jul  2 21:04:08 2020	(r362900)
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
 #include <net/if.h>	/* ip_fw.h requires IFNAMSIZ */
 #include <net/radix.h>
 #include <net/route.h>
+#include <net/route/nhop.h>
 #include <net/route/route_var.h>
 
 #include <netinet/in.h>
@@ -3811,26 +3812,22 @@ ta_lookup_kfib(struct table_info *ti, void *key, uint3
     uint32_t *val)
 {
 #ifdef INET
-	struct nhop4_basic nh4;
 	struct in_addr in;
 #endif
-#ifdef INET6
-	struct nhop6_basic nh6;
-#endif
 	int error;
 
 	error = ENOENT;
 #ifdef INET
 	if (keylen == 4) {
 		in.s_addr = *(in_addr_t *)key;
-		error = fib4_lookup_nh_basic(ti->data,
-		    in, 0, 0, &nh4);
+		NET_EPOCH_ASSERT();
+		error = fib4_lookup(ti->data, in, 0, NHR_NONE, 0) != NULL;
 	}
 #endif
 #ifdef INET6
 	if (keylen == 6)
-		error = fib6_lookup_nh_basic(ti->data,
-		    (struct in6_addr *)key, 0, 0, 0, &nh6);
+		error = fib6_lookup(ti->data, (struct in6_addr *)key,
+		    0, NHR_NONE, 0) != NULL;
 #endif
 
 	if (error != 0)

Modified: head/sys/netpfil/ipfw/nat64/nat64_translate.c
==============================================================================
--- head/sys/netpfil/ipfw/nat64/nat64_translate.c	Thu Jul  2 18:42:43 2020	(r362899)
+++ head/sys/netpfil/ipfw/nat64/nat64_translate.c	Thu Jul  2 21:04:08 2020	(r362900)
@@ -50,9 +50,11 @@ __FBSDID("$FreeBSD$");
 #include <net/pfil.h>
 #include <net/netisr.h>
 #include <net/route.h>
+#include <net/route/nhop.h>
 
 #include <netinet/in.h>
 #include <netinet/in_fib.h>
+#include <netinet/in_var.h>
 #include <netinet/ip.h>
 #include <netinet/ip_var.h>
 #include <netinet/ip_fw.h>
@@ -79,9 +81,9 @@ typedef int (*nat64_output_t)(struct ifnet *, struct m
 typedef int (*nat64_output_one_t)(struct mbuf *, struct nat64_counters *,
     void *);
 
-static int nat64_find_route4(struct nhop4_basic *, struct sockaddr_in *,
+static struct nhop_object *nat64_find_route4(struct sockaddr_in *,
     struct mbuf *);
-static int nat64_find_route6(struct nhop6_basic *, struct sockaddr_in6 *,
+static struct nhop_object *nat64_find_route6(struct sockaddr_in6 *,
     struct mbuf *);
 static int nat64_output_one(struct mbuf *, struct nat64_counters *, void *);
 static int nat64_output(struct ifnet *, struct mbuf *, struct sockaddr *,
@@ -172,8 +174,8 @@ static int
 nat64_direct_output_one(struct mbuf *m, struct nat64_counters *stats,
     void *logdata)
 {
-	struct nhop6_basic nh6;
-	struct nhop4_basic nh4;
+	struct nhop_object *nh4 = NULL;
+	struct nhop_object *nh6 = NULL;
 	struct sockaddr_in6 dst6;
 	struct sockaddr_in dst4;
 	struct sockaddr *dst;
@@ -183,25 +185,28 @@ nat64_direct_output_one(struct mbuf *m, struct nat64_c
 	int error;
 
 	ip4 = mtod(m, struct ip *);
+	error = 0;
 	switch (ip4->ip_v) {
 	case IPVERSION:
 		dst4.sin_addr = ip4->ip_dst;
-		error = nat64_find_route4(&nh4, &dst4, m);
-		if (error != 0)
+		nh4 = nat64_find_route4(&dst4, m);
+		if (nh4 == NULL) {
 			NAT64STAT_INC(stats, noroute4);
-		else {
-			ifp = nh4.nh_ifp;
+			error = EHOSTUNREACH;
+		} else {
+			ifp = nh4->nh_ifp;
 			dst = (struct sockaddr *)&dst4;
 		}
 		break;
 	case (IPV6_VERSION >> 4):
 		ip6 = mtod(m, struct ip6_hdr *);
 		dst6.sin6_addr = ip6->ip6_dst;
-		error = nat64_find_route6(&nh6, &dst6, m);
-		if (error != 0)
+		nh6 = nat64_find_route6(&dst6, m);
+		if (nh6 == NULL) {
 			NAT64STAT_INC(stats, noroute6);
-		else {
-			ifp = nh6.nh_ifp;
+			error = EHOSTUNREACH;
+		} else {
+			ifp = nh6->nh_ifp;
 			dst = (struct sockaddr *)&dst6;
 		}
 		break;
@@ -614,31 +619,31 @@ fail:
 	return (ENOMEM);
 }
 
-static NAT64NOINLINE int
-nat64_find_route6(struct nhop6_basic *pnh, struct sockaddr_in6 *dst,
-    struct mbuf *m)
+static struct nhop_object *
+nat64_find_route6(struct sockaddr_in6 *dst, struct mbuf *m)
 {
-
-	if (fib6_lookup_nh_basic(M_GETFIB(m), &dst->sin6_addr, 0, 0, 0,
-	    pnh) != 0)
-		return (EHOSTUNREACH);
-	if (pnh->nh_flags & (NHF_BLACKHOLE | NHF_REJECT))
-		return (EHOSTUNREACH);
+	struct nhop_object *nh;
+	NET_EPOCH_ASSERT();
+	nh = fib6_lookup(M_GETFIB(m), &dst->sin6_addr, 0, 0, 0);
+	if (nh == NULL)
+		return NULL;
+	if (nh->nh_flags & (NHF_BLACKHOLE | NHF_REJECT))
+		return NULL;
 	/*
 	 * XXX: we need to use destination address with embedded scope
 	 * zone id, because LLTABLE uses such form of addresses for lookup.
 	 */
 	dst->sin6_family = AF_INET6;
 	dst->sin6_len = sizeof(*dst);
-	dst->sin6_addr = pnh->nh_addr;
+	dst->sin6_addr = ifatoia6(nh->nh_ifa)->ia_addr.sin6_addr;
 	if (IN6_IS_SCOPE_LINKLOCAL(&dst->sin6_addr))
 		dst->sin6_addr.s6_addr16[1] =
-		    htons(pnh->nh_ifp->if_index & 0xffff);
+		    htons(nh->nh_ifp->if_index & 0xffff);
 	dst->sin6_port = 0;
 	dst->sin6_scope_id = 0;
 	dst->sin6_flowinfo = 0;
 
-	return (0);
+	return nh;
 }
 
 #define	NAT64_ICMP6_PLEN	64
@@ -766,21 +771,23 @@ freeit:
 	m_freem(m);
 }
 
-static NAT64NOINLINE int
-nat64_find_route4(struct nhop4_basic *pnh, struct sockaddr_in *dst,
-    struct mbuf *m)
+static struct nhop_object *
+nat64_find_route4(struct sockaddr_in *dst, struct mbuf *m)
 {
+	struct nhop_object *nh;
 
-	if (fib4_lookup_nh_basic(M_GETFIB(m), dst->sin_addr, 0, 0, pnh) != 0)
-		return (EHOSTUNREACH);
-	if (pnh->nh_flags & (NHF_BLACKHOLE | NHF_BROADCAST | NHF_REJECT))
-		return (EHOSTUNREACH);
+	NET_EPOCH_ASSERT();
+	nh = fib4_lookup(M_GETFIB(m), dst->sin_addr, 0, 0, 0);
+	if (nh == NULL)
+		return NULL;
+	if (nh->nh_flags & (NHF_BLACKHOLE | NHF_BROADCAST | NHF_REJECT))
+		return NULL;
 
 	dst->sin_family = AF_INET;
 	dst->sin_len = sizeof(*dst);
-	dst->sin_addr = pnh->nh_addr;
+	dst->sin_addr = IA_SIN(nh->nh_ifa)->sin_addr;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



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