Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 22 Feb 2016 19:17:59 +0000 (UTC)
From:      "George V. Neville-Neil" <gnn@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r295896 - in stable/10: share/man/man4 sys/net sys/netinet
Message-ID:  <201602221917.u1MJHxJm070096@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gnn
Date: Mon Feb 22 19:17:59 2016
New Revision: 295896
URL: https://svnweb.freebsd.org/changeset/base/295896

Log:
  Revert 295285 which was an MFC of the tryforward work (r290383,295282,295283)
  
  In the IPFW+NAT+divergent MTU case there is a bug in sening ICMP MTU updates.
  
  Approved by:	re (marius, gjb)
  Sponsored by:	Rubicon Communications (Netgate)

Modified:
  stable/10/share/man/man4/inet.4
  stable/10/sys/net/if_arcsubr.c
  stable/10/sys/net/if_ef.c
  stable/10/sys/net/if_ethersubr.c
  stable/10/sys/net/if_fddisubr.c
  stable/10/sys/net/if_fwsubr.c
  stable/10/sys/net/if_iso88025subr.c
  stable/10/sys/netinet/in_var.h
  stable/10/sys/netinet/ip_fastfwd.c
  stable/10/sys/netinet/ip_input.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/share/man/man4/inet.4
==============================================================================
--- stable/10/share/man/man4/inet.4	Mon Feb 22 18:53:55 2016	(r295895)
+++ stable/10/share/man/man4/inet.4	Mon Feb 22 19:17:59 2016	(r295896)
@@ -32,7 +32,7 @@
 .\"     From: @(#)inet.4	8.1 (Berkeley) 6/5/93
 .\" $FreeBSD$
 .\"
-.Dd Feb 4, 2016
+.Dd January 26, 2012
 .Dt INET 4
 .Os
 .Sh NAME
@@ -169,11 +169,33 @@ MIB.
 In addition to the variables supported by the transport protocols
 (for which the respective manual pages may be consulted),
 the following general variables are defined:
-.Bl -tag -width IPCTL_ACCEPTSOURCEROUTE
+.Bl -tag -width IPCTL_FASTFORWARDING
 .It Dv IPCTL_FORWARDING
 .Pq ip.forwarding
 Boolean: enable/disable forwarding of IP packets.
 Defaults to off.
+.It Dv IPCTL_FASTFORWARDING
+.Pq ip.fastforwarding
+Boolean: enable/disable the use of
+.Tn fast IP forwarding
+code.
+Defaults to off.
+When
+.Tn fast IP forwarding
+is enabled, IP packets are forwarded directly to the appropriate network
+interface with direct processing to completion, which greatly improves
+the throughput.
+All packets for local IP addresses, non-unicast, or with IP options are
+handled by the normal IP input processing path.
+All features of the normal (slow) IP forwarding path are supported
+including firewall (through
+.Xr pfil 9
+hooks) checking, except
+.Xr ipsec 4
+tunnel brokering.
+The
+.Tn IP fastforwarding
+path does not generate ICMP redirect or source quench messages.
 .It Dv IPCTL_SENDREDIRECTS
 .Pq ip.redirect
 Boolean: enable/disable sending of ICMP redirects in response to

