Subject: [6lo] Benjamin Kaduk's Discuss on draft-ietf-6lo-fragment-recovery-13: (with DISCUSS and COMMENT)

From: Benjamin Kaduk via Datatracker <[email-masked]>
Date: Tue, 18 Feb 2020 14:19:53 -0800

Benjamin Kaduk has entered the following ballot position for
draft-ietf-6lo-fragment-recovery-13: Discuss

When responding, please keep the subject line intact and reply to all
email addresses included in the To and CC lines. (Feel free to cut this
introductory paragraph, however.)

Please refer to https://www.ietf.org/iesg/statement/discuss-criteria.html
for more information about IESG DISCUSS and COMMENT positions.

The document, along with other ballot positions, can be found here:
https://datatracker.ietf.org/doc/draft-ietf-6lo-fragment-recovery/

----------------------------------------------------------------------
DISCUSS:
----------------------------------------------------------------------

In Section 2.3 we refer to the datagram_tag plus layer-2 sender
address as being "a globally unique identifier for the datagram", but I
think this can only hold within some time-bounded window (e.g., the
lifetime of the packet), since the tag space is finite and reuse
somewhat inevitable.  [The simplest way to resolve this is probably to
just remove the definition from this document and refer to
draft-ietf-6lo-minimal-fragment for definitions.]

I think we should be more clear about whether a "FULL bitmap" always has
32 bits set to one, or if "merely" having as many bits as the sender
sent fragments set to one also counts as "FULL".  The current text seems
to invite different interpretations by implementations.  (If FULL does
mean all 32 bits, then the semantics of the other case seem unclear to
me.)

What's the transition/backwards-compatibility story?  That is, how does
a sender know that all nodes on the path support the RFRAG dispatch
types, and what happens if they are sent anyway and get to a node that
doesn't implement them?

I have grave misgivings about allowing a packet (as identified by sender
and tag) to be refragmented by the sender so that a single fragment
sequence number is used for fragments of different lengths.  We do not
seem to provide a mechanism to distinguish which variant of that
fragment is being ack'd, which could lead to disagreement between sender
and receiver as to whether a full packet is reconstructed.
Brainstorming, it might be possible to allow such refragmenting at the
sender by using a Fragment_Size of zero to indicate "this fragment is
superseded" and allocating new sequence number for all its components.
(I didn't attempt to do an exhaustive check on whether that proposal is
flawed and Fragment_Size of zero already has some existing semantics
that would be in conflict.)

----------------------------------------------------------------------
COMMENT:
----------------------------------------------------------------------

It might be worth mentioning that whereas the RFC 4944 fragmentation
procedures uses different dispatch types for the first fragment and
subsequent fragments, we have no need to do so (the first fragment is
identified by sequence number zero).

I have a question about the "stickiness" of per-fragment ECN markings.
That is, suppose that fragment 1 is marked as having experienced
congestion when it arrives at the recipient.  The sender requests an ACK
after fragment 4, and the recipient duly sets the E bit in the ack.
Suppose that fragments 5 through 9 then arrive with no congestion
indicated, and fragment 9 requests and ACK.  Does this new ACK still
have to set the E bit since, as discussed in Section 5.2, "at least one
of the acknowledged fragments was received with an Explicit Congestion
Notification"?  My (very very non-expert) recollection is that we tend
to say that any given ECN marking should produce at most one "congestion
present" response on the return path.

Section 1

   LLNs.  One critical issue with this original design is that routing
   an IPv6 [RFC8200] packet across a route-over mesh requires
   reassembling the full packet at each hop, which may cause latency
   along a path and an overall buffer bloat in the network.  The "6TiSCH

I think I encountered at least one good reference for this statement
during my reading this week (posibly just -minimal-fragment, but maybe
something referenced from there?); it might be nice to help with
cross-linking.

   That problem is exacerbated when forwarding fragments over multiple
   hops since a loss at an intermediate hop will not be discovered by
   either the source or the destination, and the source will keep on
   sending fragments, wasting even more resources in the network and
   possibly contributing to the condition that caused the loss to no
   avail since the datagram cannot arrive in its entirety.  [...]

nit: I'm not sure that "to no avail" is placed properly.

