summaryrefslogtreecommitdiff
path: root/sys/netinet6/frag6.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet6/frag6.c')
-rw-r--r--sys/netinet6/frag6.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/sys/netinet6/frag6.c b/sys/netinet6/frag6.c
index 18ef0b035ec..5f8b007d2ce 100644
--- a/sys/netinet6/frag6.c
+++ b/sys/netinet6/frag6.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: frag6.c,v 1.41 2012/01/23 18:37:20 bluhm Exp $ */
+/* $OpenBSD: frag6.c,v 1.42 2012/01/24 19:08:46 bluhm Exp $ */
/* $KAME: frag6.c,v 1.40 2002/05/27 21:40:31 itojun Exp $ */
/*
@@ -235,6 +235,20 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
/* offset now points to data portion */
offset += sizeof(struct ip6_frag);
+ /*
+ * draft-gont-6man-ipv6-atomic-fragments-00: A host that receives an
+ * IPv6 packet which includes a Fragment Header with the "Fragment
+ * Offset" equal to 0 and the "M" bit equal to 0 MUST process such
+ * packet in isolation from any other packets/fragments.
+ */
+ fragoff = ntohs(ip6f->ip6f_offlg & IP6F_OFF_MASK);
+ if (fragoff == 0 && !(ip6f->ip6f_offlg & IP6F_MORE_FRAG)) {
+ ip6stat.ip6s_reassembled++;
+ in6_ifstat_inc(dstifp, ifs6_reass_ok);
+ *offp = offset;
+ return ip6f->ip6f_nxt;
+ }
+
IP6Q_LOCK();
/*
@@ -291,7 +305,6 @@ frag6_input(struct mbuf **mp, int *offp, int proto)
* If it's 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);
if (fragoff == 0) {
q6->ip6q_unfrglen = offset - sizeof(struct ip6_hdr) -
sizeof(struct ip6_frag);