-
Notifications
You must be signed in to change notification settings - Fork 2.1k
gnrc_ipv6_nib/SLAAC: rfc8981 temporary address (privacy extensions) #20369
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Welcome @xnumad! And thanks for your contribution. 😄 |
5d5b8c6
to
fa54557
Compare
Rebased. |
Changed commit message. |
Need to check for matching address rather than prefix because for a 6LN, the SLAAC prefix is never stored in the prefix list, since everything is considered off-link.
Fix time units
Slightly simplifies the coupling by moving the prefix deletion from the inner to the outer function in the call chain, when deleting a temporary address prefix: Previously: Prefix deletion calls addr deletion, which calls a prefix deletion again, which deletes the prefix, leaving the outer prefix deletion function with no prefix to delete. Now: Outer function deletes prefix before calling address deletion function, which still calls prefix deletion function, but it's this one now that doesn't have any prefix to delete.
Increases readability Was previously also needed to enable regen to work on 6LN, because a 6LN did not store SLAAC prefix prior to PR RIOT-OS#20757.
As the ta_pfx will have an NCE with unspecified next hop, 1 NCE is needed for that.
Rebased to resolve merge conflicts |
Since this was not reviewed yet, you can probably squash your commits a bit if you want to. |
Murdock results✔️ PASSED
Artifacts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't really have experience with the proposed changes or the network subsystem of RIOT in general, but below you find some general comments about the code. Nothing major, mostly style related nitpicks.
* | ||
* @see "REGEN_ADVANCE time units before" - https://www.rfc-editor.org/rfc/rfc8981.html#section-3.6 | ||
*/ | ||
#define GNRC_IPV6_NIB_REGEN_TEMP_ADDR (0x4fd6U) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#define GNRC_IPV6_NIB_REGEN_TEMP_ADDR (0x4fd6U) | |
# define GNRC_IPV6_NIB_REGEN_TEMP_ADDR (0x4fd6U) |
For newly added code we try to establish the indentation in preprocessor commands too, as is the case in other parts of this PR too.
@@ -64,7 +64,7 @@ extern "C" { | |||
# endif | |||
# ifndef CONFIG_GNRC_IPV6_NIB_NUMOF | |||
/* only needs to store default router */ | |||
# define CONFIG_GNRC_IPV6_NIB_NUMOF (1) | |||
# define CONFIG_GNRC_IPV6_NIB_NUMOF (1 + IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_SLAAC_TEMPORARY_ADDRESSES)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# define CONFIG_GNRC_IPV6_NIB_NUMOF (1 + IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_SLAAC_TEMPORARY_ADDRESSES)) | |
# if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_SLAAC_TEMPORARY_ADDRESSES)) | |
# define CONFIG_GNRC_IPV6_NIB_NUMOF (2) | |
# else | |
# define CONFIG_GNRC_IPV6_NIB_NUMOF (1) | |
# endif |
I think this would be a better approach than mixing the boolean result of the IS_ACTIVE
and an integer.
* @see [RFC 8981](https://www.rfc-editor.org/rfc/rfc8981.html) | ||
*/ | ||
#ifndef CONFIG_GNRC_IPV6_NIB_SLAAC_TEMPORARY_ADDRESSES | ||
#define CONFIG_GNRC_IPV6_NIB_SLAAC_TEMPORARY_ADDRESSES 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#define CONFIG_GNRC_IPV6_NIB_SLAAC_TEMPORARY_ADDRESSES 0 | |
# define CONFIG_GNRC_IPV6_NIB_SLAAC_TEMPORARY_ADDRESSES 0 |
#ifndef MAX_TEMP_ADDRESSES | ||
#define MAX_TEMP_ADDRESSES (4) | ||
#endif | ||
#else | ||
#define MAX_TEMP_ADDRESSES (0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#ifndef MAX_TEMP_ADDRESSES | |
#define MAX_TEMP_ADDRESSES (4) | |
#endif | |
#else | |
#define MAX_TEMP_ADDRESSES (0) | |
# ifndef MAX_TEMP_ADDRESSES | |
# define MAX_TEMP_ADDRESSES (4) | |
# endif | |
#else | |
# define MAX_TEMP_ADDRESSES (0) |
@@ -102,6 +102,33 @@ extern "C" { | |||
#define GNRC_NETIF_IPV6_RTR_ADDR (0) | |||
#endif | |||
|
|||
/** | |||
* @brief Maximum assumed number of valid (preferred or deprecated) temporary addresses. | |||
* (see _nib-slaac.h) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does Doxygen resolve the file reference? If not, it would be good to add an explicit reference command.
* @param netif Network interface of the temporary address and the SLAAC prefix. | ||
* @param addr Current temporary address (or any address in the SLAAC prefix for that matter) | ||
* @param retries passed as-is to @ref _generate_temporary_addr | ||
* @param caller_description Text detail for logging |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These parameters are missing the direction.
@@ -1539,6 +1559,31 @@ static void _handle_pfx_timeout(_nib_offl_entry_t *pfx) | |||
netif->ipv6.addrs_flags[i] |= GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_DEPRECATED; | |||
} | |||
} | |||
#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_SLAAC_TEMPORARY_ADDRESSES) | |||
if (pfx->flags & _PFX_SLAAC) { | |||
/* Remove regen event from temporary addresses (the current temporary address should have one scheduled). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line causes a static error because it's too long.
* because the temporary address is deprecated but not invalidated/removed yet. | ||
*/ | ||
|
||
//alternative way to get ta_pfx: _iter_slaac_prefix_to_temp_addr + _nib_offl_get_match |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above.
@@ -25,6 +25,9 @@ | |||
|
|||
#include "_nib-internal.h" | |||
#include "_nib-router.h" | |||
#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_SLAAC_TEMPORARY_ADDRESSES) | |||
#include "_nib-slaac.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#include "_nib-slaac.h" | |
# include "_nib-slaac.h" |
@@ -34,6 +34,9 @@ | |||
#include "net/loramac.h" | |||
#include "net/netif.h" | |||
#include "shell.h" | |||
#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_SLAAC_TEMPORARY_ADDRESSES) | |||
#include "../../net/gnrc/network_layer/ipv6/nib/_nib-slaac.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#include "../../net/gnrc/network_layer/ipv6/nib/_nib-slaac.h" | |
# include "../../net/gnrc/network_layer/ipv6/nib/_nib-slaac.h" |
Again, I wonder why such sn explicit path is required.
Contribution description
This implements RFC8981.
Design
The RFC describes an implementation where lifetimes are associated directly with an address. This is not the case in GNRC, where lifetimes are associated with a prefix (prefix list - https://datatracker.ietf.org/doc/html/rfc4861#section-5.1). This PR therefore adjusts the logic to be compatible with this design, while of course still following all the RFC requirements. (The adjusted logic may even be considered simpler than the one described in the RFC!)
In particular, the changes is in the logic used to implement coupling of temporary address to lifetimes of SLAAC prefix while still retaining maximum lifetimes for a temporary address:
Therefore this PR considers an IP address to be temporary iff there exists a /128 prefix for it (i.e. with that address). This assumption is used throughout this implementation, in particular to determine whether an assigned address is a temporary address:
https://github.com/xnumad/RIOT/blob/15e8518d64f674d711f9e4d0fdd613617257a715/sys/net/gnrc/network_layer/ipv6/nib/_nib-slaac.c#L183
https://github.com/xnumad/RIOT/blob/15e8518d64f674d711f9e4d0fdd613617257a715/sys/net/gnrc/network_layer/ipv6/nib/_nib-slaac.c#L230
It is theoretically possible for this circumstance to interfere with other /128 prefixes in the prefix list (e.g. a PIO for exactly that /128 prefix). This conflict could be detected by using a flag (to indicate relation to temporary address usage), but otherwise not avoided unless further changing the lifetime management, e.g. separating it from the NIB prefix list or even using the RFC logic that associates lifetimes directly to an address.
--
Design decision of where to store (temp addr) regeneration event:
The regen event timer is associated with the prefix for the temporary address, because a refactor showed that it results in easier code than when storing it associated with the SLAAC prefix. (f33d2e6)
--
Other noteworthy implications of this PR:
SLAAC_PREFIX_LENGTH=64
requirement of RFCs (see macro definition for RFC reference)GNRC_NETIF_IPV6_ADDRS_FLAGS_IDGEN_RETRIES
, as an easy way to associate the retry counter with the address, because the value is used again if DAD failures occurThese changes are also cherry-picked to the RFC7217 implementation at gnrc_ipv6_nib/SLAAC: rfc7217 stable privacy addresses #20370
--
RFC compatibility
All but the following requirements of the RFC are implemented:
(Requirements from section 3.3.2 do not apply because this PR uses the other algorithm, i.e. from section 3.3.1)
Disable if retry limit reached
Subrange list
Currently, no such subrange list is implemented. (Although comparatively low effort to implement.)
Temporary addresses are generated for any "prefix advertised in a RA PIO with A flag set" and not for link-local addresses.
Ad-hoc toggle
Interpreting this as the need to ad-hoc disable temporary addresses. Not fulfilled; the setting is only set through a compile-time flag and cannot be changed at runtime.
Cleanup
Should this be added to
RIOT/sys/net/gnrc/network_layer/ipv6/nib/nib.c
Line 173 in 32d1cd9
Currently, only link-local addresses seem to be removed at all.
RIOT/sys/net/gnrc/network_layer/ipv6/nib/nib.c
Line 196 in 32d1cd9
Adaptability
This implementation supports Ethernet and 6LoWPAN. Supporting a new link layer only requires its REGEN_ADVANCE value to be returned by
https://github.com/xnumad/RIOT/blob/15e8518d64f674d711f9e4d0fdd613617257a715/sys/net/gnrc/netif/gnrc_netif_device_type.c#L224
The usage of IIDs which do not match the link layer address causes LOWPAN_IPHC to not be able to statelessly compress the IP address anymore. An optimization to enable compression again could be to add compression contexts (feature branch for opportunistic compression contexts: https://github.com/xnumad/RIOT/tree/feature%2Fopportunistic-compression-contexts).
Testing procedure
Add
CFLAGS += -DCONFIG_GNRC_IPV6_NIB_SLAAC_TEMPORARY_ADDRESSES=1
at the appropriate position in the Makefile ofexamples/gnrc_networking
. Tested on BOARD=nrf52840dkOutput of
ifconfig
command is expected to contain a line with a temporary address ("TMP"), likeinet6 addr: 2001:db8::6f04:c775:f9a9:dc48 scope: global VAL TMP
The temporary address is the preferred source address for the global address scope (can be tested by e.g. ping)
(And many more tests could be done)