Section 2.2

   "LLN Minimal Fragment Forwarding" [I-D.ietf-6lo-minimal-fragment]
   introduces the generic concept of a Virtual Reassembly Buffer (VRB)

It's perhaps debatable whether -minimal-fragment vs. lwig-vrb really
"introduces" the concept -- draft-ietf-6lo-minimal-fragment-12 doesn't
really say very much about it, to me.

   and specifies behaviours and caveats that are common to a large
   family of FF techniques including this, which fully inherits from
   that specification.

nit: I'd suggest rewording "including this" for clarity, perhaps
"including the mechanism specified by this document".

Section 2.3

   6LoWPAN endpoints:  The LLN nodes in charge of generating or
      expanding a 6LoWPAN header from/to a full IPv6 packet.  The
      6LoWPAN endpoints are the points where fragmentation and
      reassembly take place.

[-minimal-fragment also defines this, and many of the other terms we
define here, with minimal-but-nonzero variation.  Given that we already
have a normative dependency on that document, perhaps we should pull
definitions from it as well, instead of repeating them?  If not, I note
that on -minimal-fragment, I commented:
nit: I think they are only "the [only] points" where
fragmentation/reassembly happen if the entire newtork is using fragment
forwarding; in other cases some intermediate nodes will also reassemble
and (re)fragment.]

Section 4.1

   This specification cannot allow this operation since fragments are
   recovered end-to-end based on a sequence number.  This means that the

I suggest s/this operation/such a refragmentation operation/.

   fragments that contain a 6LoWPAN-compressed header MUST have enough
   slack to enable a less efficient compression in the next hops that
   still fits in one MAC frame.  For instance, if the IID of the source

(This assumes a homogeneous MAC mesh, an assumption that might be worth
making explicit.

   IPv6 address is elided by the originator, then it MUST compute the
   Fragment_Size as if the MTU was 8 bytes less.  This way, the next hop
   can restore the source IID to the first fragment without impacting
   the second fragment.

Is it worth noting that this to large extent obviates the benefits of
header compression?

Section 4.2

   This specification introduces a concept of an inter-frame gap, which
   is a configurable interval of time between transmissions to the same

I think draft-ietf-6lo-minimal-fragment also talks about an "inter-frame
gap", though in less detail.

Section 4.3

   The compression of the Hop Limit, of the source and destination
   addresses in the IPv6 Header, and of the Routing Header may change en
   route in a Route-Over mesh LLN.  If the size of the first fragment is
   modified, then the intermediate node MUST adapt the Datagram_Size to
   reflect that difference.

Hmm, if this really only affects the first fragment, then maybe Section
4.1 could be more clear that the need for extra "slack" in practice only
applies to the first fragment, as well.

   The intermediate node MUST also save the difference of Datagram_Size
   of the first fragment in the VRB and add it to the Datagram_Size and
   to the Fragment_Offset of all the subsequent fragments for that
   datagram.

The RFRAG header does not carry the Datagram_Size, so I think this needs
rewording (we do, however, need to store the updated size to detect the
final fragment).

Section 5

   This specification provides a technique that is derived from MPLS to
   forward individual fragments across a 6LoWPAN route-over mesh without
   reassembly at each hop.  The Datagram_Tag is used as a label; it is
   locally unique to the node that owns the source MAC address of the
   fragment, so together the MAC address and the label can identify the
   fragment globally.  A node may build the Datagram_Tag in its own

(More "globally unique" with implied "lifetime of the packet".)

   locally-significant way, as long as the chosen Datagram_Tag stays
   unique to the particular datagram for the lifetime of that datagram.

[okay, less implied and more explicit here than it was above :) ]

Section 5.1

We discuss the header format, but I don't think we actually say that
"you put the fragment payload after the header" :)

                             1                   2                   3
        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
                                       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                                       |1 1 1 0 1 0 0|E|  Datagram_Tag |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |X| Sequence|   Fragment_Size   |       Fragment_Offset         |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

I strongly suggest a stronger indicator that the field marked
"Fragment_Offset" is also used to carry the Datagram_Size (for sequence
number zero).

   The format of the fragment header is shown in Figure 1.  It is the
   same for all fragments.  The format has a length and an offset, as

