Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 12 Sep 2018 08:46:50 +0000 (UTC)
From:      Eugene Grosbein <eugen@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r338611 - stable/11/sys/netinet
Message-ID:  <201809120846.w8C8kojs033094@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: eugen
Date: Wed Sep 12 08:46:49 2018
New Revision: 338611
URL: https://svnweb.freebsd.org/changeset/base/338611

Log:
  MFC r338468: Fix "ipfw fwd" to work for incoming IPv4 packets
  when ip_tryforward() chooses fast forwarding path, as it already works
  for IPv6 and for both of them on old slow path.
  
  PR:			231143
  Reviewed by:		ae
  Differential Revision:	https://reviews.freebsd.org/D17039

Modified:
  stable/11/sys/netinet/ip_fastfwd.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/netinet/ip_fastfwd.c
==============================================================================
--- stable/11/sys/netinet/ip_fastfwd.c	Wed Sep 12 08:13:54 2018	(r338610)
+++ stable/11/sys/netinet/ip_fastfwd.c	Wed Sep 12 08:46:49 2018	(r338611)
@@ -151,7 +151,7 @@ ip_tryforward(struct mbuf *m)
 	struct mbuf *m0 = NULL;
 	struct nhop4_basic nh;
 	struct sockaddr_in dst;
-	struct in_addr odest, dest;
+	struct in_addr dest, odest, rtdest;
 	uint16_t ip_len, ip_off;
 	int error = 0;
 	struct m_tag *fwd_tag = NULL;
@@ -292,12 +292,31 @@ passin:
 #endif
 
 	/*
+	 * Next hop forced by pfil(9) hook?
+	 */
+	if ((m->m_flags & M_IP_NEXTHOP) &&
+	    ((fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL)) != NULL)) {
+		/*
+		 * Now we will find route to forced destination.
+		 */
+		dest.s_addr = ((struct sockaddr_in *)
+			    (fwd_tag + 1))->sin_addr.s_addr;
+		m_tag_delete(m, fwd_tag);
+		m->m_flags &= ~M_IP_NEXTHOP;
+	}
+
+	/*
 	 * Find route to destination.
 	 */
 	if (ip_findroute(&nh, dest, m) != 0)
 		return (NULL);	/* icmp unreach already sent */
 
 	/*
+	 * Avoid second route lookup by caching destination.
+	 */
+	rtdest.s_addr = dest.s_addr;
+
+	/*
 	 * Step 5: outgoing firewall packet processing
 	 */
 	if (!PFIL_HOOKED(&V_inet_pfil_hook))
@@ -319,6 +338,8 @@ passin:
 	 */
 	if (m->m_flags & M_IP_NEXTHOP)
 		fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL);
+	else
+		fwd_tag = NULL;
 	if (odest.s_addr != dest.s_addr || fwd_tag != NULL) {
 		/*
 		 * Is it now for a local address on this host?
@@ -340,7 +361,8 @@ forwardlocal:
 			m_tag_delete(m, fwd_tag);
 			m->m_flags &= ~M_IP_NEXTHOP;
 		}
-		if (ip_findroute(&nh, dest, m) != 0)
+		if (dest.s_addr != rtdest.s_addr &&
+		    ip_findroute(&nh, dest, m) != 0)
 			return (NULL);	/* icmp unreach already sent */
 	}
 



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