From 3fa9881f2c38b58ae3f155813b98bddb25de45ac Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Fri, 10 Jan 2025 18:52:52 +0100 Subject: [PATCH] fixup! fixup! gnrc/ipv6_auto_subnets: unicast RA if upstream is 6lo --- .../gnrc_ipv6_auto_subnets.c | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/sys/net/gnrc/routing/ipv6_auto_subnets/gnrc_ipv6_auto_subnets.c b/sys/net/gnrc/routing/ipv6_auto_subnets/gnrc_ipv6_auto_subnets.c index ec7b1f0c6d25..0389ce587dab 100644 --- a/sys/net/gnrc/routing/ipv6_auto_subnets/gnrc_ipv6_auto_subnets.c +++ b/sys/net/gnrc/routing/ipv6_auto_subnets/gnrc_ipv6_auto_subnets.c @@ -100,6 +100,7 @@ */ #include "compiler_hints.h" +#include "macros/utils.h" #include "net/gnrc/ipv6.h" #include "net/gnrc/netif.h" #include "net/gnrc/netif/hdr.h" @@ -110,12 +111,6 @@ #include "random.h" #include "xtimer.h" -/* If we derive the subnet from the interface's EUI, we have to use all - available prefix bits to ensure uniqueness */ -#if IS_USED(MODULE_GNRC_IPV6_AUTO_SUBNETS_EUI) -#define CONFIG_GNRC_IPV6_AUTO_SUBNETS_PREFIX_MIN_LEN (64) -#endif - /** * @brief Port for the custom UDP sync protocol */ @@ -335,11 +330,18 @@ static void _init_sub_prefix_eui(ipv6_addr_t *out, uint8_t u8[8]; } eui64 = {}; + /* If EUI is small, we want to preserve leftover unused bits at the end */ + uint8_t bits_total = bits + 8 * eui_len; + uint8_t shift = bits_total < 64 + ? 64 - bits_total + : 0; + /* treat EUI as a EUI-64 with unused bytes set to 0 */ memcpy(&eui64.u8[sizeof(uint64_t) - eui_len], eui, eui_len); /* create downstream prefix from upstream prefix + masked EUI64 */ - out->u64[0].u64 = prefix->u64[0].u64 | (eui64.u64 & mask); + out->u64[0].u64 = prefix->u64[0].u64 + | ((eui64.u64 & mask) >> shift); out->u64[1].u64 = 0; } @@ -433,13 +435,16 @@ static void _configure_subnets(uint8_t subnets, uint8_t start_idx, gnrc_netif_t /* create subnet from upstream prefix */ if (IS_USED(MODULE_GNRC_IPV6_AUTO_SUBNETS_EUI)) { uint8_t hwaddr[GNRC_NETIF_L2ADDR_MAXLEN]; - int res = netif_get_opt(&downstream->netif, NETOPT_ADDRESS, 0, - hwaddr, sizeof(hwaddr)); - if (res <= 0) { + int hwaddr_len = netif_get_opt(&downstream->netif, NETOPT_ADDRESS, 0, + hwaddr, sizeof(hwaddr)); + if (hwaddr_len <= 0) { DEBUG("auto_subnets: can't get l2 address from netif %u\n", downstream->pid); continue; } - _init_sub_prefix_eui(&new_prefix, prefix, prefix_len, hwaddr, res); + _init_sub_prefix_eui(&new_prefix, prefix, prefix_len, hwaddr, hwaddr_len); + + new_prefix_len = prefix_len + 8 * hwaddr_len; + new_prefix_len = MAX(new_prefix_len, CONFIG_GNRC_IPV6_AUTO_SUBNETS_PREFIX_MIN_LEN); } else { _init_sub_prefix(&new_prefix, prefix, prefix_len, ++start_idx, subnet_len); }