(Similarly, this could mention the slight exception to "all fragments".)

   order in which the fragments are received.  This enables out-of-
   sequence subfragmenting, e.g., a fragment seq. 5 that is retried end-
   to-end as smaller fragments seq. 5, 13 and 14 due to a change of MTU
   along the path between the 6LoWPAN endpoints.

Per the Discuss, reusing a sequence number to mean a different fragment
(here, a smaller one) seems pretty risky.  I recall that one of the big
advantages of QUIC over TCP is that we don't reuse sequence numbers for
retransmissions in QUIC, to get better clarity about what exactly is
lost vs. ack'd; reusing a sequence number to mean something with a
different *size* seems qualitatively worse (riskier) to me.

   There is no requirement on the receiver to check for contiguity of
   the received fragments.  The sender knows that the datagram is fully
   received when the acknowledged fragments cover the whole datagram.

But what if there's ambiguity about which version of a fragment
(identified by sequence number) is ack'd?
Also, I'm confused by "no requirement" to check for contiguity;
presumably the receiver also is going to check that it has all the data
in the datagram somehow...

   The first fragment is recognized by a Sequence of 0; it carries its
   Fragment_Size and the Datagram_Size of the compressed packet before
   it is fragmented, whereas the other fragments carry their
   Fragment_Size and Fragment_Offset.  The last fragment for a datagram
   is recognized when its Fragment_Offset and its Fragment_Size add up
   to the Datagram_Size.

I suggest "add up to the stored Datagram_Size of the packet identified
by the sender and Datagram_Tag".

   E:  1 bit; Explicit Congestion Notification; the "E" flag is reset by
      the source of the fragment and set by intermediate routers to
      signal that this fragment experienced congestion along its path.

nit: I suggest s/reset/cleared/.

   Datagram_Tag:  8 bits; an identifier of the datagram that is locally
      unique to the sender.

RFC 4944 had a 16-bit tag field; I would expect some discussion of why
the shorter tag is acceptable now.  I guess that's in the security
considerations, which is okay (albeit not where I would have first
looked).

   Sequence:  5-bit unsigned integer; the sequence number of the
      fragment in the acknowledgement bitmap.  Fragments are numbered
      [0..N] where N is in [0..31].  A Sequence of 0 indicates the first

This implies that a one-fragment packet is allowed (N of 0).  Wouldn't
you just not use the fragmentation framing for the case where the packet
fits in a single frame?

      *  if a VRB already exists and is not broken, the fragment is to
         be forwarded along the associated Label Switched Path (LSP) as
         described in Section 6.1.2, but regardless of the value of the
         Sequence field;

I'm not sure I'm parsing "but regardless of the value of the Sequence
field" properly; if the intent is to say that it is forwarded without
checking the value of the Sequence field, I would remove the "but".
Also, we seem to be intending "is not broken" to match up with "the next
hop is still reachable" in the preceding paragraph; I'd suggest
harmonizing the wording between the two instances.

      *  else, if the Sequence is 0, then the fragment is to be routed
         as described in Section 6.1.1, but no state is conserved
         afterwards.  In that case, the session if it exists is aborted
         and the packet is also forwarded in an attempt to clean up the
         next hops along the path indicated by the IPv6 header (possibly
         including a routing header).

Do we want an "*  else (the Sequence is nonzero and either no VRB exists
or the next hop is unavailable), the fragment is discarded and an abort
RFRAG-ACK is sent back [...]" to replace the last paragraph of the
section?

Section 5.2

   This specification also defines a 4-octet RFRAG Acknowledgment bitmap
   that is used by the reassembling endpoint to confirm selectively the
   reception of individual fragments.  A given offset in the bitmap maps
   one-to-one with a given sequence number and indicates which fragment
   is acknowledged as follows:

[Except it *doesn't* indicate that, since the sequence number is not a
unique fragment identifier if the fragment size can change!]

        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
                                       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                                       |1 1 1 0 1 0 1|E|  Datagram_Tag |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |          RFRAG Acknowledgment Bitmap (32 bits)                |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

I think we need to explicitly say here that the Datagram_Tag, in a
reversal of the previous usage, is scoped to the link-layer *recipient*
of the RFRAG_ACK frame.

