svn commit: r350746 - head/sys/netinet6

Bjoern A. Zeeb bz at FreeBSD.org
Thu Aug 8 09:42:58 UTC 2019


Author: bz
Date: Thu Aug  8 09:42:57 2019
New Revision: 350746
URL: https://svnweb.freebsd.org/changeset/base/350746

Log:
  frag6.c: initial comment and whitespace cleanup.
  
  Cleanup some comments (start with upper case, ends in punctuation,
  use width and do not consume vertical space).  Update comments to
  RFC8200.  Some whitespace changes.
  
  No functional changes.
  
  MFC after:		3 months
  Sponsored by:		Netflix

Modified:
  head/sys/netinet6/frag6.c

Modified: head/sys/netinet6/frag6.c
==============================================================================
--- head/sys/netinet6/frag6.c	Thu Aug  8 08:23:27 2019	(r350745)
+++ head/sys/netinet6/frag6.c	Thu Aug  8 09:42:57 2019	(r350746)
@@ -60,16 +60,14 @@ __FBSDID("$FreeBSD$");
 #include <netinet/ip6.h>
 #include <netinet6/ip6_var.h>
 #include <netinet/icmp6.h>
-#include <netinet/in_systm.h>	/* for ECN definitions */
-#include <netinet/ip.h>		/* for ECN definitions */
+#include <netinet/in_systm.h>	/* For ECN definitions. */
+#include <netinet/ip.h>		/* For ECN definitions. */
 
 #ifdef MAC
 #include <security/mac/mac_framework.h>
 #endif
 
-/*
- * Reassembly headers are stored in hash buckets.
- */
+/* Reassembly headers are stored in hash buckets. */
 #define	IP6REASS_NHASH_LOG2	10
 #define	IP6REASS_NHASH		(1 << IP6REASS_NHASH_LOG2)
 #define	IP6REASS_HMASK		(IP6REASS_NHASH - 1)
@@ -211,8 +209,7 @@ ip6_deletefraghdr(struct mbuf *m, int offset, int wait
 }
 
 /*
- * Free a fragment reassembly header and all
- * associated datagrams.
+ * Free a fragment reassembly header and all associated datagrams.
  */
 static void
 frag6_freef(struct ip6q *q6, uint32_t bucket)
@@ -235,17 +232,18 @@ frag6_freef(struct ip6q *q6, uint32_t bucket)
 		if (af6->ip6af_off == 0) {
 			struct ip6_hdr *ip6;
 
-			/* adjust pointer */
+			/* Adjust pointer. */
 			ip6 = mtod(m, struct ip6_hdr *);
 
-			/* restore source and destination addresses */
+			/* Restore source and destination addresses. */
 			ip6->ip6_src = q6->ip6q_src;
 			ip6->ip6_dst = q6->ip6q_dst;
 
 			icmp6_error(m, ICMP6_TIME_EXCEEDED,
-				    ICMP6_TIME_EXCEED_REASSEMBLY, 0);
+			    ICMP6_TIME_EXCEED_REASSEMBLY, 0);
 		} else
 			m_freem(m);
+
 		free(af6, M_FRAG6);
 	}
 	frag6_remque(q6, bucket);
