Skip to content
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

gnrc_ipv6_nib/SLAAC: rfc8981 temporary address (privacy extensions) #20369

Open
wants to merge 65 commits into
base: master
Choose a base branch
from

Conversation

xnumad
Copy link
Contributor

@xnumad xnumad commented Feb 11, 2024

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:

  • RFC: Initial and updated values for the lifetimes of the temporary address are always derived from both the prefix lifetime as well as the lifetime limits configured for temporary addresses.
  • this PR: A temporary address is coupled to a new /128 (code keyword IPV6_ADDR_BIT_LEN=128) prefix to manage its maximum lifetime. (Coupling being that they are created and deleted at once.) Then, to couple the temporary address with the SLAAC prefix it was created from (so that the temporary address cannot possibly outlive the SLAAC prefix), the temporary address is deleted if the SLAAC prefix is deprecated or invalidated.

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:

  • implements the SLAAC_PREFIX_LENGTH=64 requirement of RFCs (see macro definition for RFC reference)
  • adds a new address flag, 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 occur
    These 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

    If, after TEMP_IDGEN_RETRIES consecutive attempts, the host is unable to generate a unique temporary address, the host MUST log a system error and SHOULD NOT attempt to generate a temporary address for the given prefix for the duration of the host's attachment to the network via this interface.

  • Subrange list

    implementations SHOULD provide a way to enable and disable generation of temporary addresses for specific prefix subranges

    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

    In addition, a site might wish to disable the use of temporary addresses in order to simplify network debugging and operations. Consequently, implementations SHOULD provide a way for trusted system administrators to enable or disable the use of temporary addresses.

    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

    when an interface connects to a new (different) link, existing temporary addresses for the corresponding interface MUST be removed

    Should this be added to

    void gnrc_ipv6_nib_iface_down(gnrc_netif_t *netif, bool send_final_ra)
    ?
    Currently, only link-local addresses seem to be removed at all.
    if (ipv6_addr_is_link_local(&netif->ipv6.addrs[i])) {
    I didn't find a way to test this.

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 of examples/gnrc_networking. Tested on BOARD=nrf52840dk

Output of ifconfig command is expected to contain a line with a temporary address ("TMP"), like inet6 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)

@kaspar030
Copy link
Contributor

Welcome @xnumad! And thanks for your contribution. 😄
This looks quite interesting. Curious what the gnrc specialists have to say about it.

@xnumad xnumad force-pushed the rfc8981 branch 2 times, most recently from 5d5b8c6 to fa54557 Compare August 26, 2024 09:41
@xnumad
Copy link
Contributor Author

xnumad commented Aug 26, 2024

Rebased, then dropped last commit (5d5b8c6) which was a workaround to a bug that was fixed in #20757 (hence the rebase)

@xnumad
Copy link
Contributor Author

xnumad commented Sep 18, 2024

Rebased.

@xnumad
Copy link
Contributor Author

xnumad commented Sep 18, 2024

Changed commit message.

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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: Kconfig Area: Kconfig integration Area: network Area: Networking Area: sys Area: System Area: tests Area: tests and testing framework
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants