summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2017-09-11 21:41:57 +0200
committerThomas Haller <thaller@redhat.com>2017-09-13 08:17:31 +0200
commitaee48dfd44c9e469303573fb6d02b0d0113658c5 (patch)
tree113de66f95922b2b9bce3757a0bdd01996a3c127
parente730ae7600854d159667d972717e2f0a7639ac42 (diff)
downloadNetworkManager-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.c96
-rw-r--r--src/nm-ip4-config.h9
-rw-r--r--src/nm-ip6-config.c5
-rw-r--r--src/platform/nm-platform.c16
-rw-r--r--src/platform/nm-platform.h5
-rw-r--r--src/tests/test-ip4-config.c8
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