@@ -258,27 +256,27 @@ frag6_freef(struct ip6q *q6, uint32_t bucket)
 }
 
 /*
- * In RFC2460, fragment and reassembly rule do not agree with each other,
- * in terms of next header field handling in fragment header.
+ * Like in RFC2460, in RFC8200, fragment and reassembly rules do not agree with
+ * each other, in terms of next header field handling in fragment header.
  * While the sender will use the same value for all of the fragmented packets,
- * receiver is suggested not to check the consistency.
+ * receiver is suggested not to check for consistency.
  *
- * fragment rule (p20):
- *	(2) A Fragment header containing:
- *	The Next Header value that identifies the first header of
- *	the Fragmentable Part of the original packet.
+ * Fragment rules (p18,p19):
+ *	(2)  A Fragment header containing:
+ *	The Next Header value that identifies the first header
+ *	after the Per-Fragment headers of the original packet.
  *		-> next header field is same for all fragments
  *
- * reassembly rule (p21):
- *	The Next Header field of the last header of the Unfragmentable
- *	Part is obtained from the Next Header field of the first
+ * Reassembly rule (p20):
+ *	The Next Header field of the last header of the Per-Fragment
+ *	headers is obtained from the Next Header field of the first
  *	fragment's Fragment header.
  *		-> should grab it from the first fragment only
  *
  * The following note also contradicts with fragment rule - no one is going to
  * send different fragment with different next header field.
  *
- * additional note (p22):
+ * Additional note (p22) [not an error]:
  *	The Next Header values in the Fragment headers of different
  *	fragments of the same original packet may differ.  Only the value
  *	from the Offset zero fragment packet is used for reassembly.
@@ -287,7 +285,7 @@ frag6_freef(struct ip6q *q6, uint32_t bucket)
  * There is no explicit reason given in the RFC.  Historical reason maybe?
  */
 /*
- * Fragment input
+ * Fragment input.
  */
 int
 frag6_input(struct mbuf **mp, int *offp, int proto)
@@ -322,13 +320,14 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
 #endif
 
 	dstifp = NULL;
-	/* find the destination interface of the packet. */
+	/* Find the destination interface of the packet. */
 	ia = in6ifa_ifwithaddr(&ip6->ip6_dst, 0 /* XXX */);
 	if (ia != NULL) {
 		dstifp = ia->ia_ifp;
 		ifa_free(&ia->ia_ifa);
 	}
-	/* jumbo payload can't contain a fragment header */
+
+	/* Jumbo payload cannot contain a fragment header. */
 	if (ip6->ip6_plen == 0) {
 		icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, offset);
 		in6_ifstat_inc(dstifp, ifs6_reass_fail);
@@ -336,8 +335,8 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
 	}
 
 	/*
-	 * check whether fragment packet's fragment length is
-	 * multiple of 8 octets.
+	 * Check whether fragment packet's fragment length is a
+	 * multiple of 8 octets (unless it is the last one).
 	 * sizeof(struct ip6_frag) == 8
 	 * sizeof(struct ip6_hdr) = 40
 	 */
@@ -352,16 +351,17 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
 	IP6STAT_INC(ip6s_fragments);
 	in6_ifstat_inc(dstifp, ifs6_reass_reqd);
 
-	/* offset now points to data portion */
+	/* Offset now points to data portion. */
 	offset += sizeof(struct ip6_frag);
 
 	/*
 	 * Handle "atomic" fragments (offset and m bit set to 0) upfront,
-	 * unrelated to any reassembly (see RFC 6946 and section 4.5 of RFC
-	 * 8200).  Just skip the fragment header.
+	 * unrelated to any reassembly.  Still need to remove the frag hdr.
+	 * See RFC 6946 and section 4.5 of RFC 8200.
 	 */
 	if ((ip6f->ip6f_offlg & ~IP6F_RESERVED_MASK) == 0) {
 		IP6STAT_INC(ip6s_atomicfrags);
+		/* XXX-BZ handle correctly. */
 		in6_ifstat_inc(dstifp, ifs6_reass_ok);
 		*offp = offset;
 		m->m_flags |= M_FRAGMENTED;
@@ -378,6 +378,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
 		return IPPROTO_DONE;
 	}
 
+	/* Generate a hash value for fragment bucket selection. */
 	hashkeyp = hashkey;
 	memcpy(hashkeyp, &ip6->ip6_src, sizeof(struct in6_addr));
 	hashkeyp += sizeof(struct in6_addr) / sizeof(*hashkeyp);
@@ -390,7 +391,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
 	IP6QB_LOCK(bucket);
 
 	/*
-	 * Enforce upper bound on number of fragments.
+	 * Enforce upper bound on number of fragments for the entire system.
 	 * If maxfrag is 0, never accept fragments.
 	 * If maxfrag is -1, accept all fragments without limitation.
 	 */
