In the cases that nd6 checks whether the interface is up before
sending a packet, also check whether the link is up. Without this
additional check, temporary link downtime could easily result in
unnecessary false negatives for Duplicate Address Detection.
In addition, use the netif abstraction macros to perform the checks.
In summary, this patch aims to resolve bugs #47923 and #48162, by
decoupling address autoconfiguration from the on-link prefix list,
since those are not related. Important necessary changes are needed
to meet this goal, ultimately bringing the lwIP ND6 implementation
closer to compliance with RFC 4862. The main changes are:
1. support for address lifetimes, and,
2. addition of a new DUPLICATED address state.
The decoupling implies that the prefix list can no longer be used to
maintain state for address autoconfiguration. Most importantly, the
lifetime of each address, which was previously derived from the
prefix slot's lifetime, must now be associated with the address
itself. This patch implements address lifetime tracking, maintaining
both a valid and a preferred lifetime for each address, along with
the corresponding address state changes (e.g., between PREFERRED and
DEPRECATED), all as required by RFC 4862.
The support for address lifetimes can be enabled with a new
LWIP_IPV6_ADDRESS_LIFETIMES setting in lwipopts.h. It is required for
autoconfiguration and enabled by default if autoconfiguration is
enabled as well, but it may also be enabled separately, so as to allow
application-controlled lifetime management (e.g., if autoconfiguration
is implemented in a separate application). A special valid-lifetime of
zero is used to denote a static address--that is, an address that was
configured manually, that does not have lifetimes, and that should be
left alone by the autoconfiguration functionality. Addresses assigned
without setting a lifetime are deemed static, thus preserving
compatibility with existing lwIP-based applications in this respect.
Similarly, the decoupling implies that the prefix list can no longer
be used to remember cases of address duplication. Previously, the
detection of a duplicated address would simply result in removal of
the address altogether. Instead, this patch introduces a new state
"DUPLICATED", indicating that the address, while technically still
present, has been found to conflict with other node addresses, and no
attempt should be made to produce an autoconfiguration address for
that prefix.
Manually added addresses, including the link-local address, once set
to DUPLICATED, will remain in that state until manual intervention.
Autoconfigured DUPLICATED addresses will expire according to their
valid-lifetime, essentially preserving the current behavior but
without the use of the prefix list. As a first attempt to approach
compliance with RFC 4862 Sec. 5.4.5, if the link-local address is
detected to be duplicated, all derived addresses are marked duplicated
as well, and no new addresses will be autoconfigured. More work is to
be done for full compliance with that section, however.
Together, those two main changes indeed do fully decouple address
autoconfiguration from the on-link prefix list. Changes to the latter
thus no longer affect the former, resolving bug #47923. Moreover, as a
result, autoconfiguration can, and does, now also take place on
advertised prefixes that do not have the on-link flag set, resolving
bug #48162. The routing changes mentioned in the discussion of that
bug are left to a separate patch, though.
If MLD support is enabled, each locally assigned IPv6 address in the
appropriate state must be a member of the solicited-node multicast
group corresponding to that address. Ensure that this is always the
case by (re-)deciding on the membership upon every address state
change. By doing so, this patch enforces that user-initiated state
changes to addresses (e.g., deletion) never cause a desynchronization
with the corresponding solicited-node multicast group membership,
thereby making such user-initiated state changes simpler and safer.
Fix below build error when LWIP_ND6_RDNSS_MAX_DNS_SERVERS == 0
../../../../lwip/src/core/ipv6/nd6.c: In function ‘nd6_input’:
../../../../lwip/src/core/ipv6/nd6.c:400:10: error: unused variable ‘rdnss_server_idx’ [-Werror=unused-variable]
u8_t rdnss_server_idx = 0;
^~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
../Common.mk:93: recipe for target 'nd6.o' failed
make: *** [nd6.o] Error 1
Fixes: 6b1950ec24bc ("nd6: add support for RDNSS option (as per RFC 6106)")
Signed-off-by: Axel Lin <axel.lin@ingics.com>
Previously, ethip6 and lowpan6 each had their own copy of code that
used internal nd6 data structures to decide whether to send a packet
on the local link right away, or queue it while nd6 performed local
address resolution. This patch moves that code into nd6, thereby
eliminating all remaining cases of external access to internal nd6
data structures, as well as the need to expose two specific nd6
functions.
As a side effect, the patch effectively fixes two bugs in the lowpan6
code that were already fixed in the ethip6 code.
This patch rearranges the code division between nd6.c and ip6.c such
that the latter does not need to access ND6-internal data structures
(specifically, "default_router_list") directly anymore.
The new function, while currently not used internally, allows external
code to clear the ND destination cache in the case that it may have
become inconsistent with the current situation, for example as the
result of a change of locally assigned addresses, or a change in
routing tables implemented through the LWIP_HOOK_ND6_GET_GW hook.
Let lwip use functions/macros prefixed by lwip_ internally to avoid naming clashes with external #includes.
Remove over-complicated #define handling in def.h
Make functions easier to override in cc.h. The following is sufficient now (no more LWIP_PLATFORM_BYTESWAP):
#define lwip_htons(x) <your_htons>
#define lwip_htonl(x) <your_htonl>
delay_time and stale_time are ticks now.
reachable_time and invalidation_timer are untouched since they may originate from telegram values -> not converting them to ticks avoids an integer division
pbuf_alloc() for PBUF_RAM type always return big enough memory on success.
So checking p->len is not necessary. Testing if p is NULL or not is enough.
Signed-off-by: Axel Lin <axel.lin@ingics.com>
ip_addr_t is used for all generic IP addresses for the API, ip(4/6)_addr_t are only used internally or when initializing netifs or when calling version-related functions