diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index 4fe55710391..23d40ccc411 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -115,6 +115,20 @@ void address_free(Address *address) { free(address); } +static uint32_t address_prefix(const Address *a) { + assert(a); + + /* make sure we don't try to shift by 32. + * See ISO/IEC 9899:TC3 § 6.5.7.3. */ + if (a->prefixlen == 0) + return 0; + + if (a->in_addr_peer.in.s_addr != 0) + return be32toh(a->in_addr_peer.in.s_addr) >> (32 - a->prefixlen); + else + return be32toh(a->in_addr.in.s_addr) >> (32 - a->prefixlen); +} + static void address_hash_func(const Address *a, struct siphash *state) { assert(a); @@ -125,16 +139,8 @@ static void address_hash_func(const Address *a, struct siphash *state) { siphash24_compress(&a->prefixlen, sizeof(a->prefixlen), state); /* peer prefix */ - if (a->prefixlen != 0) { - uint32_t prefix; - - if (a->in_addr_peer.in.s_addr != 0) - prefix = be32toh(a->in_addr_peer.in.s_addr) >> (32 - a->prefixlen); - else - prefix = be32toh(a->in_addr.in.s_addr) >> (32 - a->prefixlen); - - siphash24_compress(&prefix, sizeof(prefix), state); - } + uint32_t prefix = address_prefix(a); + siphash24_compress(&prefix, sizeof(prefix), state); _fallthrough_; case AF_INET6: @@ -162,26 +168,11 @@ static int address_compare_func(const Address *a1, const Address *a2) { if (r != 0) return r; - /* compare the peer prefixes */ - if (a1->prefixlen != 0) { - /* make sure we don't try to shift by 32. - * See ISO/IEC 9899:TC3 § 6.5.7.3. */ - uint32_t b1, b2; - - if (a1->in_addr_peer.in.s_addr != 0) - b1 = be32toh(a1->in_addr_peer.in.s_addr) >> (32 - a1->prefixlen); - else - b1 = be32toh(a1->in_addr.in.s_addr) >> (32 - a1->prefixlen); - - if (a2->in_addr_peer.in.s_addr != 0) - b2 = be32toh(a2->in_addr_peer.in.s_addr) >> (32 - a1->prefixlen); - else - b2 = be32toh(a2->in_addr.in.s_addr) >> (32 - a1->prefixlen); - - r = CMP(b1, b2); - if (r != 0) - return r; - } + uint32_t prefix1 = address_prefix(a1); + uint32_t prefix2 = address_prefix(a2); + r = CMP(prefix1, prefix2); + if (r != 0) + return r; _fallthrough_; case AF_INET6: diff --git a/src/network/networkd-neighbor.c b/src/network/networkd-neighbor.c index 537f6be9e16..fd61ebd5d37 100644 --- a/src/network/networkd-neighbor.c +++ b/src/network/networkd-neighbor.c @@ -209,18 +209,20 @@ static void neighbor_hash_func(const Neighbor *neighbor, struct siphash *state) assert(neighbor); siphash24_compress(&neighbor->family, sizeof(neighbor->family), state); + siphash24_compress(&neighbor->lladdr_size, sizeof(neighbor->lladdr_size), state); switch (neighbor->family) { case AF_INET: case AF_INET6: /* Equality of neighbors are given by the pair (addr,lladdr) */ siphash24_compress(&neighbor->in_addr, FAMILY_ADDRESS_SIZE(neighbor->family), state); - siphash24_compress(&neighbor->lladdr, neighbor->lladdr_size, state); break; default: /* treat any other address family as AF_UNSPEC */ break; } + + siphash24_compress(&neighbor->lladdr, neighbor->lladdr_size, state); } static int neighbor_compare_func(const Neighbor *a, const Neighbor *b) { diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index bae7cd8f960..85df5d9395f 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -157,11 +157,14 @@ static void route_hash_func(const Route *route, struct siphash *state) { switch (route->family) { case AF_INET: case AF_INET6: - siphash24_compress(&route->gw, FAMILY_ADDRESS_SIZE(route->family), state); - siphash24_compress(&route->dst, FAMILY_ADDRESS_SIZE(route->family), state); siphash24_compress(&route->dst_prefixlen, sizeof(route->dst_prefixlen), state); - siphash24_compress(&route->src, FAMILY_ADDRESS_SIZE(route->family), state); + siphash24_compress(&route->dst, FAMILY_ADDRESS_SIZE(route->family), state); + siphash24_compress(&route->src_prefixlen, sizeof(route->src_prefixlen), state); + siphash24_compress(&route->src, FAMILY_ADDRESS_SIZE(route->family), state); + + siphash24_compress(&route->gw, FAMILY_ADDRESS_SIZE(route->family), state); + siphash24_compress(&route->prefsrc, FAMILY_ADDRESS_SIZE(route->family), state); siphash24_compress(&route->tos, sizeof(route->tos), state); @@ -170,6 +173,7 @@ static void route_hash_func(const Route *route, struct siphash *state) { siphash24_compress(&route->protocol, sizeof(route->protocol), state); siphash24_compress(&route->scope, sizeof(route->scope), state); siphash24_compress(&route->type, sizeof(route->type), state); + siphash24_compress(&route->initcwnd, sizeof(route->initcwnd), state); siphash24_compress(&route->initrwnd, sizeof(route->initrwnd), state); @@ -194,10 +198,26 @@ static int route_compare_func(const Route *a, const Route *b) { if (r != 0) return r; + r = memcmp(&a->dst, &b->dst, FAMILY_ADDRESS_SIZE(a->family)); + if (r != 0) + return r; + r = CMP(a->src_prefixlen, b->src_prefixlen); if (r != 0) return r; + r = memcmp(&a->src, &b->src, FAMILY_ADDRESS_SIZE(a->family)); + if (r != 0) + return r; + + r = memcmp(&a->gw, &b->gw, FAMILY_ADDRESS_SIZE(a->family)); + if (r != 0) + return r; + + r = memcmp(&a->prefsrc, &b->prefsrc, FAMILY_ADDRESS_SIZE(a->family)); + if (r != 0) + return r; + r = CMP(a->tos, b->tos); if (r != 0) return r; @@ -230,19 +250,7 @@ static int route_compare_func(const Route *a, const Route *b) { if (r != 0) return r; - r = memcmp(&a->gw, &b->gw, FAMILY_ADDRESS_SIZE(a->family)); - if (r != 0) - return r; - - r = memcmp(&a->dst, &b->dst, FAMILY_ADDRESS_SIZE(a->family)); - if (r != 0) - return r; - - r = memcmp(&a->src, &b->src, FAMILY_ADDRESS_SIZE(a->family)); - if (r != 0) - return r; - - return memcmp(&a->prefsrc, &b->prefsrc, FAMILY_ADDRESS_SIZE(a->family)); + return 0; default: /* treat any other address family as AF_UNSPEC */ return 0; diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c index 9443db02fd6..8203f87c9fa 100644 --- a/src/network/networkd-routing-policy-rule.c +++ b/src/network/networkd-routing-policy-rule.c @@ -105,7 +105,6 @@ static void routing_policy_rule_hash_func(const RoutingPolicyRule *rule, struct switch (rule->family) { case AF_INET: case AF_INET6: - siphash24_compress(&rule->from, FAMILY_ADDRESS_SIZE(rule->family), state); siphash24_compress(&rule->from_prefixlen, sizeof(rule->from_prefixlen), state); @@ -151,10 +150,18 @@ static int routing_policy_rule_compare_func(const RoutingPolicyRule *a, const Ro if (r != 0) return r; + r = memcmp(&a->from, &b->from, FAMILY_ADDRESS_SIZE(a->family)); + if (r != 0) + return r; + r = CMP(a->to_prefixlen, b->to_prefixlen); if (r != 0) return r; + r = memcmp(&a->to, &b->to, FAMILY_ADDRESS_SIZE(a->family)); + if (r != 0) + return r; + r = CMP(a->invert_rule, b->invert_rule); if (r != 0) return r; @@ -179,14 +186,6 @@ static int routing_policy_rule_compare_func(const RoutingPolicyRule *a, const Ro if (r != 0) return r; - r = strcmp_ptr(a->iif, b->iif); - if (!r) - return r; - - r = strcmp_ptr(a->oif, b->oif); - if (!r) - return r; - r = CMP(a->protocol, b->protocol); if (r != 0) return r; @@ -199,12 +198,15 @@ static int routing_policy_rule_compare_func(const RoutingPolicyRule *a, const Ro if (r != 0) return r; - r = memcmp(&a->from, &b->from, FAMILY_ADDRESS_SIZE(a->family)); + r = strcmp_ptr(a->iif, b->iif); if (r != 0) return r; - return memcmp(&a->to, &b->to, FAMILY_ADDRESS_SIZE(a->family)); + r = strcmp_ptr(a->oif, b->oif); + if (r != 0) + return r; + return 0; default: /* treat any other address family as AF_UNSPEC */ return 0;