This implements a client for DHCPv6 IA_PD (Identity Association for
Prefix Delegation). Goal was to have a IETF-compliant alternative to
UHCP. The implementation was based on RFC 8415.
The comment exists since the introduction of the [original
implementation], but its meaning is unclear and misleading, as the code
doesn't do anything with link-local.
[original implementation]: https://github.com/RIOT-OS/RIOT/pull/3561
Rule 2 of the source address algorithm outlined in [RFC6724] states the
possible source addresses must also be compared among each other:
> Rule 2: Prefer appropriate scope.
> If Scope(SA) < Scope(SB): If Scope(SA) < Scope(D), then prefer SB and
> otherwise prefer SA. Similarly, if Scope(SB) < Scope(SA): If
> Scope(SB) < Scope(D), then prefer SA and otherwise prefer SB.
Our current implementation doesn't do that. It just checks if the scope
of a possible source is lesser than the scope of the destination
(which involves the second "If" in the rule).
This fix grants points according to the scope of an address. If the
scope matches, they get the highest points, ensuring that the selected
source will always be reachable from the destination.
[RFC6724]: https://tools.ietf.org/html/rfc6724
Having the definitions sit in the `net/gnrc/sixlowpan/frag.h` header
does not make much sense, when using Selective Fragment Forwarding
(and the fragmentation buffer already includes a
`net/gnrc/sixlowpan/frag/stats.h` header), so they are moved to their
own header. Since with this change it makes more sense to have the
statistics stored in their own sub-module, the pseudo-module is also
actualized.
A pointer is not 32 bit on all platforms.
Since gnrc_lwmac only stores 16 bit in the pointer variable it is
still save to cast like this even on AVR, but cast to uintptr_t
instead of uint32_t.
fixes#12869
When the destination address is the loopback address (`::1`) in GNRC
the selected network interface typically is `NULL`, as with GNRC no
loopback interface de facto exists. So the assertion when checking if
the source address is valid if `netif != NULL` fails on that check.
This change fixes that issue by checking if the destination address is
the loopback address, before checking the validity of the source
address.
The RTT callback for a super-frame cycle uses the `arg` pointer to set
the message value that then is handed to the GoMacH thread. However,
in both instances the timer is scheduled the constant
`GNRC_GOMACH_EVENT_RTT_NEW_CYCLE` is provided. This means the argument
is not really necessary.
This fits with the semantics of this function which doesn't provide or
uses any state of the reassembly buffer provided by the user, but finds
the entry itself and then removes it. This gives the user no chance to
remove the packet in the reassembly buffer entry, so
`gnrc_sixlowpan_frag_rb_rm_by_datagram()` has to release the packet
(other than `gnrc_sixlowpan_frag_rb_remove()` where not releasing the
packet is desired as it might be handed up to an upper layer).
Right now 'ipv6_addr_split_iface' assumes that the interface specifier
will always be a number (based on GNRC way of identifying interfaces),
but this may not be always the case.In order to be able to use the
Network Interface API, interfaces should be referred by their name.
This changes 'ipv6_addr_split_iface' so it returns a pointer to the
string that specifies the interface.
This allows to set a timer between the completion of a datagram in the
reassembly buffer and the deletion of the corresponding reassembly
buffer entry. This allows to ignore potentially late incoming link-layer
duplicates of fragments of the datagram that then will have the
reassembly buffer entry be blocked.
This was noted in this [discussion] for classic 6LoWPAN reassembly (and
minimal fragment forwarding) and is recommended in the current
[selective fragment recovery draft][SFR draft].
[discussion]: https://mailarchive.ietf.org/arch/msg/6lo/Ez0tzZDqawVn6AFhYzAFWUOtJns
[SFR draft]: https://tools.ietf.org/html/draft-ietf-6lo-fragment-recovery-07#section-6
As analyzed in #12678 there are cases where different reports can be
generated for the different snips of the packet send via the `sock`.
To catch all errors generated by the stack, the sock has to subscribe
for all snips of the packet sent. If any of the snips reports an error
distinct from `GNRC_NETERR_SUCCESS` or the previous one, we report that
status instead of just the first we receive. This way we are ensured to
have the first error reported by the stack for the given packet.
The name `fragment_msg` or `frag_msg`/`msg_frag` always to me was a bit
misplaced, as it basically implements an asynchronous fragmentation
buffer and doesn't necessarily have anything to do with messages.
This change
1. changes the name to `fb` (for fragmentation buffer)
2. factors its code out to its own sub-module so it can be re-used by
other 6LoWPAN fragmentation schemes like [Selective Fragment
Recovery]
[Selective Fragment Recovery]: https://tools.ietf.org/html/draft-ietf-6lo-fragment-recovery-05
The interface is already fetched in the beginning of the function and
doesn't change during its run, so getting the interface again at this
point is just redundant.
When decoding IPHC in a fragmented datagram, relying on the size of the
allocated space for the decoded packet is wrong when fragments are
forwarded and decoded on an intermediate node (for which the reassembly
buffer's space is used): Using the full datagram size for allocation in
this case would be wasteful, so the allocated space is only marginally
larger than the fragment's compressed form.
This in turn results in the wrong UDP payload size being chosen and
even worse being forwarded to the subsequent nodes.
This change uses the (virtual) reassembly buffer's `datagram_size`
instead of relying on the allocated space for the encoded
datagram/fragment.
`_match_to_idx()` was removed from source address selection (which was
the only one setting the filter parameter to a non-NULL value), so it
is the parameter is not needed anymore.
When source address selection is done, both RFC and comments in the code
state, that a longest prefix match should *only* be used as a
tie-breaker between more than one viable candidate. If there is only one
address, there is
a) no need for a tie-breaker
b) in the case of either the destination address or the single remaining
address being ULAs ([which are considered to be of global scope]
[RFC4193]) possibly not matching, as `fd00::/7` and e.g. `2001::/8`
do not have a common prefix.
(b) in fact causes the match function to return -1, causing the source
address selection to return -1, causing the outer function to return the
first address it found (which most often is the link-local address),
causing e.g. a ping to an ULA to fail, even is there is a global
address.
[RFC4193]: https://tools.ietf.org/html/rfc4193
Different platforms evaluate `printf()` for NULL pointers differently,
resulting tests checking for a certain output to fail. This unifies that
(debug) output for the static packet buffer statistics.
Similar as with #12513, when the NIB is compiled in 6LN mode (but not
6LR mode), the address-resolution state-machine (ARSM) functionality is
disabled in favor of the more simpler address resolution proposed in RFC
6775.
However, if a non-6LN interface is also compiled in (without making it
a router or border router) it will never join the solicited-nodes
multicast address of addresses added to it, resulting in address
resolution to that interface to fail.
If the interface is not a 6LN (which in case 6LN mode is disabled is
always false), a warning is now printed, encouraging the user to
activate the ARSM functionality if needed.
When the NIB is compiled for 6LN mode (but not a 6LBR), the Stateless
Address Autoconfiguration (SLAAC) functionality is disabled, as it is
typically not required; see `sys/include/net/gnrc/ipv6/nib/conf.h`, ll.
46 and 55. However, if a non-6LN interface is also compiled in (still
without making the node a border router) an auto-configured address will
be assigned in accordance with [RFC 6775] to the interface, just
assuming the interface is a 6LN interface. As it then only performs
duplicate address detection RFC-6775-style then, the address then never
becomes valid, as the duplicate address detection according to [RFC
4862] (part of the SLAAC functionality) is never performed.
As auto-configuring an address without SLAAC doesn't make sense, this
fix makes the interface skip it completely, but provides a warning to
the user, so they know what to do.
[RFC 6775]: https://tools.ietf.org/html/rfc6775#section-5.2
[RFC 4862]: https://tools.ietf.org/html/rfc4862#section-5.4
The functions now are semantic distinct:
- gnrc_netif_is_6lo(): the interface is a 6Lo interface
- gnrc_netif_is_6ln(): the interface is using Neighbor Discovery
according to RFC 6775
We want to check if the interface is an interface requiring the 6Lo
adaptation layer, not if it is a 6LN according to RFC 6775 [[1]].
[1]: https://tools.ietf.org/html/rfc6775#section-2
When writing to the IPv6 header the implementation currently doesn't
take the packet with the (potentially) duplicated header, but the
packet with the original one, which leads to the packet sent and then
released in `gnrc_netif_ethernet.c` first and then accessed again in
further iterations of the "writing to the IPv6 header" loop, which
causes access to an invalid pointer, causing a crash.
Fixes#11980
While 485dbd1fda (from #12175) was right
in assuming that the for most ICMPv6 error messages the originating
packet's destination address must not be a multicast, this is not the
case for _all_ ICMPv6 error messages (see [RFC 4443], section 2.4(e.3)).
Additionally, 485dbd1fda removed the
check for the source address ([RFC 4443], section 2.4(e.6)), which this
PR re-adds.
[RFC 4443]: https://tools.ietf.org/html/rfc4443#section-2.4
Rather than dispatching the packet automatically once it is complete,
`gnrc_sixlowpan_frag_rb_add()` now only returns success, and leaves it
to the caller to dispatch the packet.
While it is correct to not use an invalid address as a source address,
it is incorrect to assume that addresses not assigned to the interface
(`idx == -1` in the respective piece of code) are invalid: Other than
classic forwarding via a FIB, forwarded packets utilizing a IPv6
routing header will pass this check, like any other packet sent by this
node. The source address for these is not on the given node, so e.g.
source routing is not possible at the moment.
The IPv6 (extension) headers of the first fragment received are re-used
for the reassembled packet, so when receiving a subsequent packet we
need to distinguish, if we just want to release the payload or all of
the packet after the packet data was added to the reassembly buffer.