svn commit: r281334 - head/sys/netinet

Gleb Smirnoff glebius at FreeBSD.org
Thu Apr 9 21:32:33 UTC 2015


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) {


More information about the svn-src-head mailing list