From 3af0785da15cdba0c06b4866a38d82feba01afdd Mon Sep 17 00:00:00 2001 From: xnumad <34810600+xnumad@users.noreply.github.com> Date: Thu, 7 Mar 2024 16:43:05 +0100 Subject: [PATCH] fix: Idempotency wrapper for callers Example for a caller assuming idempotency: uhcp (-> `gnrc_netif_ipv6_add_prefix` -> `NETOPT_IPV6_IID`) --- sys/net/gnrc/netif/gnrc_netif.c | 2 +- .../gnrc/network_layer/ipv6/nib/_nib-slaac.c | 24 +++++++++++++++++++ .../gnrc/network_layer/ipv6/nib/_nib-slaac.h | 7 ++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/sys/net/gnrc/netif/gnrc_netif.c b/sys/net/gnrc/netif/gnrc_netif.c index 0efc06067631..60dd8a963405 100644 --- a/sys/net/gnrc/netif/gnrc_netif.c +++ b/sys/net/gnrc/netif/gnrc_netif.c @@ -280,7 +280,7 @@ int gnrc_netif_get_from_netdev(gnrc_netif_t *netif, gnrc_netapi_opt_t *opt) assert(opt->data_len == sizeof(netopt_ipv6_rfc7217_iid_data)); netopt_ipv6_rfc7217_iid_data *data = (netopt_ipv6_rfc7217_iid_data *) opt->data; - res = ipv6_get_rfc7217_iid( + res = ipv6_get_rfc7217_iid_idempotent( data->iid, netif, data->pfx, data->dad_ctr); break; #endif diff --git a/sys/net/gnrc/network_layer/ipv6/nib/_nib-slaac.c b/sys/net/gnrc/network_layer/ipv6/nib/_nib-slaac.c index 673078ca709e..61777bc142e7 100644 --- a/sys/net/gnrc/network_layer/ipv6/nib/_nib-slaac.c +++ b/sys/net/gnrc/network_layer/ipv6/nib/_nib-slaac.c @@ -216,6 +216,30 @@ int ipv6_get_rfc7217_iid(eui64_t *iid, gnrc_netif_t *netif, const ipv6_addr_t *p return 0; } + +inline int ipv6_get_rfc7217_iid_idempotent(eui64_t *iid, gnrc_netif_t *netif, const ipv6_addr_t *pfx, + uint8_t *dad_ctr) { + int idx; + if ((idx = gnrc_netif_ipv6_addr_pfx_idx(netif, pfx, SLAAC_PREFIX_LENGTH)) >= 0) { + /* if the prefix is already known, + * do not cause generation of a potentially different + * stable privacy address (keyword DAD_Counter). + * refer to https://datatracker.ietf.org/doc/html/rfc4862#section-5.5.3 d) + * */ + DEBUG("nib: Not calling IDGEN, prefix already known.\n"); + + //write out params + //- dad_ctr + *dad_ctr = gnrc_netif_ipv6_addr_gen_retries(netif, idx); + //- iid + ipv6_addr_t *addr = &netif->ipv6.addrs[idx]; + memcpy(iid, &addr->u64[1], sizeof(*iid)); + + return 1; + } + + return ipv6_get_rfc7217_iid(iid, netif, pfx,dad_ctr); +} #endif #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_SLAAC) diff --git a/sys/net/gnrc/network_layer/ipv6/nib/_nib-slaac.h b/sys/net/gnrc/network_layer/ipv6/nib/_nib-slaac.h index 0558c4e43598..c2c392607420 100644 --- a/sys/net/gnrc/network_layer/ipv6/nib/_nib-slaac.h +++ b/sys/net/gnrc/network_layer/ipv6/nib/_nib-slaac.h @@ -149,6 +149,13 @@ bool _stable_privacy_should_retry_idgen(uint8_t *dad_ctr, const char *reason); */ int ipv6_get_rfc7217_iid(eui64_t *iid, gnrc_netif_t *netif, const ipv6_addr_t *pfx, uint8_t *dad_ctr); + +/** + * @brief @ref ipv6_get_rfc7217_iid for those callers which assume idempotency. + * @return 1 if ignored for idempotency, else @ref ipv6_get_rfc7217_iid + */ +int ipv6_get_rfc7217_iid_idempotent(eui64_t *iid, gnrc_netif_t *netif, const ipv6_addr_t *pfx, + uint8_t *dad_ctr); #endif #if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_SLAAC) || defined(DOXYGEN)