From owner-svn-src-all@FreeBSD.ORG Thu Apr 9 21:32:33 2015 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id A5F1FD1F; Thu, 9 Apr 2015 21:32:33 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::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 78810E94; Thu, 9 Apr 2015 21:32:33 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t39LWXgG043856; Thu, 9 Apr 2015 21:32:33 GMT (envelope-from glebius@FreeBSD.org) Received: (from glebius@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t39LWXmw043855; Thu, 9 Apr 2015 21:32:33 GMT (envelope-from glebius@FreeBSD.org) Message-Id: <201504092132.t39LWXmw043855@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: glebius set sender to glebius@FreeBSD.org using -f From: Gleb Smirnoff Date: Thu, 9 Apr 2015 21:32:33 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r281334 - head/sys/netinet X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 09 Apr 2015 21:32:33 -0000 Author: glebius Date: Thu Apr 9 21:32:32 2015 New Revision: 281334 URL: https://svnweb.freebsd.org/changeset/base/281334 Log: In the ip_reass() do packet examination and adjusting before acquiring locks and doing lookups. Sponsored by: Nginx, Inc. Modified: head/sys/netinet/ip_input.c Modified: head/sys/netinet/ip_input.c ============================================================================== --- head/sys/netinet/ip_input.c Thu Apr 9 21:30:11 2015 (r281333) +++ head/sys/netinet/ip_input.c Thu Apr 9 21:32:32 2015 (r281334) @@ -938,6 +938,41 @@ ip_reass(struct mbuf *m) ip = mtod(m, struct ip *); hlen = ip->ip_hl << 2; + /* + * Adjust ip_len to not reflect header, + * convert offset of this to bytes. + */ + ip->ip_len = htons(ntohs(ip->ip_len) - hlen); + if (ip->ip_off & htons(IP_MF)) { + /* + * Make sure that fragments have a data length + * that's a non-zero multiple of 8 bytes. + */ + if (ip->ip_len == htons(0) || (ntohs(ip->ip_len) & 0x7) != 0) { + IPSTAT_INC(ips_toosmall); /* XXX */ + IPSTAT_INC(ips_fragdropped); + m_freem(m); + return (NULL); + } + m->m_flags |= M_IP_FRAG; + } else + m->m_flags &= ~M_IP_FRAG; + ip->ip_off = htons(ntohs(ip->ip_off) << 3); + + /* + * Attempt reassembly; if it succeeds, proceed. + * ip_reass() will return a different mbuf. + */ + IPSTAT_INC(ips_fragments); + m->m_pkthdr.PH_loc.ptr = ip; + + /* + * Presence of header sizes in mbufs + * would confuse code below. + */ + m->m_data += hlen; + m->m_len -= hlen; + hash = IPREASS_HASH(ip->ip_src.s_addr, ip->ip_id); head = &V_ipq[hash].head; IPQ_LOCK(hash); @@ -980,40 +1015,6 @@ ip_reass(struct mbuf *m) found: /* - * Adjust ip_len to not reflect header, - * convert offset of this to bytes. - */ - ip->ip_len = htons(ntohs(ip->ip_len) - hlen); - if (ip->ip_off & htons(IP_MF)) { - /* - * Make sure that fragments have a data length - * that's a non-zero multiple of 8 bytes. - */ - if (ip->ip_len == htons(0) || (ntohs(ip->ip_len) & 0x7) != 0) { - IPSTAT_INC(ips_toosmall); /* XXX */ - goto dropfrag; - } - m->m_flags |= M_IP_FRAG; - } else - m->m_flags &= ~M_IP_FRAG; - ip->ip_off = htons(ntohs(ip->ip_off) << 3); - - /* - * Attempt reassembly; if it succeeds, proceed. - * ip_reass() will return a different mbuf. - */ - IPSTAT_INC(ips_fragments); - m->m_pkthdr.PH_loc.ptr = ip; - - /* Previous ip_reass() started here. */ - /* - * Presence of header sizes in mbufs - * would confuse code below. - */ - m->m_data += hlen; - m->m_len -= hlen; - - /* * If first fragment to arrive, create a reassembly queue. */ if (fp == NULL) {