When a VRB entry exists use minfwd to forward.
When a route exist for the first fragment received in reassembly create
a virtual reassembly buffer entry.
Non-routing 6LNs do not have to join the solicited nodes address, so
probing for a neighbor using that address may be in vain and only
spamming the LLN with unnecessary messages. RFC 6775 basically assumes
this in section 5.2:
> There is no need to join the solicited-node multicast address, since
> nobody multicasts NSs in this type of network.
In accordance with RFC 6775, section 5.2 an NCE should be set STALE
when an ARO renews the address registration for the address:
> The routers SHOULD NOT garbage-collect Registered NCEs (see
> Section 3.4), since they need to retain them until the Registration
> Lifetime expires. Similarly, if NUD on the router determines that
> the host is UNREACHABLE (based on the logic in [RFC4861]), the NCE
> SHOULD NOT be deleted but rather retained until the Registration
> Lifetime expires. A renewed ARO should mark the cache entry as
> STALE. Thus, for 6LoWPAN routers, the Neighbor Cache doesn't behave
> like a cache. Instead, it behaves as a registry of all the host
> addresses that are attached to the router.
When `nce` is NULL on the duplicate check, the later re-fetching of the
`nce` might result in an actual NCE entry that then contains a
duplicate, so we need to re-check the EUI-64 again as well.
This changes the prefixes of the symbols generated from USEMODULE and
USEPKG variables. The changes are as follow:
KCONFIG_MODULE_ => KCONFIG_USEMODULE_
KCONFIG_PKG_ => KCONFIG_USEPKG_
MODULE_ => USEMODULE_
PKG_ => USEPKG_
Replace direct accesses to sched_active_thread and sched_active_pid with
the helper functions thread_getpid() and thread_get_active(). This serves
two purposes:
1. It makes accidental writes to those variable from outside core less likely.
2. Casting off the volatile qualifier is now well contained to those two
functions
Coverty scan found this:
> CID 298295 (#1 of 1): Operands don't affect result (CONSTANT_EXPRESSION_RESULT) result_independent_of_operands:
> (ipv6_hdr_get_fl(ipv6_hdr) & 255) >> 8 is 0 regardless of the values of its operands.
Looking at the code, this appears to be a copy & paste error from the previous line.
Coverty scan found this:
> CID 298279 (#1 of 1): Out-of-bounds read (OVERRUN)
> 21. overrun-local: Overrunning array of 16 bytes at byte offset 64 by dereferencing pointer
The original intention was probably to advance the destination pointer by 4 bytes, not
4 * the destination type size.
Using pointer difference already gives us the number of elements of
size of what the pointer is pointing to.
Dividing by size will lead to the wrong (always 0) result.
Since `min(a,b)` is a very frequently used function, several libraries such as ESP8266 SDK define a `MIN` macro in their header files. Therefore the `MIN` macro should be undefined before its definition to avoid compilation errors if it is defined anywhere else before.
Add a message bus where threads can listen for nib events.
Currently only the GNRC_IPV6_NIB_EVENT_ADDR_VALID event is
implemented which informs subscribers that an address got
valid.
With multiple 6LoWPAN interfaces the router for the given interface
—the one the triggering RA came over—should be used to register the
address with.
Co-Authored-By: Benjamin Valentin <benpicco@googlemail.com>
In 06aa65e1ba (#10627) a new behavior was
introduced in IPv6 route resolution to try address resolution only at
interfaces that have the prefix of the address to be resolved configured
in the prefix list. This however only makes sense, if the prefix
configured is [on-link], otherwise there is small likelihood of the
address to be resolved being on that link.
For the error case presented for 06aa65e (circular routing at the border
router) this made sense, however within a 6LoWPAN, due to the prefix
being valid for the entire mesh, this leads to the nodes always trying
classic address resolution for in-network addresses instead of just
routing to the default route.
Classic address resolution however fails, as 6LoWPAN hosts typically
[don't join the solicited-node multicast address of their unicast
addresses][6LN-iface-init], resulting in in-network addresses not being
reachable.
As such, to prevent both error cases
- the fallback to address resolution by prefix list must only be used
when the prefix is on-link,
- the prefix configured by DHCPv6/UHCP at the 6LoWPAN border router
must be configured as on-link, but
- the prefix must not be advertised as on-link within the 6LoWPAN to
still be [in line with RFC 6775][RFC-6775-forbidden]
With this change these cases are covered.
[on-link]: https://tools.ietf.org/html/rfc4861#page-6
[RFC 6775]: https://tools.ietf.org/html/rfc6775
[6LN-iface-init]: https://tools.ietf.org/html/rfc6775#section-5.2
[RFC-6775-forbidden]: https://tools.ietf.org/html/rfc6775#section-6.1
When pinging to a prefix for which there is a prefix list entry on the
node (so no next hop) but a default route, a packet to a non-existent
address under that prefix results in the packet being forwarded to the
default route instead. This fixes it, so the node tries address
resolution on the interface the prefix list entry is associated to.
The reassembly buffer only needs (and stores) the headers *before* the
fragment header (called per-fragment headers in RFC 8200, section 4.5).
Currently, when a subsequent IPv6 fragment is received before the first
fragment the fragment header is however not removed. With this fix it
does.
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.
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.
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).
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
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.