On Mon, Mar 09, 2026 at 03:52:33PM -0400, Jon Maloy wrote:
nl_addr_get() was not setting the prefix_len output parameter for IPv6 addresses, only for IPv4. This meant callers always got 0 for IPv6, forcing them to use a hardcoded default (64).
Fix by assigning *prefix_len even in the IPv6 case.
Signed-off-by: Jon Maloy
Reviewed-by: David Gibson
--- v2: - Simplified according to feedback from S. Brivio - Added test for AF_INET link local property v3: - Corrected claim about convention for IPv4 link local address scope in commit log. v4: - Reverted from the IPv4 link local exclusion change --- netlink.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/netlink.c b/netlink.c index 82a2f0c..ee9a6b1 100644 --- a/netlink.c +++ b/netlink.c @@ -752,7 +752,7 @@ int nl_addr_set_ll_nodad(int s, unsigned int ifi) * @ifi: Interface index in outer network namespace * @af: Address family * @addr: Global address to fill - * @prefix_len: Mask or prefix length, to fill (for IPv4) + * @prefix_len: Mask or prefix length, to fill * @addr_l: Link-scoped address to fill (for IPv6) * * Return: 0 on success, negative error code on failure @@ -788,16 +788,11 @@ int nl_addr_get(int s, unsigned int ifi, sa_family_t af, (af == AF_INET6 && rta->rta_type != IFA_ADDRESS)) continue;
- if (af == AF_INET && ifa->ifa_prefixlen > prefix_max) { + if (ifa->ifa_prefixlen > prefix_max && + (af == AF_INET || ifa->ifa_scope < RT_SCOPE_LINK)) { memcpy(addr, RTA_DATA(rta), RTA_PAYLOAD(rta));
prefix_max = *prefix_len = ifa->ifa_prefixlen; - } else if (af == AF_INET6 && addr && - ifa->ifa_scope < RT_SCOPE_LINK && - ifa->ifa_prefixlen > prefix_max) { - memcpy(addr, RTA_DATA(rta), RTA_PAYLOAD(rta)); - - prefix_max = ifa->ifa_prefixlen; }
if (addr_l && -- 2.52.0
-- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson