core: implement NMIP4Config's and NMIP6Config's route equality based on nm_platform_ipx_route_cmp()

There are various notions of how to compare routes. Collect them all
in nm_platform_ip4_route_cmp(), nm_platform_ip4_route_hash(),
nm_platform_ip6_route_cmp(), and nm_platform_ip6_route_hash().

This way, we have them side-by-side, which makes the differences more
discoverable.
This commit is contained in:
Thomas Haller 2017-07-31 17:20:20 +02:00
parent 7141a3b87a
commit 9be9cab646
3 changed files with 25 additions and 8 deletions

View file

@ -76,16 +76,14 @@ gboolean
nm_ip_config_obj_id_equal_ip4_route (const NMPlatformIP4Route *r_a,
const NMPlatformIP4Route *r_b)
{
return r_a->network == r_b->network
&& r_a->plen == r_b->plen;
return nm_platform_ip4_route_cmp (r_a, r_b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_DST) == 0;
}
gboolean
nm_ip_config_obj_id_equal_ip6_route (const NMPlatformIP6Route *r_a,
const NMPlatformIP6Route *r_b)
{
return r_a->plen == r_b->plen
&& IN6_ARE_ADDR_EQUAL (&r_a->network, &r_b->network);
return nm_platform_ip6_route_cmp (r_a, r_b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_DST) == 0;
}
static guint
@ -108,13 +106,11 @@ _idx_obj_id_hash (const NMDedupMultiIdxType *idx_type,
break;
case NMP_OBJECT_TYPE_IP4_ROUTE:
h = 40303327;
h = NM_HASH_COMBINE (h, o->ip4_route.network);
h = NM_HASH_COMBINE (h, o->ip_route.plen);
h = NM_HASH_COMBINE (h, nm_platform_ip4_route_hash (NMP_OBJECT_CAST_IP4_ROUTE (o), NM_PLATFORM_IP_ROUTE_CMP_TYPE_DST));
break;
case NMP_OBJECT_TYPE_IP6_ROUTE:
h = 577629323;
h = NM_HASH_COMBINE_IN6ADDR (h, &o->ip6_route.network);
h = NM_HASH_COMBINE (h, o->ip_route.plen);
h = NM_HASH_COMBINE (h, nm_platform_ip6_route_hash (NMP_OBJECT_CAST_IP6_ROUTE (o), NM_PLATFORM_IP_ROUTE_CMP_TYPE_DST));
break;
default:
g_return_val_if_reached (0);

View file

@ -4718,6 +4718,10 @@ nm_platform_ip4_route_hash (const NMPlatformIP4Route *obj, NMPlatformIPRouteCmpT
if (obj) {
switch (cmp_type) {
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_DST:
h = NM_HASH_COMBINE (h, nm_utils_ip4_address_clear_host_address (obj->network, obj->plen));
h = NM_HASH_COMBINE (h, obj->plen);
break;
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID_CACHE:
h = NM_HASH_COMBINE (h, nm_utils_ip4_address_clear_host_address (obj->network, obj->plen));
h = NM_HASH_COMBINE (h, obj->plen);
@ -4785,6 +4789,10 @@ nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route
{
NM_CMP_SELF (a, b);
switch (cmp_type) {
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_DST:
NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX (a->network, b->network, MIN (a->plen, b->plen));
NM_CMP_FIELD (a, b, plen);
break;
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID_CACHE:
NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX (a->network, b->network, MIN (a->plen, b->plen));
NM_CMP_FIELD (a, b, plen);
@ -4853,6 +4861,10 @@ nm_platform_ip6_route_hash (const NMPlatformIP6Route *obj, NMPlatformIPRouteCmpT
if (obj) {
switch (cmp_type) {
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_DST:
h = NM_HASH_COMBINE_IN6ADDR_PREFIX (h, &obj->network, obj->plen);
h = NM_HASH_COMBINE (h, obj->plen);
break;
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID_CACHE:
h = NM_HASH_COMBINE_IN6ADDR_PREFIX (h, &obj->network, obj->plen);
h = NM_HASH_COMBINE (h, obj->plen);
@ -4914,6 +4926,10 @@ nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6Route
{
NM_CMP_SELF (a, b);
switch (cmp_type) {
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_DST:
NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX (&a->network, &b->network, MIN (a->plen, b->plen));
NM_CMP_FIELD (a, b, plen);
break;
case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID_CACHE:
NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX (&a->network, &b->network, MIN (a->plen, b->plen));
NM_CMP_FIELD (a, b, plen);

View file

@ -101,6 +101,11 @@ typedef enum {
* which is the same what kernel does. */
NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID_CACHE,
/* NMIP4Config and NMIP6Config also track a list of routes. They have their
* own notion of what equality means. Basically, they consider network/plen
* for IPv4 and IPv6. */
NM_PLATFORM_IP_ROUTE_CMP_TYPE_DST,
/* compare all fields as they make sense for kernel. For example,
* a route destination 192.168.1.5/24 is not accepted by kernel and
* we treat it identical to 192.168.1.0/24. Semantically these