Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 23 Aug 2015 18:19:26 +0000 (UTC)
From:      "Alexander V. Chernikov" <melifaro@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r287053 - projects/routing/sys/netinet
Message-ID:  <201508231819.t7NIJQK8042769@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: melifaro
Date: Sun Aug 23 18:19:25 2015
New Revision: 287053
URL: https://svnweb.freebsd.org/changeset/base/287053

Log:
  Convert ip_fastfwd() to use new routing api.

Modified:
  projects/routing/sys/netinet/ip_fastfwd.c

Modified: projects/routing/sys/netinet/ip_fastfwd.c
==============================================================================
--- projects/routing/sys/netinet/ip_fastfwd.c	Sun Aug 23 18:18:44 2015	(r287052)
+++ projects/routing/sys/netinet/ip_fastfwd.c	Sun Aug 23 18:19:25 2015	(r287053)
@@ -106,6 +106,8 @@ __FBSDID("$FreeBSD$");
 #include <netinet/ip_icmp.h>
 #include <netinet/ip_options.h>
 
+#include <net/rt_nhops.h>
+
 #include <machine/in_cksum.h>
 
 static VNET_DEFINE(int, ipfastforward_active);
@@ -114,42 +116,6 @@ static VNET_DEFINE(int, ipfastforward_ac
 SYSCTL_INT(_net_inet_ip, OID_AUTO, fastforwarding, CTLFLAG_VNET | CTLFLAG_RW,
     &VNET_NAME(ipfastforward_active), 0, "Enable fast IP forwarding");
 
-static struct sockaddr_in *
-ip_findroute(struct route *ro, struct in_addr dest, struct mbuf *m)
-{
-	struct sockaddr_in *dst;
-	struct rtentry *rt;
-
-	/*
-	 * Find route to destination.
-	 */
-	bzero(ro, sizeof(*ro));
-	dst = (struct sockaddr_in *)&ro->ro_dst;
-	dst->sin_family = AF_INET;
-	dst->sin_len = sizeof(*dst);
-	dst->sin_addr.s_addr = dest.s_addr;
-	in_rtalloc_ign(ro, 0, M_GETFIB(m));
-
-	/*
-	 * Route there and interface still up?
-	 */
-	rt = ro->ro_rt;
-	if (rt && (rt->rt_flags & RTF_UP) &&
-	    (rt->rt_ifp->if_flags & IFF_UP) &&
-	    (rt->rt_ifp->if_drv_flags & IFF_DRV_RUNNING)) {
-		if (rt->rt_flags & RTF_GATEWAY)
-			dst = (struct sockaddr_in *)rt->rt_gateway;
-	} else {
-		IPSTAT_INC(ips_noroute);
-		IPSTAT_INC(ips_cantforward);
-		if (rt)
-			RTFREE(rt);
-		icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0);
-		return NULL;
-	}
-	return dst;
-}
-
 /*
  * Try to forward a packet based on the destination address.
  * This is a fast path optimized for the plain forwarding case.
@@ -162,11 +128,11 @@ ip_fastforward(struct mbuf *m)
 {
 	struct ip *ip;
 	struct mbuf *m0 = NULL;
-	struct route ro;
-	struct sockaddr_in *dst = NULL;
+	struct nhop_data nhd, *pnhd;
 	struct ifnet *ifp;
 	struct in_addr odest, dest;
 	uint16_t sum, ip_len, ip_off;
+	uint32_t fibnum;
 	int error = 0;
 	int hlen, mtu;
 	struct m_tag *fwd_tag = NULL;
@@ -180,7 +146,8 @@ ip_fastforward(struct mbuf *m)
 	M_ASSERTVALID(m);
 	M_ASSERTPKTHDR(m);
 
-	bzero(&ro, sizeof(ro));
+	fibnum = M_GETFIB(m);
+	pnhd = NULL;
 
 	/*
 	 * Step 1: check for packet drop conditions (and sanity checks)
@@ -413,16 +380,22 @@ passin:
 	/*
 	 * Find route to destination.
 	 */
-	if ((dst = ip_findroute(&ro, dest, m)) == NULL)
-		return NULL;	/* icmp unreach already sent */
-	ifp = ro.ro_rt->rt_ifp;
+	fibnum = M_GETFIB(m);
+	if (fib4_lookup_prepend(fibnum, dest, m, &nhd, NULL) != 0) {
+		IPSTAT_INC(ips_noroute);
+		IPSTAT_INC(ips_cantforward);
+		icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0);
+		return (NULL);
+	}
+	pnhd = &nhd;
+	ifp = NH_LIFP(&nhd);
 
 	/*
 	 * Immediately drop blackholed traffic, and directed broadcasts
 	 * for either the all-ones or all-zero subnet addresses on
 	 * locally attached networks.
 	 */
