Linux doesn't have ARO support at the moment so this is a workaround to
try to speak 6Lo-ND while still being able to do DAD with a border
router that doesn't.
UDP port 0 is reserved for system usage, e.g., to tell the OS to
set a random source port. Hence, neither source nor destination
port should be 0 when transmitting. This PR adds proper asserts.
While `tmp` in the loop for write-protection for the check-sum
calculation is used to check the return value of
`gnrc_pktbuf_start_write()`, it was never overwriting `payload` causing
the original snip to be used in the following iteration `prev` when
duplicated, and destroying the sanity of `ipv6`.
This refactors reception/decoding part of `gnrc_sixlowpan_iphc` to the
more layered approach modeled in #8511. Since the reception part is
already complicated enough I decided to divide send and receive up into
separate changes.
This refactors sending/encoding part of `gnrc_sixlowpan_iphc` to the
more layered approach modeled in #8511. Since the reception part is
already was pretty complicated to refactor, I decided to divide send
and receive up into separate changes.
This will be used in the IPHC refactoring to control the reassembly
buffer as a context.
I also adapted the name of `gnrc_sixlowpan_frag_gc_rbuf()` to be in
line with the rest of the newer functions.
On a NETOPT_STATE set call with NETOPT_STATE_RESET the netdev device
resets the callback event flags. This requires that after the netdev
device resets, the network stack also reapplies these callback event
flags
This change is a gnrc_ipv6_nib/gnrc_netif(2)-based rework of #7210.
Packet duplication
==================
Its main optimization is that it restructures `gnrc_ipv6` handling of
sent packets so that duplication for write-protection happens at the
latest possible step:
* potential `gnrc_netif` headers added by upper layers are
write-protected before their removal
* This unifies the duplication of the IPv6 header directly after
that
* Extension headers in-between the IPv6 header and the payload header
are duplicated just before the check sum is duplicated
Especially the last point allows for only handing a single packet snip
to all lower functions instead of an already searched IPv6 header
(which now is always the first until it is handed to the interface) +
payload header.
Further clean-ups
=================
* Next-hop link-layer address determination was moved to the
`_send_unicast` function, greatly simplifying the unicast case in the
`_send` function
* Code for loopback case was added to a new function `_send_to_self`
* Removed some code duplication
While refactoring IPHC I noticed that the page actually can already be
used for fragmentation: Given @cgundogan's work on [ICN LoWPAN] we can
already assume, that the page context may (among other thing) determine
the type of the reassembled packet. This PR provides the basis for
that.
[ICN LoWPAN]: https://tools.ietf.org/html/draft-gundogan-icnrg-ccnlowpan-01
While the current approach for garbage collection in the 6Lo reassembly
buffer is good for best-effort handling of
*fragmented* packets and nicely RAM saving, it has the problem that
incomplete, huge datagrams can basically DoS a node, if no further
fragmented datagram is received for a while (since the packet buffer is
full and GC is not triggered).
This change adds a asynchronous GC (utilizing the existing
functionality) to the reassembly buffer, so that even if there is no new
fragmented packet received, fragments older than `RBUF_TIMEOUT` will be
removed from the reassembly buffer, freeing up the otherwise wasted
packet buffer space.
Since IPHC also manipulates the total number of bytes of a received
datagram (by decompressing it), this also needs to be exposed. I guess
I was too focused on introducing a *generic* packet buffer for a future
virtual reassembly buffer (where it isn't needed, but so isn't `pkt` to
be honest), that I totally forgot about it in #9352.
This fixes an alignment issue I encountered in the static version of
the packet buffer.
The bug is caused by a race-condition where a certain order of
operations leads to a chunk being released according to the
byte-alignment of the platform, but overlapping potential space for
a future `_unused_t` struct e.g. (x mark allocated regions):
Future leak of size sizeof(_unused_t) Time
v |
+------------+-----+--------------------+ |
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx| +
+------------+-----+--------------------+ |
|
+------------+--+--+--------------------+ |
| |xxxxxxxxxxxxxxxxxxxxxxx| +
+------------+--+--+--------------------+ |
|
+-----+------+--+--+--------------------+ |
|xxxxx| |xxxxxxxxxxxxxxxxxxxxxxx| +
+-----+------+--+--+--------------------+ |
|
+-----+------+-----+---------+----------+ |
|xxxxx| |xxxxxxxxxx| +
+-----+------+-----+---------+----------+ |
|
+-----+------+-----+--------------------+ |
|xxxxx| |xxxxxxxxxxxxxxxxxxxxxxxxxx| +
+-----+------+-----+--------------------+ |
|
+------------+-----+--------------------+ |
|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx| +
+------------+-----+--------------------+ |
|
+------------+-----+--------------------+ |
|xxxxxxxxxxxxxxxxxx| | +
+------------+-----+--------------------+ |
|
+------------+-----+--------------------+ |
| |xxxxx| | +
+------------+-----+--------------------+ |
v
Sadly, I wasn't able to create a reproducable unittest that show-cases
this corner-case, since I don't understand the order of operations that
cause this one 100%, but the bug is reproducable (but also not
reliably) by sending large (i.e. fragmented) packets to a 6Lo-enabled
host from more than 1 host simultaneously (use `gnrc_pktbuf_cmd` to
check).
By making the size of `_unused_t` the only condition for alignment,
this bug is fixed.
This refactors the `gnrc_sixlowpan_frag` module for the API proposed
in #8511.
The `ctx` for `gnrc_sixlowpan_frag_send()` is required to be a
`gnrc_sixlowpan_msg_frag_t` object, so IPHC can later on use it to
provide the *original* datagram size (otherwise, we would need to adapt
the API just for that, which seems to me as convoluted as this
proposal).
I also provide an expose function with a future possibility to provide
more than just one `gnrc_sixlowpan_msg_frag_t` object later on (plus
having cleaner module separation in general).