diff options
author | Thomas Haller <thaller@redhat.com> | 2017-09-11 21:41:57 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2017-09-13 08:17:31 +0200 |
commit | aee48dfd44c9e469303573fb6d02b0d0113658c5 (patch) | |
tree | 113de66f95922b2b9bce3757a0bdd01996a3c127 | |
parent | e730ae7600854d159667d972717e2f0a7639ac42 (diff) | |
download | NetworkManager-aee48dfd44c9e469303573fb6d02b0d0113658c5.tar.gz |
core: adjust route equality for NMIP4Config/NMIP6Config to what kernel does
For kernel, route ID compare identical according to NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID.
Well, mostly. In practice, NM ignores several route properties that
kernel considers part of the ID too. This leaves the possibility that
kernel allows addition of two routes that compare idential for
NetworkManager.
Anyway, NMIP4Config/NMIP6Config should use the same equality as platform
cache. Otherwise, there is the odd situation that ip-config merges routes
that are treated as different by kernel.
For IP addresses the ID operator already corresponded to what kernel
does. There is no change for addresses.
Note that NMSettingIPConfig also uses a different algorithm for
comparing routes. But that doesn't really matter here, it it differed
before too.
-rw-r--r-- | src/nm-ip4-config.c | 96 | ||||
-rw-r--r-- | src/nm-ip4-config.h | 9 | ||||
-rw-r--r-- | src/nm-ip6-config.c | 5 | ||||
-rw-r--r-- | src/platform/nm-platform.c | 16 | ||||
-rw-r--r-- | src/platform/nm-platform.h | 5 | ||||
-rw-r--r-- | src/tests/test-ip4-config.c | 8 |
6 files changed, 20 insertions, 119 deletions
diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index a27893ca2b..c21343510d 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -55,67 +55,11 @@ _route_valid (const NMPlatformIP4Route *r) /*****************************************************************************/ -gboolean -nm_ip_config_obj_id_equal_ip4_address (const NMPlatformIP4Address *a, - const NMPlatformIP4Address *b) -{ - return a->address == b->address - && a->plen == b->plen - && ((a->peer_address ^ b->peer_address) & _nm_utils_ip4_prefix_to_netmask (a->plen)) == 0; -} - -gboolean -nm_ip_config_obj_id_equal_ip6_address (const NMPlatformIP6Address *a, - const NMPlatformIP6Address *b) -{ - return IN6_ARE_ADDR_EQUAL (&a->address, &b->address); -} - -gboolean -nm_ip_config_obj_id_equal_ip4_route (const NMPlatformIP4Route *r_a, - const NMPlatformIP4Route *r_b) -{ - 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 nm_platform_ip6_route_cmp (r_a, r_b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_DST) == 0; -} - static guint _idx_obj_id_hash (const NMDedupMultiIdxType *idx_type, const NMDedupMultiObj *obj) { - const NMPObject *o = (NMPObject *) obj; - guint h; - - switch (NMP_OBJECT_GET_TYPE (o)) { - case NMP_OBJECT_TYPE_IP4_ADDRESS: - h = 1550630563; - h = NM_HASH_COMBINE (h, o->ip4_address.address); - h = NM_HASH_COMBINE (h, o->ip_address.plen); - h = NM_HASH_COMBINE (h, nm_utils_ip4_address_clear_host_address (o->ip4_address.peer_address, o->ip_address.plen)); - break; - case NMP_OBJECT_TYPE_IP6_ADDRESS: - h = 851146661; - h = NM_HASH_COMBINE_IN6ADDR (h, &o->ip6_address.address); - break; - case NMP_OBJECT_TYPE_IP4_ROUTE: - h = 40303327; - 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 (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); - }; - - return h; + return nmp_object_id_hash ((NMPObject *) obj); } static gboolean @@ -123,36 +67,20 @@ _idx_obj_id_equal (const NMDedupMultiIdxType *idx_type, const NMDedupMultiObj *obj_a, const NMDedupMultiObj *obj_b) { - const NMPObject *o_a = (NMPObject *) obj_a; - const NMPObject *o_b = (NMPObject *) obj_b; - - nm_assert (NMP_OBJECT_GET_TYPE (o_a) == NMP_OBJECT_GET_TYPE (o_b)); - - switch (NMP_OBJECT_GET_TYPE (o_a)) { - case NMP_OBJECT_TYPE_IP4_ADDRESS: - return nm_ip_config_obj_id_equal_ip4_address (NMP_OBJECT_CAST_IP4_ADDRESS (o_a), NMP_OBJECT_CAST_IP4_ADDRESS (o_b)); - case NMP_OBJECT_TYPE_IP6_ADDRESS: - return nm_ip_config_obj_id_equal_ip6_address (NMP_OBJECT_CAST_IP6_ADDRESS (o_a), NMP_OBJECT_CAST_IP6_ADDRESS (o_b)); - case NMP_OBJECT_TYPE_IP4_ROUTE: - return nm_ip_config_obj_id_equal_ip4_route (&o_a->ip4_route, &o_b->ip4_route); - case NMP_OBJECT_TYPE_IP6_ROUTE: - return nm_ip_config_obj_id_equal_ip6_route (&o_a->ip6_route, &o_b->ip6_route); - default: - g_return_val_if_reached (FALSE); - }; + return nmp_object_id_equal ((NMPObject *) obj_a, (NMPObject *) obj_b); } -static const NMDedupMultiIdxTypeClass _dedup_multi_idx_type_class = { - .idx_obj_id_hash = _idx_obj_id_hash, - .idx_obj_id_equal = _idx_obj_id_equal, -}; - void nm_ip_config_dedup_multi_idx_type_init (NMIPConfigDedupMultiIdxType *idx_type, NMPObjectType obj_type) { + static const NMDedupMultiIdxTypeClass idx_type_class = { + .idx_obj_id_hash = _idx_obj_id_hash, + .idx_obj_id_equal = _idx_obj_id_equal, + }; + nm_dedup_multi_idx_type_init ((NMDedupMultiIdxType *) idx_type, - &_dedup_multi_idx_type_class); + &idx_type_class); idx_type->obj_type = obj_type; } @@ -325,7 +253,7 @@ _nm_ip_config_lookup_ip_route (const NMDedupMultiIndex *multi_idx, if (!entry) return NULL; - if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_DST) + if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) nm_assert (nm_platform_ip4_route_cmp (NMP_OBJECT_CAST_IP4_ROUTE (entry->obj), NMP_OBJECT_CAST_IP4_ROUTE (needle), cmp_type) == 0); else { if (nm_platform_ip4_route_cmp (NMP_OBJECT_CAST_IP4_ROUTE (entry->obj), @@ -1679,7 +1607,8 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev if (nm_platform_ip4_address_cmp (r_src, r_dst) != 0) { are_equal = FALSE; - if ( !nm_ip_config_obj_id_equal_ip4_address (r_src, r_dst) + if ( r_src->address != r_dst->address + || r_src->plen != r_dst->plen || r_src->peer_address != r_dst->peer_address) { has_relevant_changes = TRUE; break; @@ -1725,7 +1654,8 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev if (nm_platform_ip4_route_cmp_full (r_src, r_dst) != 0) { are_equal = FALSE; - if ( !nm_ip_config_obj_id_equal_ip4_route (r_src, r_dst) + if ( r_src->plen != r_dst->plen + || !nm_utils_ip4_address_same_prefix (r_src->network, r_dst->network, r_src->plen) || r_src->gateway != r_dst->gateway || r_src->metric != r_dst->metric) { has_relevant_changes = TRUE; diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h index 7db858b7b5..a8e22c2e59 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -94,15 +94,6 @@ gboolean _nm_ip_config_best_default_route_merge (const NMPObject **best_default_ /*****************************************************************************/ -gboolean nm_ip_config_obj_id_equal_ip4_address (const NMPlatformIP4Address *a, - const NMPlatformIP4Address *b); -gboolean nm_ip_config_obj_id_equal_ip6_address (const NMPlatformIP6Address *a, - const NMPlatformIP6Address *b); -gboolean nm_ip_config_obj_id_equal_ip4_route (const NMPlatformIP4Route *r_a, - const NMPlatformIP4Route *r_b); -gboolean nm_ip_config_obj_id_equal_ip6_route (const NMPlatformIP6Route *r_a, - const NMPlatformIP6Route *r_b); - gboolean _nm_ip_config_add_obj (NMDedupMultiIndex *multi_idx, NMIPConfigDedupMultiIdxType *idx_type, int ifindex, diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index 85883241d1..97d25d549c 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -1277,7 +1277,7 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev if (nm_platform_ip6_address_cmp (r_src, r_dst) != 0) { are_equal = FALSE; - if ( !nm_ip_config_obj_id_equal_ip6_address (r_src, r_dst) + if ( !IN6_ARE_ADDR_EQUAL (&r_src->address, &r_dst->address) || r_src->plen != r_dst->plen || !IN6_ARE_ADDR_EQUAL (nm_platform_ip6_address_get_peer (r_src), nm_platform_ip6_address_get_peer (r_dst))) { @@ -1325,7 +1325,8 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev if (nm_platform_ip6_route_cmp_full (r_src, r_dst) != 0) { are_equal = FALSE; - if ( !nm_ip_config_obj_id_equal_ip6_route (r_src, r_dst) + if ( r_src->plen != r_dst->plen + || !nm_utils_ip6_address_same_prefix (&r_src->network, &r_dst->network, r_src->plen) || r_src->metric != r_dst->metric || !IN6_ARE_ADDR_EQUAL (&r_src->gateway, &r_dst->gateway)) { has_relevant_changes = TRUE; diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 6a301765f6..4cae03a944 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -5402,10 +5402,6 @@ 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_WEAK_ID: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: h = NM_HASH_COMBINE (h, obj->table_coerced); @@ -5475,10 +5471,6 @@ 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_WEAK_ID: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: NM_CMP_FIELD (a, b, table_coerced); @@ -5553,10 +5545,6 @@ 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_WEAK_ID: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: h = NM_HASH_COMBINE (h, obj->table_coerced); @@ -5617,10 +5605,6 @@ 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_WEAK_ID: case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID: NM_CMP_FIELD (a, b, table_coerced); diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index a703d4c879..8075a08b86 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -129,11 +129,6 @@ typedef enum { */ NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID, - /* 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 diff --git a/src/tests/test-ip4-config.c b/src/tests/test-ip4-config.c index 22d488db73..8c6cd8d15c 100644 --- a/src/tests/test-ip4-config.c +++ b/src/tests/test-ip4-config.c @@ -251,19 +251,19 @@ test_add_route_with_source (void) g_assert_cmpint (nm_ip4_config_get_num_routes (a), ==, 0); /* Test that a lower priority address source is overwritten */ - route.rt_source = NM_IP_CONFIG_SOURCE_KERNEL; + route.rt_source = NM_IP_CONFIG_SOURCE_RTPROT_KERNEL; nm_ip4_config_add_route (a, &route, NULL); g_assert_cmpint (nm_ip4_config_get_num_routes (a), ==, 1); test_route = _nmtst_ip4_config_get_route (a, 0); - g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_KERNEL); + g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_RTPROT_KERNEL); - route.rt_source = NM_IP_CONFIG_SOURCE_USER; + route.rt_source = NM_IP_CONFIG_SOURCE_KERNEL; nm_ip4_config_add_route (a, &route, NULL); g_assert_cmpint (nm_ip4_config_get_num_routes (a), ==, 1); test_route = _nmtst_ip4_config_get_route (a, 0); - g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER); + g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_KERNEL); } static void |