From owner-svn-src-stable-10@freebsd.org Mon Feb 22 19:18:01 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 74380AB0184; Mon, 22 Feb 2016 19:18:01 +0000 (UTC) (envelope-from gnn@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 3713714E0; Mon, 22 Feb 2016 19:18:01 +0000 (UTC) (envelope-from gnn@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u1MJI0Uu070110; Mon, 22 Feb 2016 19:18:00 GMT (envelope-from gnn@FreeBSD.org) Received: (from gnn@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u1MJHxJm070096; Mon, 22 Feb 2016 19:17:59 GMT (envelope-from gnn@FreeBSD.org) Message-Id: <201602221917.u1MJHxJm070096@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: gnn set sender to gnn@FreeBSD.org using -f From: "George V. Neville-Neil" Date: Mon, 22 Feb 2016 19:17:59 +0000 (UTC) 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 X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 22 Feb 2016 19:18:01 -0000 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 +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 #ifdef IPSEC #include -#include -#include #endif /* IPSEC */ #include @@ -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 */ /*