Section 6

   that was the originator of the fragments.  To achieve this, each hop
   that performed an MPLS-like operation on fragments reverses that
   operation for the RFRAG_ACK by sending a frame from the next hop to
   the previous hop as known by its MAC address in the VRB.  The

I'm not 100% sure that the previous work in this space (e.g.,
draft-ietf-6lo-minimal-fragment) framed things such that there was a
requirement to be able to perform this "reverse lookup".  It might be
worth calling this out as an additional requirement over the prevoius
fragment-forwarding methodologies...
(We do seem to do so in Section 6.1.1, though I am not sure if it merits
an earlier mention in the document.)

   limiting the number of outstanding fragments, which are the fragments
   that have been sent but for which reception or loss was not
   positively confirmed by the reassembling endpoint.  The maximum

(Do we have a way for *loss* to be "positively confirmed"?  Appendix C
notes that we infer loss from timeout without acknowledgment.)

   The Ack-Request ('X') set in an RFRAG marks the end of a window.
   This flag MUST be set on the last fragment if the sender wishes to
   protect the datagram, and it MAY be set in any intermediate fragment
   for the purpose of flow control.

Is this usage of "protect" conventional or should it get clarified
somewhere?

   This automatic repeat request (ARQ) process MUST be protected by a
   Retransmission Time Out (RTO) timer, and the fragment that carries

nit: I'm not sure that "this" is appropriate yet, since we haven't
really talked about "repeat"ing or retransmission yet.  (Perhaps also
give a bit more discussion about what this ARQ process specifically
entails, too.)

   of times (see Section 7.1).  Upon exhaustion of the retries the
   sender may either abort the transmission of the datagram or retry the
   datagram from the first fragment with an 'X' flag set in order to
   reestablish a path and discover which fragments were received over
   the old path in the acknowledgment bitmap.  When the sender of the

I'm not sure I'm understanding properly what's meant by "retry the
datagram from the first fragment with an 'X' flag set".  My best guess
is that it's saying "re-send the fragment with sequence number 0, and
set the 'X' flag in this new transmission", in which case I'd suggest
s/from the first fragment with an 'X' flag set/from the first fragment,
setting the 'X' flag in the retransmitted fragment,/.

   The receiver MAY issue unsolicited acknowledgments.  An unsolicited
   acknowledgment signals to the sender endpoint that it can resume
   sending if it had reached its maximum number of outstanding
   fragments.  Another use is to inform the sender that the reassembling

How would the sender get into a situation where it has saturated its
transmit window but not requested an ACK?  Is this just the case where
the fragment requesting an ACK gets lost and thus we have to rely on
some timeout (whether at the sender or the receiver) to recover?  It
seems like we may need to define a symbolic constant for the
"unsolicited ACK" timer after no fragments are received, and give some
guidance on how to determine it.

   The RFRAG Acknowledgment can optionally carry an ECN indication for
   flow control (see Appendix C).  The receiver of a fragment with the
   'E' (ECN) flag set MUST echo that information by setting the 'E'
   (ECN) flag in the next RFRAG Acknowledgment.

I'm not sure I'd use the word "optionally" here -- IIUC the idea is to
make it mandatory to implement the ECN behavior, and the ECN indication
is only "optional" in that it is sometimes set, but when it is set and
when it is not set are mandatory parts of the protocol, not subject to
implementation discretion.  If that's correct, then I'd just say "The
RFRAG Acknowledgment carries and ECN indication for flow control".

   round-trip delay in the network.  As the timer runs, the receiving
   endpoint absorbs the fragments that were still in flight for that
   datagram without creating a new state.  The receiving endpoint aborts
   the communication if it keeps going on beyond the duration of the
   timer.

(This "absorbs" the behavior is to catch retransmissions, right?  Might
be worth saying so, though also might not.)
I'd suggest expanding "if it keeps going", perhaps as "if fragments with
matching source and tag continue to be received after the timer
expires".

   Fragments are sent in a round-robin fashion: the sender sends all the
   fragments for a first time before it retries any lost fragment; lost
   fragments are retried in sequence, oldest first.  This mechanism
   enables the receiver to acknowledge fragments that were delayed in
   the network before they are retried.

Is this round-robin within a given "window" or within the entire packet?

   When a single frequency is used by contiguous hops, the sender should

nit: "radio frequency"?  Retransmissions have a frequency, too (though
several orders of magnitude different!).

