<p><b>@benpicco</b> commented on this pull request.</p>

<p>This looks very good!<br>
I only have a few minor comments, but I must also say that I'm not familiar with the GNRC internals, so I might not know what to look out for.</p>
<p>The default settings seem a bit confusing though - did I get it right that it will only support one fragment by default?</p><hr>

<p>In <a href="https://github.com/RIOT-OS/RIOT/pull/11596#discussion_r324310015">sys/include/net/gnrc/ipv6/ext.h</a>:</p>
<pre style='color:#555'>> @@ -38,6 +39,40 @@
 extern "C" {
 #endif
 
+/**
+ * @defgroup    net_gnrc_ipv6_ext_conf IPv6 extension header compile configurations
+ * @ingroup     net_gnrc_ipv6_ext
+ * @ingroup     config
+ * @{
+ */
+/**
+ * @brief   IPv6 fragmentation reassembly buffer size
+ *
+ * @note    Only applicable with [gnrc_ipv6_ext_frag](@ref net_gnrc_ipv6_ext_frag) module
+ */
+#ifndef GNRC_IPV6_EXT_FRAG_RBUF_SIZE
+#define GNRC_IPV6_EXT_FRAG_RBUF_SIZE        (1U)
</pre>
<p>So only one fragment is supported as a default?<br>
If I do <code>USEMODULE += gnrc_ipv6_ext_frag</code>, I'd expect my node to receive larger packets than before <g-emoji class="g-emoji" alias="wink" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f609.png">😉</g-emoji></p>

<hr>

<p>In <a href="https://github.com/RIOT-OS/RIOT/pull/11596#discussion_r324313171">sys/include/net/gnrc/ipv6/ext.h</a>:</p>
<pre style='color:#555'>> +/**
+ * @brief   IPv6 fragmentation reassembly buffer size
+ *
+ * @note    Only applicable with [gnrc_ipv6_ext_frag](@ref net_gnrc_ipv6_ext_frag) module
+ */
+#ifndef GNRC_IPV6_EXT_FRAG_RBUF_SIZE
+#define GNRC_IPV6_EXT_FRAG_RBUF_SIZE        (1U)
+#endif
+
+/**
+ * @brief   The number of total allocatable @ref gnrc_ipv6_ext_frag_limits_t objects
+ *
+ * @note    Only applicable with [gnrc_ipv6_ext_frag](@ref net_gnrc_ipv6_ext_frag) module
+ */
+#ifndef GNRC_IPV6_EXT_FRAG_LIMITS_POOL_SIZE
+#define GNRC_IPV6_EXT_FRAG_LIMITS_POOL_SIZE (GNRC_IPV6_EXT_FRAG_RBUF_SIZE * 2U)
</pre>
<p>Why is it twice the size of <code>GNRC_IPV6_EXT_FRAG_RBUF_SIZE</code>?</p>
<p>Since these are both user-configurable it would be good to have a comment about the relationship between them.</p>

<hr>

<p>In <a href="https://github.com/RIOT-OS/RIOT/pull/11596#discussion_r324321707">sys/net/gnrc/network_layer/ipv6/ext/frag/gnrc_ipv6_ext_frag.c</a>:</p>
<pre style='color:#555'>> +        /* first fragment */
+        uint16_t ipv6_len = byteorder_ntohs(ipv6->len);
+
+        /* not divisible by 8*/
+        if ((pkt->size & 0x7)) {
+            DEBUG("ipv6_ext_frag: fragment length not divisible by 8");
+            goto error_exit;
+        }
+        _set_nh(fh_snip->next, nh);
+        gnrc_pktbuf_remove_snip(pkt, fh_snip);
+        /* TODO: RFC 8200 says "- 8"; determine if `sizeof(ipv6_ext_frag_t)` is
+         * really needed*/
+        rbuf->pkt_len += ipv6_len - pkt->size - sizeof(ipv6_ext_frag_t);
+        if (rbuf->pkt != NULL) {
+            /* first fragment but not first arriving */
+            memcpy(rbuf->pkt->data, pkt->data, pkt->size);
</pre>
<p>Are we sure there will always be enough space in <code>rbuf->pkt->data</code>?<br>
I've seen checks for the other cases, but not here - maybe I missed it?</p>

<hr>

<p>In <a href="https://github.com/RIOT-OS/RIOT/pull/11596#discussion_r324326150">sys/net/gnrc/network_layer/ipv6/ext/frag/gnrc_ipv6_ext_frag.c</a>:</p>
<pre style='color:#555'>> +        return _completed(rbuf);
+    }
+    else if (!ipv6_ext_frag_more(fh)) {
+        /* first fragment but actually not fragmented */
+        _set_nh(fh_snip->next, nh);
+        gnrc_pktbuf_remove_snip(pkt, fh_snip);
+        gnrc_ipv6_ext_frag_rbuf_del(rbuf);
+        ipv6->len = byteorder_htons(byteorder_ntohs(ipv6->len) -
+                                    sizeof(ipv6_ext_frag_t));
+        return pkt;
+    }
+    else {
+        /* first fragment */
+        uint16_t ipv6_len = byteorder_ntohs(ipv6->len);
+
+        /* not divisible by 8*/
</pre>
<p>minor nit: space missing</p>

<p style="font-size:small;-webkit-text-size-adjust:none;color:#666;">—<br />You are receiving this because you are subscribed to this thread.<br />Reply to this email directly, <a href="https://github.com/RIOT-OS/RIOT/pull/11596?email_source=notifications&email_token=ABE7WYBUP5IELD7QTSVYMYTQJPQEFA5CNFSM4HQECP7KYY3PNVWWK3TUL52HS4DFWFIHK3DMKJSXC5LFON2FEZLWNFSXPKTDN5WW2ZLOORPWSZGOCEWTHGY#pullrequestreview-288175003">view it on GitHub</a>, or <a href="https://github.com/notifications/unsubscribe-auth/ABE7WYE52D7KQEDEVTM2MC3QJPQEFANCNFSM4HQECP7A">mute the thread</a>.<img src="https://github.com/notifications/beacon/ABE7WYEFDUTO5DAOIU77353QJPQEFA5CNFSM4HQECP7KYY3PNVWWK3TUL52HS4DFWFIHK3DMKJSXC5LFON2FEZLWNFSXPKTDN5WW2ZLOORPWSZGOCEWTHGY.gif" height="1" width="1" alt="" /></p>
<script type="application/ld+json">[
{
"@context": "http://schema.org",
"@type": "EmailMessage",
"potentialAction": {
"@type": "ViewAction",
"target": "https://github.com/RIOT-OS/RIOT/pull/11596?email_source=notifications\u0026email_token=ABE7WYBUP5IELD7QTSVYMYTQJPQEFA5CNFSM4HQECP7KYY3PNVWWK3TUL52HS4DFWFIHK3DMKJSXC5LFON2FEZLWNFSXPKTDN5WW2ZLOORPWSZGOCEWTHGY#pullrequestreview-288175003",
"url": "https://github.com/RIOT-OS/RIOT/pull/11596?email_source=notifications\u0026email_token=ABE7WYBUP5IELD7QTSVYMYTQJPQEFA5CNFSM4HQECP7KYY3PNVWWK3TUL52HS4DFWFIHK3DMKJSXC5LFON2FEZLWNFSXPKTDN5WW2ZLOORPWSZGOCEWTHGY#pullrequestreview-288175003",
"name": "View Pull Request"
},
"description": "View this Pull Request on GitHub",
"publisher": {
"@type": "Organization",
"name": "GitHub",
"url": "https://github.com"
}
}
]</script>