diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index 8e6d913cd5..b94e0d3af0 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -373,6 +373,9 @@ static void address_hash_func(const Address *a, struct siphash *state) { } case AF_INET6: siphash24_compress(&a->in_addr.in6, sizeof(a->in_addr.in6), state); + + if (in6_addr_is_null(&a->in_addr.in6)) + siphash24_compress(&a->prefixlen, sizeof(a->prefixlen), state); break; default: @@ -407,7 +410,16 @@ static int address_compare_func(const Address *a1, const Address *a2) { } case AF_INET6: /* See kernel's ipv6_get_ifaddr() in net/ipv6/addrconf.c */ - return memcmp(&a1->in_addr.in6, &a2->in_addr.in6, sizeof(a1->in_addr.in6)); + r = memcmp(&a1->in_addr.in6, &a2->in_addr.in6, sizeof(a1->in_addr.in6)); + if (r != 0) + return r; + + /* To distinguish IPv6 null addresses with different prefixlen, e.g. ::48 vs ::64, let's + * compare the prefix length. */ + if (in6_addr_is_null(&a1->in_addr.in6)) + r = CMP(a1->prefixlen, a2->prefixlen); + + return r; default: /* treat any other address family as AF_UNSPEC */