Section 6.1

   label, which is swapped in each hop.  All fragments follow the same
   path and fragments are delivered in the order in which they are sent.

Where do we make a normative requirement for intermediate nodes to
retain order in transmitting fragments?

Section 6.1.1

   In Route-Over mode, the source and destination MAC addresses in a

It feels surprising to mention Route-Over mode and not have a
corresponding mention of Mesh-Under.

   (and unique) for that source MAC address.  Upon receiving the first
   fragment (i.e., with a Sequence of zero), an intermediate router
   creates a VRB and the associated LSP state for the tuple (source MAC
   address, Datagram_Tag) and the fragment is forwarded along the IPv6
   route that matches the destination IPv6 address in the IPv6 header as
   prescribed by [I-D.ietf-6lo-minimal-fragment], where the receiving
   endpoint allocates a reassembly buffer.

nit: please check the comma usage here (the last one looks misplaced, to
my eye).

   Datagram_Tag.  This reverse LSP state also points at the VRB and
   enables matching the (next MAC address, swapped_Datagram_Tag) found
   in an RFRAG Acknowledgment to the tuple (previous MAC address,

nit(?): doesn't this "reverse lookup" only depend on the
swapped_Datagram_Tag?  I don't think "next MAC address" is needed.

   The first fragment may be received a second time, indicating that it
   did not reach the destination and was retried.  In that case, it
   SHOULD follow the same path as the first occurrence.  It is up to
   sending endpoint to determine whether to abort a transmission and
   then retry it from scratch, which may build an entirely new path.

This seems to be alluding to the text in Section 6 about "or retry the
datagram from the first fragment with an 'X' flag set in order to
reestablish a path", however, my reading of that text is that the same
datagram tag value is used in the retry, in which case the
retransmission of the first fragment seems like it would be
indistinguishable from any other retransmission, to the intermediate
node.  If a new tag was to be allocated, then we would not be able to
get information about fragments received over the old path as Section 6
discusses.  So it seems like this recommendation here ("use the same
path") is at odds with the implied recommendation in the earlier text
("use a potentially different path"), and it would be worth some
discussion to resolve the apparent disparity.

Section 6.1.2

   [I-D.ietf-6lo-minimal-fragment] indicates that the receiving endpoint
   stores "the actual packet data from the fragments received so far, in
   a form that makes it possible to detect when the whole packet has
   been received and can be processed or forwarded".  How this is
   computed is implementation specific but relies on receiving all the
   bytes up to the Datagram_Size indicated in the first fragment.  An
   implementation may receive overlapping fragments as the result of
   retries after an MTU change.

This text leaves me feeling unsatisfied, for a couple reasons:
(1) I have to think to infer that "receiving endpoint" means "the
intermediate router receiving the fragments" and not the ultimate (IPv6)
destination
(2) overlapping fragments that contain different data can be a security
risk, and we don't discuss that here (whether directly or by reference).

Section 6.2

   Upon receipt of an RFRAG-ACK, the router looks up a reverse LSP
   indexed by the tuple (MAC address, Datagram_Tag), which are

(As above, is the MAC address needed here?)

   Either way, if the RFRAG-ACK indicates that the fragment was entirely
   received (FULL bitmap), it arms a short timer, and upon timeout, the
   VRB and all the associated state are destroyed.  Until the timer

Is there anything that could cancel this timer (e.g., an RFRAG-ACK that
with non-FULL bitmap)?

   This specification does not provide a method to discover the number
   of hops or the minimal value of MTU along those hops.  But should the
   minimal MTU decrease, it is possible to retry a long fragment (say
   Sequence of 5) with first a shorter fragment of the same Sequence (5
   again) and then one or more other fragments with a Sequence that was
   not used before (e.g., 13 and 14).  Note that Path MTU Discovery is
   out of scope for this document.

[another mention of sequence number reuse]

Section 6.3

   A reset is signaled on the forward path with a pseudo fragment that
   has the Fragment_Offset, Sequence, and Fragment_Size all set to 0,
   and no data.

The text in Section 5.1 indicates that an abort is characterized by
Fragment_Offset of zero.  I don't think that it has a requirement to set
the other fields to zero in order to be considered an abort.

   When the sender or a router on the way decides that a packet should

nit: I don't think we've used "on the way" previously in this sense (and
do use "on the path").  Though, it looks like we do use "on the way"
again a few paragraphs later.

   The other way around, the receiver might need to abort the process of
   a fragmented packet for internal reasons, for instance if it is out
   of reassembly buffers, already uses all 256 possible values of the
   Datagram_Tag, or if it keeps receiving fragments beyond a reasonable
   time while it considers that this packet is already fully reassembled
   and was passed to the upper layer.  In that case, the receiver SHOULD

nit: s/process/processing/?

Section 7

We can probably inherit discussion of integrity and confidentiality
(non-)protection from -minimal-fragment, assuming my recommended changes
there are made.  It remains the case, though, that intermediate nodes
can always modify the payload and disrupt/deny service, and I, for one,
would not turn down another reminder of that.

   This specification extends "On Forwarding 6LoWPAN Fragments over a
   Multihop IPv6 Network" [I-D.ietf-6lo-minimal-fragment] and requires
   the same parameters in the receiver and on intermediate nodes.  There
   is no new parameter as echoing ECN is always on.  These parameters
   typically include the reassembly time-out at the receiver and an
   inactivity clean-up timer on the intermediate nodes, and the number
   of messages that can be processed in parallel in all nodes.

Do we have a new parameter for the "timer for a receiver node to send an
unsolicited ack if no additional fragments are received"?

   The configuration settings introduced by this specification only
   apply to the sender, which is in full control of the transmission.

(Similarly, this is "full control" modulo acks.)

Section 7.1

   OptWindowSize:  The OptWindowSize is the value for the Window_Size
      that the sender should use to start with.  It is greater than or
      equal to MinWindowSize.  It is less than or equal to
      MaxWindowSize.  The Window_Size should be maintained below the
      number of hops in the path of the fragment to avoid stacking
      fragments at the bottleneck on the path.  If an inter-frame gap is
      used to avoid interference between fragments then the Window_Size
      should be at most on the order of the estimation of the trip time
      divided by the inter-frame gap.

Let's do some dimensional analysis here: the window size is measured in
number of frames, the trip time is measured in time, and the inter-frame
gap is discussed above as an "amount of time" (though whether this is an
absolute time value or a count of transmit windows is perhaps subject to
interpretation).  The ratio of trip time deivided by inter-frame gap,
then, is dimensionless, which we then try to interpret as a number of
frames.  That's probably okay, though mathematics pedants might want
some additional clarifying discussion.

   An implementation may be capable of performing flow control based on
   ECN; see in Appendix C.  This is controlled by the following
   parameter:

   UseECN:  Indicates whether the sender should react to ECN.  The
      sender may react to ECN by varying the Window_Size between
      MinWindowSize and MaxWindowSize, varying the Fragment_Size between
      MinFragmentSize and MaxFragmentSize, and/or by increasing the
      inter-frame gap.

Please forgive the naivite, but shouldn't this parameter merely control
*how* an implementation responds to ECN markings, not *whether or not it
should respond at all* (since obviously it should respond in some
fashion)?

Section 11

I'm not seeing why RFC 6554 (as referenced in one location only) is a
normative reference.

Section 12

Given that "Readers are expected to be familiar with all the terms and
concepts that are discussed in "IPv6 over Low-Power Wireless Personal
Area Networks (6LoWPANs): Overview, Assumptions, Problem Statement, and
Goals" [RFC4919]", RFC 4919 seems like it is more properly categorized
as Normative.  Similarly for RFC 6606.

I don't have strong feelings about RFC 8200's status, though I suppose
one could argue that one needs to parse the network header in order to
route the initial fragment.

Appendix A

   Considering that RFC 4944 defines an MTU is 1280 bytes and that in
   most incarnations (but 802.15.4g) a IEEE Std. 802.15.4 frame can
   limit the MAC payload to as few as 74 bytes, a packet might be

I'm not sure I'm parsing this properly, but I think "except" is more
approriate than "but" in the parenthetical.

Appendix C

   From the standpoint of a source 6LoWPAN endpoint, an outstanding
   fragment is a fragment that was sent but for which no explicit
   acknowledgment was received yet.  This means that the fragment might

Is there also a timer that has to have not expired yet?