@@ -410,9 +411,8 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
 			break;
 
 	if (q6 == head) {
-		/*
-		 * the first fragment to arrive, create a reassembly queue.
-		 */
+
+		/* The first fragment to arrive, create a reassembly queue. */
 		first_frag = 1;
 
 		/*
@@ -429,6 +429,8 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
 		    (u_int)V_ip6_maxfragpackets)
 			goto dropfrag;
 		atomic_add_int(&V_frag6_nfragpackets, 1);
+
+		/* Allocate IPv6 fragement packet queue entry. */
 		q6 = (struct ip6q *)malloc(sizeof(struct ip6q), M_FRAG6,
 		    M_NOWAIT | M_ZERO);
 		if (q6 == NULL)
@@ -442,7 +444,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
 #endif
 		frag6_insque_head(q6, head, bucket);
 
-		/* ip6q_nxt will be filled afterwards, from 1st fragment */
+		/* ip6q_nxt will be filled afterwards, from 1st fragment. */
 		q6->ip6q_down	= q6->ip6q_up = (struct ip6asfrag *)q6;
 #ifdef notyet
 		q6->ip6q_nxtp	= (u_char *)nxtp;
@@ -459,7 +461,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
 	}
 
 	/*
-	 * If it's the 1st fragment, record the length of the
+	 * If it is the 1st fragment, record the length of the
 	 * unfragmentable part and the next header of the fragment header.
 	 */
 	fragoff = ntohs(ip6f->ip6f_offlg & IP6F_OFF_MASK);
@@ -491,7 +493,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
 		return (IPPROTO_DONE);
 	}
 	/*
-	 * If it's the first fragment, do the above check for each
+	 * If it is the first fragment, do the above check for each
 	 * fragment already stored in the reassembly queue.
 	 */
 	if (fragoff == 0) {
@@ -505,11 +507,11 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
 				struct ip6_hdr *ip6err;
 				int erroff = af6->ip6af_offset;
 
-				/* dequeue the fragment. */
+				/* Dequeue the fragment. */
 				frag6_deq(af6, bucket);
 				free(af6, M_FRAG6);
 
-				/* adjust pointer. */
+				/* Adjust pointer. */
 				ip6err = mtod(merr, struct ip6_hdr *);
 
 				/*
@@ -527,6 +529,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
 		}
 	}
 
+	/* Allocate an IPv6 fragement queue entry for this fragmented part. */
 	ip6af = (struct ip6asfrag *)malloc(sizeof(struct ip6asfrag), M_FRAG6,
 	    M_NOWAIT | M_ZERO);
 	if (ip6af == NULL)
@@ -542,10 +545,11 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
 		goto insert;
 	}
 
+	/* Do duplicate, condition, and boundry checks. */
 	/*
 	 * Handle ECN by comparing this segment with the first one;
 	 * if CE is set, do not lose CE.
-	 * drop if CE and not-ECT are mixed for the same packet.
+	 * Drop if CE and not-ECT are mixed for the same packet.
 	 */
 	ecn = (ntohl(ip6->ip6_flow) >> 20) & IPTOS_ECN_MASK;
 	ecn0 = q6->ip6q_ecn;
@@ -562,9 +566,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
 		goto dropfrag;
 	}
 
-	/*
-	 * Find a segment which begins after this one does.
-	 */
+	/* Find a fragmented part which begins after this one does. */
 	for (af6 = q6->ip6q_down; af6 != (struct ip6asfrag *)q6;
 	     af6 = af6->ip6af_down)
 		if (af6->ip6af_off > ip6af->ip6af_off)
@@ -572,13 +574,11 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
 
 	/*
 	 * If the incoming framgent overlaps some existing fragments in
-	 * the reassembly queue, drop it, since it is dangerous to override
-	 * existing fragments from a security point of view.
-	 * We don't know which fragment is the bad guy - here we trust
-	 * fragment that came in earlier, with no real reason.
-	 *
-	 * Note: due to changes after disabling this part, mbuf passed to
-	 * m_adj() below now does not meet the requirement.
+	 * the reassembly queue, drop both the new fragment and the
+	 * entire reassembly queue.  However, if the new fragment
+	 * is an exact duplicate of an existing fragment, only silently
+	 * drop the existing fragment and leave the fragmentation queue
+	 * unchanged, as allowed by the RFC.  (RFC 8200, 4.5)
 	 */
 	if (af6->ip6af_up != (struct ip6asfrag *)q6) {
 		i = af6->ip6af_up->ip6af_off + af6->ip6af_up->ip6af_frglen
@@ -603,11 +603,9 @@ insert:
 #endif
 
 	/*
-	 * Stick new segment in its place;
-	 * check for complete reassembly.
-	 * If not complete, check fragment limit.
-	 * Move to front of packet queue, as we are
-	 * the most recently active fragmented packet.
+	 * Stick new segment in its place; check for complete reassembly.
+	 * If not complete, check fragment limit.  Move to front of packet
+	 * queue, as we are the most recently active fragmented packet.
 	 */
 	frag6_enq(ip6af, af6->ip6af_up, bucket);
 	atomic_add_int(&frag6_nfrags, 1);
@@ -634,9 +632,7 @@ insert:
 		return IPPROTO_DONE;
 	}
 
-	/*
-	 * Reassembly is complete; concatenate fragments.
-	 */
+	/* Reassembly is complete; concatenate fragments. */
 	ip6af = q6->ip6q_down;
 	t = m = IP6_REASS_MBUF(ip6af);
 	af6 = ip6af->ip6af_down;
@@ -662,7 +658,7 @@ insert:
 		m->m_pkthdr.csum_data = (m->m_pkthdr.csum_data & 0xffff) +
 		    (m->m_pkthdr.csum_data >> 16);
 
-	/* adjust offset to point where the original next header starts */
+	/* Adjust offset to point where the original next header starts. */
 	offset = ip6af->ip6af_offset - sizeof(struct ip6_frag);
 	free(ip6af, M_FRAG6);
 	ip6 = mtod(m, struct ip6_hdr *);
@@ -683,9 +679,7 @@ insert:
 		goto dropfrag;
 	}
 
-	/*
-	 * Store NXT to the original.
-	 */
+	/* Set nxt(-hdr field value) to the original value. */
 	m_copyback(m, ip6_get_prevhdr(m, offset), sizeof(uint8_t),
 	    (caddr_t)&nxt);
 
@@ -723,17 +717,12 @@ insert:
 	in6_ifstat_inc(dstifp, ifs6_reass_ok);
 
 #ifdef RSS
-	/*
-	 * Queue/dispatch for reprocessing.
-	 */
+	/* Queue/dispatch for reprocessing. */
 	netisr_dispatch(NETISR_IPV6_DIRECT, m);
 	return IPPROTO_DONE;
 #endif
 
-	/*
-	 * Tell launch routine the next header
-	 */
-
+	/* Tell launch routine the next header. */
 	*mp = m;
 	*offp = offset;
 
@@ -749,8 +738,7 @@ insert:
 
 /*
  * IPv6 reassembling timer processing;
- * if a timer expires on a reassembly
- * queue, discard it.
+ * if a timer expires on a reassembly queue, discard it.
  */
 void
 frag6_slowtimo(void)
@@ -790,7 +778,7 @@ frag6_slowtimo(void)
 			 * enough to get down to the new limit.
 			 * Note that we drain all reassembly queues if
 			 * maxfragpackets is 0 (fragmentation is disabled),
-			 * and don't enforce a limit when maxfragpackets
+			 * and do not enforce a limit when maxfragpackets
 			 * is negative.
 			 */
 			while ((V_ip6_maxfragpackets == 0 ||
@@ -828,6 +816,9 @@ frag6_slowtimo(void)
 	VNET_LIST_RUNLOCK_NOSLEEP();
 }
 
+/*
+ * Eventhandler to adjust limits in case nmbclusters change.
+ */
 static void
 frag6_change(void *tag)
 {


More information about the svn-src-head mailing list