Modified: stable/10/sys/net/if_arcsubr.c
==============================================================================
--- stable/10/sys/net/if_arcsubr.c	Mon Feb 22 18:53:55 2016	(r295895)
+++ stable/10/sys/net/if_arcsubr.c	Mon Feb 22 19:17:59 2016	(r295896)
@@ -557,11 +557,15 @@ arc_input(struct ifnet *ifp, struct mbuf
 #ifdef INET
 	case ARCTYPE_IP:
 		m_adj(m, ARC_HDRNEWLEN);
+		if ((m = ip_fastforward(m)) == NULL)
+			return;
 		isr = NETISR_IP;
 		break;
 
 	case ARCTYPE_IP_OLD:
 		m_adj(m, ARC_HDRLEN);
+		if ((m = ip_fastforward(m)) == NULL)
+			return;
 		isr = NETISR_IP;
 		break;
 

Modified: stable/10/sys/net/if_ef.c
==============================================================================
--- stable/10/sys/net/if_ef.c	Mon Feb 22 18:53:55 2016	(r295895)
+++ stable/10/sys/net/if_ef.c	Mon Feb 22 19:17:59 2016	(r295896)
@@ -240,6 +240,8 @@ ef_inputEII(struct mbuf *m, struct ether
 #endif
 #ifdef INET
 	case ETHERTYPE_IP:
+		if ((m = ip_fastforward(m)) == NULL)
+			return (0);
 		isr = NETISR_IP;
 		break;
 

Modified: stable/10/sys/net/if_ethersubr.c
==============================================================================
--- stable/10/sys/net/if_ethersubr.c	Mon Feb 22 18:53:55 2016	(r295895)
+++ stable/10/sys/net/if_ethersubr.c	Mon Feb 22 19:17:59 2016	(r295896)
@@ -784,6 +784,8 @@ ether_demux(struct ifnet *ifp, struct mb
 	switch (ether_type) {
 #ifdef INET
 	case ETHERTYPE_IP:
+		if ((m = ip_fastforward(m)) == NULL)
+			return;
 		isr = NETISR_IP;
 		break;
 

Modified: stable/10/sys/net/if_fddisubr.c
==============================================================================
--- stable/10/sys/net/if_fddisubr.c	Mon Feb 22 18:53:55 2016	(r295895)
+++ stable/10/sys/net/if_fddisubr.c	Mon Feb 22 19:17:59 2016	(r295896)
@@ -501,6 +501,8 @@ fddi_input(ifp, m)
 		switch (type) {
 #ifdef INET
 		case ETHERTYPE_IP:
+			if ((m = ip_fastforward(m)) == NULL)
+				return;
 			isr = NETISR_IP;
 			break;
 

Modified: stable/10/sys/net/if_fwsubr.c
==============================================================================
--- stable/10/sys/net/if_fwsubr.c	Mon Feb 22 18:53:55 2016	(r295895)
+++ stable/10/sys/net/if_fwsubr.c	Mon Feb 22 19:17:59 2016	(r295896)
@@ -595,6 +595,8 @@ firewire_input(struct ifnet *ifp, struct
 	switch (type) {
 #ifdef INET
 	case ETHERTYPE_IP:
+		if ((m = ip_fastforward(m)) == NULL)
+			return;
 		isr = NETISR_IP;
 		break;
 

Modified: stable/10/sys/net/if_iso88025subr.c
==============================================================================
--- stable/10/sys/net/if_iso88025subr.c	Mon Feb 22 18:53:55 2016	(r295895)
+++ stable/10/sys/net/if_iso88025subr.c	Mon Feb 22 19:17:59 2016	(r295896)
@@ -579,6 +579,8 @@ iso88025_input(ifp, m)
 #ifdef INET
 		case ETHERTYPE_IP:
 			th->iso88025_shost[0] &= ~(TR_RII); 
+			if ((m = ip_fastforward(m)) == NULL)
+				return;
 			isr = NETISR_IP;
 			break;
 

Modified: stable/10/sys/netinet/in_var.h
==============================================================================
--- stable/10/sys/netinet/in_var.h	Mon Feb 22 18:53:55 2016	(r295895)
+++ stable/10/sys/netinet/in_var.h	Mon Feb 22 19:17:59 2016	(r295896)
@@ -452,7 +452,7 @@ int	in_scrubprefix(struct in_ifaddr *, u
 void	ip_input(struct mbuf *);
 int	in_ifadown(struct ifaddr *ifa, int);
 void	in_ifscrub(struct ifnet *, struct in_ifaddr *, u_int);
-struct	mbuf	*ip_tryforward(struct mbuf *);
+struct	mbuf	*ip_fastforward(struct mbuf *);
 void	*in_domifattach(struct ifnet *);
 void	in_domifdetach(struct ifnet *, void *);
 

Modified: stable/10/sys/netinet/ip_fastfwd.c
==============================================================================
--- stable/10/sys/netinet/ip_fastfwd.c	Mon Feb 22 18:53:55 2016	(r295895)
+++ stable/10/sys/netinet/ip_fastfwd.c	Mon Feb 22 19:17:59 2016	(r295896)
@@ -109,6 +109,12 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/in_cksum.h>
 
+static VNET_DEFINE(int, ipfastforward_active);
+#define	V_ipfastforward_active		VNET(ipfastforward_active)
+
+SYSCTL_VNET_INT(_net_inet_ip, OID_AUTO, fastforwarding, 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)
 {
@@ -153,7 +159,7 @@ ip_findroute(struct route *ro, struct in
  * to ip_input for full processing.
  */
 struct mbuf *
-ip_tryforward(struct mbuf *m)
+ip_fastforward(struct mbuf *m)
 {
 	struct ip *ip;
 	struct mbuf *m0 = NULL;
@@ -161,20 +167,119 @@ ip_tryforward(struct mbuf *m)
 	struct sockaddr_in *dst = NULL;
 	struct ifnet *ifp;
 	struct in_addr odest, dest;
-	uint16_t ip_len, ip_off;
+	uint16_t sum, ip_len, ip_off;
 	int error = 0;
-	int mtu;
+	int hlen, mtu;
 	struct m_tag *fwd_tag = NULL;
 
 	/*
 	 * Are we active and forwarding packets?
 	 */
+	if (!V_ipfastforward_active || !V_ipforwarding)
+		return m;
 
 	M_ASSERTVALID(m);
 	M_ASSERTPKTHDR(m);
 
 	bzero(&ro, sizeof(ro));
 
+	/*
+	 * Step 1: check for packet drop conditions (and sanity checks)
+	 */
+
+	/*
+	 * Is entire packet big enough?
+	 */
+	if (m->m_pkthdr.len < sizeof(struct ip)) {
+		IPSTAT_INC(ips_tooshort);
+		goto drop;
+	}
+
+	/*
+	 * Is first mbuf large enough for ip header and is header present?
+	 */
+	if (m->m_len < sizeof (struct ip) &&
+	   (m = m_pullup(m, sizeof (struct ip))) == NULL) {
+		IPSTAT_INC(ips_toosmall);
+		return NULL;	/* mbuf already free'd */
+	}
+
+	ip = mtod(m, struct ip *);
+
+	/*
+	 * Is it IPv4?
+	 */
+	if (ip->ip_v != IPVERSION) {
+		IPSTAT_INC(ips_badvers);
+		goto drop;
+	}
+
+	/*
+	 * Is IP header length correct and is it in first mbuf?
+	 */
+	hlen = ip->ip_hl << 2;
+	if (hlen < sizeof(struct ip)) {	/* minimum header length */
+		IPSTAT_INC(ips_badhlen);
+		goto drop;
+	}
+	if (hlen > m->m_len) {
+		if ((m = m_pullup(m, hlen)) == NULL) {
+			IPSTAT_INC(ips_badhlen);
+			return NULL;	/* mbuf already free'd */
+		}
+		ip = mtod(m, struct ip *);
+	}
+
+	/*
+	 * Checksum correct?
+	 */
+	if (m->m_pkthdr.csum_flags & CSUM_IP_CHECKED)
+		sum = !(m->m_pkthdr.csum_flags & CSUM_IP_VALID);
+	else {
+		if (hlen == sizeof(struct ip))
+			sum = in_cksum_hdr(ip);
+		else
+			sum = in_cksum(m, hlen);
+	}
+	if (sum) {
+		IPSTAT_INC(ips_badsum);
+		goto drop;
+	}
+
+	/*
+	 * Remember that we have checked the IP header and found it valid.
+	 */
+	m->m_pkthdr.csum_flags |= (CSUM_IP_CHECKED | CSUM_IP_VALID);
+
+	ip_len = ntohs(ip->ip_len);
+
+	/*
+	 * Is IP length longer than packet we have got?
+	 */
+	if (m->m_pkthdr.len < ip_len) {
+		IPSTAT_INC(ips_tooshort);
+		goto drop;
+	}
+
+	/*
+	 * Is packet longer than IP header tells us? If yes, truncate packet.
+	 */
+	if (m->m_pkthdr.len > ip_len) {
+		if (m->m_len == m->m_pkthdr.len) {
+			m->m_len = ip_len;
+			m->m_pkthdr.len = ip_len;
+		} else
+			m_adj(m, ip_len - m->m_pkthdr.len);
+	}
+
+	/*
+	 * Is packet from or to 127/8?
+	 */
+	if ((ntohl(ip->ip_dst.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET ||
+	    (ntohl(ip->ip_src.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) {
+		IPSTAT_INC(ips_badaddr);
+		goto drop;
+	}
 
 #ifdef ALTQ
 	/*
@@ -185,10 +290,12 @@ ip_tryforward(struct mbuf *m)
 #endif
 
 	/*
-	 * Only IP packets without options
+	 * Step 2: fallback conditions to normal ip_input path processing
 	 */
-	ip = mtod(m, struct ip *);
 
+	/*
+	 * Only IP packets without options
+	 */
 	if (ip->ip_hl != (sizeof(struct ip) >> 2)) {
 		if (V_ip_doopts == 1)
 			return m;

Modified: stable/10/sys/netinet/ip_input.c
==============================================================================
--- stable/10/sys/netinet/ip_input.c	Mon Feb 22 18:53:55 2016	(r295895)
+++ stable/10/sys/netinet/ip_input.c	Mon Feb 22 19:17:59 2016	(r295896)
@@ -77,8 +77,6 @@ __FBSDID("$FreeBSD$");
 #include <netinet/ip_carp.h>
 #ifdef IPSEC
 #include <netinet/ip_ipsec.h>
-#include <netipsec/ipsec.h>
-#include <netipsec/key.h>
 #endif /* IPSEC */
 
 #include <sys/socketvar.h>
@@ -466,22 +464,12 @@ tooshort:
 		} else
 			m_adj(m, ip_len - m->m_pkthdr.len);
 	}
-	/* Try to forward the packet, but if we fail continue */
 #ifdef IPSEC
-	/* For now we do not handle IPSEC in tryforward. */
-	if (!key_havesp(IPSEC_DIR_INBOUND) && !key_havesp(IPSEC_DIR_OUTBOUND) &&
-	    (V_ipforwarding == 1))
-		if (ip_tryforward(m) == NULL)
-			return;
 	/*
 	 * Bypass packet filtering for packets previously handled by IPsec.
 	 */
 	if (ip_ipsec_filtertunnel(m))
 		goto passin;
-#else
-	if (V_ipforwarding == 1)
-		if (ip_tryforward(m) == NULL)
-			return;
 #endif /* IPSEC */
 
 	/*



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