-	if ((ro.ro_rt->rt_flags & (RTF_BLACKHOLE|RTF_BROADCAST)) != 0)
+	if ((nhd.nh_flags & (NHOP_BLACKHOLE|RTF_BROADCAST)) != 0)
 		goto drop;
 
 	/*
@@ -460,8 +433,8 @@ forwardlocal:
 			 * Return packet for processing by ip_input().
 			 */
 			m->m_flags |= M_FASTFWD_OURS;
-			if (ro.ro_rt)
-				RTFREE(ro.ro_rt);
+			if (pnhd != NULL)
+				fib4_free_nh(fibnum, pnhd);
 			return m;
 		}
 		/*
@@ -473,10 +446,17 @@ forwardlocal:
 			m_tag_delete(m, fwd_tag);
 			m->m_flags &= ~M_IP_NEXTHOP;
 		}
-		RTFREE(ro.ro_rt);
-		if ((dst = ip_findroute(&ro, dest, m)) == NULL)
-			return NULL;	/* icmp unreach already sent */
-		ifp = ro.ro_rt->rt_ifp;
+		fib4_free_nh(fibnum, pnhd);
+
+
+		if (fib4_lookup_prepend(fibnum, dest, m, &nhd, NULL) != 0) {
+			IPSTAT_INC(ips_noroute);
+			IPSTAT_INC(ips_cantforward);
+			icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0);
+			return (NULL);
+		}
+		pnhd = &nhd;
+		ifp = NH_LIFP(&nhd);
 	}
 
 passout:
@@ -486,6 +466,7 @@ passout:
 	ip_len = ntohs(ip->ip_len);
 	ip_off = ntohs(ip->ip_off);
 
+#if 0
 	/*
 	 * Check if route is dampned (when ARP is unable to resolve)
 	 */
@@ -494,6 +475,11 @@ passout:
 		icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0);
 		goto consumed;
 	}
+#endif
+	if ((nhd.nh_flags & NHOP_REJECT) != 0) {
+		icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0);
+		goto consumed;
+	}
 
 	/*
 	 * Check if media link state of interface is not down
@@ -506,10 +492,7 @@ passout:
 	/*
 	 * Check if packet fits MTU or if hardware will fragment for us
 	 */
-	if (ro.ro_rt->rt_mtu)
-		mtu = min(ro.ro_rt->rt_mtu, ifp->if_mtu);
-	else
-		mtu = ifp->if_mtu;
+	mtu = nhd.nh_mtu;
 
 	if (ip_len <= mtu) {
 		/*
@@ -520,8 +503,7 @@ passout:
 		 * Send off the packet via outgoing interface
 		 */
 		IP_PROBE(send, NULL, NULL, ip, ifp, ip, NULL);
-		error = (*ifp->if_output)(ifp, m,
-				(struct sockaddr *)dst, &ro);
+		error = fib4_sendmbuf(ifp, m, &nhd, dest);
 	} else {
 		/*
 		 * Handle EMSGSIZE with icmp reply needfrag for TCP MTU discovery
@@ -552,8 +534,7 @@ passout:
 				m_clrprotoflags(m);
 
 				IP_PROBE(send, NULL, NULL, ip, ifp, ip, NULL);
-				error = (*ifp->if_output)(ifp, m,
-					(struct sockaddr *)dst, &ro);
+				error = fib4_sendmbuf(ifp, m, &nhd, dest);
 				if (error)
 					break;
 			} while ((m = m0) != NULL);
@@ -571,17 +552,16 @@ passout:
 	if (error != 0)
 		IPSTAT_INC(ips_odropped);
 	else {
-		counter_u64_add(ro.ro_rt->rt_pksent, 1);
 		IPSTAT_INC(ips_forward);
 		IPSTAT_INC(ips_fastforward);
 	}
 consumed:
-	RTFREE(ro.ro_rt);
+	fib4_free_nh(fibnum, &nhd);
 	return NULL;
 drop:
 	if (m)
 		m_freem(m);
-	if (ro.ro_rt)
-		RTFREE(ro.ro_rt);
+	if (pnhd != NULL)
+		fib4_free_nh(fibnum, pnhd);
 	return NULL;
 }



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