summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2017-07-26 10:50:23 +0200
committerThomas Haller <thaller@redhat.com>2017-08-03 18:32:59 +0200
commit372f14a6ef724c407c7e1ff1f52d8777c16bd33e (patch)
tree97bb64071c202dceac6d8b4dfeb1ee6838c6b669
parent54f8c2ac22b0df9d7316744808163e95f573dfbd (diff)
downloadNetworkManager-372f14a6ef724c407c7e1ff1f52d8777c16bd33e.tar.gz
platform: add compare functions for routes with different compare semantics
Routes are complicated. `ip route add` and `ip route append` behaves differently with respect to determine whether an existing route is idential or not. Extend the cmp() and hash() functions to have a compare type, that covers the different semantics.
-rw-r--r--src/nm-core-utils.h26
-rw-r--r--src/nm-default-route-manager.c4
-rw-r--r--src/nm-ip4-config.c6
-rw-r--r--src/nm-ip6-config.c2
-rw-r--r--src/nm-route-manager.c2
-rw-r--r--src/nm-test-utils-core.h8
-rw-r--r--src/platform/nm-platform.c297
-rw-r--r--src/platform/nm-platform.h73
-rw-r--r--src/platform/nmp-object.c54
-rw-r--r--src/platform/tests/test-route.c14
-rw-r--r--src/tests/test-route-manager.c2
11 files changed, 310 insertions, 178 deletions
diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h
index 99d9e9c486..42afcb0e2d 100644
--- a/src/nm-core-utils.h
+++ b/src/nm-core-utils.h
@@ -111,12 +111,6 @@ extern const NMIPAddr nm_ip_addr_zero;
guint nm_utils_in6_addr_hash (const struct in6_addr *addr);
-static inline guint
-NM_HASH_COMBINE_IN6_ADDR (guint h, const struct in6_addr *addr)
-{
- return NM_HASH_COMBINE (h, addr ? nm_utils_in6_addr_hash (addr) : 0);
-}
-
gboolean nm_ethernet_address_is_valid (gconstpointer addr, gssize len);
gconstpointer nm_utils_ipx_address_clear_host_address (int family, gpointer dst, gconstpointer src, guint8 plen);
@@ -143,6 +137,26 @@ nm_utils_ip6_address_same_prefix (const struct in6_addr *addr_a, const struct in
htonl (nm_utils_ip4_address_clear_host_address (_ab, _plen))); \
} G_STMT_END
+static inline guint
+NM_HASH_COMBINE_IN6ADDR (guint h, const struct in6_addr *addr)
+{
+ if (!addr)
+ g_return_val_if_reached (h);
+ return NM_HASH_COMBINE (h, nm_utils_in6_addr_hash (addr));
+}
+
+static inline guint
+NM_HASH_COMBINE_IN6ADDR_PREFIX (guint h, const struct in6_addr *addr, guint8 plen)
+{
+ struct in6_addr a;
+
+ if (!addr)
+ g_return_val_if_reached (h);
+ nm_utils_ip6_address_clear_host_address (&a, addr, plen);
+ /* we don't hash plen itself. The caller may want to do that.*/
+ return NM_HASH_COMBINE (h, nm_utils_in6_addr_hash (&a));
+}
+
double nm_utils_exp10 (gint16 e);
/**
diff --git a/src/nm-default-route-manager.c b/src/nm-default-route-manager.c
index fc209fc852..eeaf38fc4e 100644
--- a/src/nm-default-route-manager.c
+++ b/src/nm-default-route-manager.c
@@ -212,7 +212,7 @@ _vt_routes_has_entry (const VTableIP *vtable, const GPtrArray *routes, const Ent
const NMPlatformIP4Route *r = NMP_OBJECT_CAST_IP4_ROUTE (routes->pdata[i]);
route.rx.rt_source = r->rt_source;
- if (nm_platform_ip4_route_cmp (r, &route.r4) == 0)
+ if (nm_platform_ip4_route_cmp_full (r, &route.r4) == 0)
return TRUE;
}
} else {
@@ -220,7 +220,7 @@ _vt_routes_has_entry (const VTableIP *vtable, const GPtrArray *routes, const Ent
const NMPlatformIP6Route *r = NMP_OBJECT_CAST_IP6_ROUTE (routes->pdata[i]);
route.rx.rt_source = r->rt_source;
- if (nm_platform_ip6_route_cmp (r, &route.r6) == 0)
+ if (nm_platform_ip6_route_cmp_full (r, &route.r6) == 0)
return TRUE;
}
}
diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c
index 808ea31263..64d71fae88 100644
--- a/src/nm-ip4-config.c
+++ b/src/nm-ip4-config.c
@@ -104,7 +104,7 @@ _idx_obj_id_hash (const NMDedupMultiIdxType *idx_type,
break;
case NMP_OBJECT_TYPE_IP6_ADDRESS:
h = 851146661;
- h = NM_HASH_COMBINE_IN6_ADDR (h, &o->ip6_address.address);
+ h = NM_HASH_COMBINE_IN6ADDR (h, &o->ip6_address.address);
break;
case NMP_OBJECT_TYPE_IP4_ROUTE:
h = 40303327;
@@ -113,7 +113,7 @@ _idx_obj_id_hash (const NMDedupMultiIdxType *idx_type,
break;
case NMP_OBJECT_TYPE_IP6_ROUTE:
h = 577629323;
- h = NM_HASH_COMBINE_IN6_ADDR (h, &o->ip6_route.network);
+ h = NM_HASH_COMBINE_IN6ADDR (h, &o->ip6_route.network);
h = NM_HASH_COMBINE (h, o->ip_route.plen);
break;
default:
@@ -1512,7 +1512,7 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev
if (!has)
break;
- if (nm_platform_ip4_route_cmp (r_src, r_dst) != 0) {
+ 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)
|| r_src->gateway != r_dst->gateway
diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c
index 3b66442ab5..dafc63cbfc 100644
--- a/src/nm-ip6-config.c
+++ b/src/nm-ip6-config.c
@@ -1291,7 +1291,7 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev
if (!has)
break;
- if (nm_platform_ip6_route_cmp (r_src, r_dst) != 0) {
+ 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)
|| r_src->metric != r_dst->metric
diff --git a/src/nm-route-manager.c b/src/nm-route-manager.c
index a54deebe47..07947d790c 100644
--- a/src/nm-route-manager.c
+++ b/src/nm-route-manager.c
@@ -428,7 +428,7 @@ _route_equals_ignoring_ifindex (const VTableIP *vtable, const NMPlatformIPXRoute
r2_backup.rx.metric = (guint32) r2_metric;
r2 = &r2_backup;
}
- return vtable->vt->route_cmp (r1, r2, FALSE) == 0;
+ return vtable->vt->route_cmp (r1, r2, NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) == 0;
}
static NMPlatformIPXRoute *
diff --git a/src/nm-test-utils-core.h b/src/nm-test-utils-core.h
index 879e9190af..58beadcdf1 100644
--- a/src/nm-test-utils-core.h
+++ b/src/nm-test-utils-core.h
@@ -195,7 +195,7 @@ nmtst_platform_ip6_route_full (const char *network, guint plen, const char *gate
static inline int
_nmtst_platform_ip4_routes_equal_sort (gconstpointer a, gconstpointer b, gpointer user_data)
{
- return nm_platform_ip4_route_cmp ((const NMPlatformIP4Route *) a, (const NMPlatformIP4Route *) b);
+ return nm_platform_ip4_route_cmp_full ((const NMPlatformIP4Route *) a, (const NMPlatformIP4Route *) b);
}
static inline void
@@ -215,7 +215,7 @@ nmtst_platform_ip4_routes_equal (const NMPlatformIP4Route *a, const NMPlatformIP
}
for (i = 0; i < len; i++) {
- if (nm_platform_ip4_route_cmp (&a[i], &b[i]) != 0) {
+ if (nm_platform_ip4_route_cmp_full (&a[i], &b[i]) != 0) {
char buf[sizeof (_nm_utils_to_string_buffer)];
g_error ("Error comparing IPv4 route[%lu]: %s vs %s", (unsigned long) i,
@@ -248,7 +248,7 @@ nmtst_platform_ip4_routes_equal_aptr (const NMPObject *const*a, const NMPlatform
static inline int
_nmtst_platform_ip6_routes_equal_sort (gconstpointer a, gconstpointer b, gpointer user_data)
{
- return nm_platform_ip6_route_cmp ((const NMPlatformIP6Route *) a, (const NMPlatformIP6Route *) b);
+ return nm_platform_ip6_route_cmp_full ((const NMPlatformIP6Route *) a, (const NMPlatformIP6Route *) b);
}
static inline void
@@ -268,7 +268,7 @@ nmtst_platform_ip6_routes_equal (const NMPlatformIP6Route *a, const NMPlatformIP
}
for (i = 0; i < len; i++) {
- if (nm_platform_ip6_route_cmp (&a[i], &b[i]) != 0) {
+ if (nm_platform_ip6_route_cmp_full (&a[i], &b[i]) != 0) {
char buf[sizeof (_nm_utils_to_string_buffer)];
g_error ("Error comparing IPv6 route[%lu]: %s vs %s", (unsigned long) i,
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c
index 3cdfba882a..46d1db345d 100644
--- a/src/platform/nm-platform.c
+++ b/src/platform/nm-platform.c
@@ -4442,8 +4442,8 @@ nm_platform_lnk_ip6tnl_hash (const NMPlatformLnkIp6Tnl *obj)
guint h = 1651660009;
h = NM_HASH_COMBINE (h, obj->parent_ifindex);
- h = NM_HASH_COMBINE (h, nm_utils_in6_addr_hash (&obj->local));
- h = NM_HASH_COMBINE (h, nm_utils_in6_addr_hash (&obj->remote));
+ h = NM_HASH_COMBINE_IN6ADDR (h, &obj->local);
+ h = NM_HASH_COMBINE_IN6ADDR (h, &obj->remote);
h = NM_HASH_COMBINE (h, obj->ttl);
h = NM_HASH_COMBINE (h, obj->tclass);
h = NM_HASH_COMBINE (h, obj->encap_limit);
@@ -4613,8 +4613,8 @@ nm_platform_lnk_vxlan_hash (const NMPlatformLnkVxlan *obj)
h = NM_HASH_COMBINE (h, obj->id);
h = NM_HASH_COMBINE (h, obj->group);
h = NM_HASH_COMBINE (h, obj->local);
- h = NM_HASH_COMBINE_IN6_ADDR (h, &obj->group6);
- h = NM_HASH_COMBINE_IN6_ADDR (h, &obj->local6);
+ h = NM_HASH_COMBINE_IN6ADDR (h, &obj->group6);
+ h = NM_HASH_COMBINE_IN6ADDR (h, &obj->local6);
h = NM_HASH_COMBINE (h, obj->tos);
h = NM_HASH_COMBINE (h, obj->ttl);
h = NM_HASH_COMBINE (h, obj->learning);
@@ -4699,9 +4699,9 @@ nm_platform_ip6_address_hash (const NMPlatformIP6Address *obj)
if (obj) {
h = NM_HASH_COMBINE (h, obj->ifindex);
- h = NM_HASH_COMBINE (h, nm_utils_in6_addr_hash (&obj->address));
+ h = NM_HASH_COMBINE_IN6ADDR (h, &obj->address);
h = NM_HASH_COMBINE (h, obj->plen);
- h = NM_HASH_COMBINE (h, nm_utils_in6_addr_hash (&obj->peer_address));
+ h = NM_HASH_COMBINE_IN6ADDR (h, &obj->peer_address);
h = NM_HASH_COMBINE (h, obj->addr_source);
h = NM_HASH_COMBINE (h, obj->timestamp);
h = NM_HASH_COMBINE (h, obj->lifetime);
@@ -4732,135 +4732,210 @@ nm_platform_ip6_address_cmp (const NMPlatformIP6Address *a, const NMPlatformIP6A
}
guint
-nm_platform_ip4_route_hash (const NMPlatformIP4Route *obj)
+nm_platform_ip4_route_hash (const NMPlatformIP4Route *obj, NMPlatformIPRouteCmpType cmp_type)
{
- guint h = 1228913327;
+ guint h = NM_HASH_COMBINE (1228913327, cmp_type);
if (obj) {
- h = NM_HASH_COMBINE (h, obj->ifindex);
- h = NM_HASH_COMBINE (h, obj->network);
- h = NM_HASH_COMBINE (h, obj->plen);
- h = NM_HASH_COMBINE (h, obj->metric);
- h = NM_HASH_COMBINE (h, obj->gateway);
- h = NM_HASH_COMBINE (h, obj->rt_source);
- h = NM_HASH_COMBINE (h, obj->mss);
- h = NM_HASH_COMBINE (h, obj->scope_inv);
- h = NM_HASH_COMBINE (h, obj->pref_src);
- h = NM_HASH_COMBINE (h, obj->rt_cloned);
- h = NM_HASH_COMBINE (h, obj->tos);
- h = NM_HASH_COMBINE (h, obj->lock_window);
- h = NM_HASH_COMBINE (h, obj->lock_cwnd);
- h = NM_HASH_COMBINE (h, obj->lock_initcwnd);
- h = NM_HASH_COMBINE (h, obj->lock_initrwnd);
- h = NM_HASH_COMBINE (h, obj->lock_mtu);
- h = NM_HASH_COMBINE (h, obj->window);
- h = NM_HASH_COMBINE (h, obj->cwnd);
- h = NM_HASH_COMBINE (h, obj->initcwnd);
- h = NM_HASH_COMBINE (h, obj->initrwnd);
- h = NM_HASH_COMBINE (h, obj->mtu);
+ switch (cmp_type) {
+ 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);
+ h = NM_HASH_COMBINE (h, obj->metric);
+ h = NM_HASH_COMBINE (h, obj->ifindex);
+ break;
+ case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID:
+ case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID:
+ h = NM_HASH_COMBINE (h, nm_utils_ip4_address_clear_host_address (obj->network, obj->plen));
+ h = NM_HASH_COMBINE (h, obj->plen);
+ h = NM_HASH_COMBINE (h, obj->metric);
+ if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID)
+ h = NM_HASH_COMBINE (h, obj->ifindex);
+ break;
+ case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY:
+ case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL:
+ h = NM_HASH_COMBINE (h, obj->ifindex);
+ if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY)
+ h = NM_HASH_COMBINE (h, nm_utils_ip4_address_clear_host_address (obj->network, obj->plen));
+ else
+ h = NM_HASH_COMBINE (h, obj->network);
+ h = NM_HASH_COMBINE (h, obj->plen);
+ h = NM_HASH_COMBINE (h, obj->metric);
+ h = NM_HASH_COMBINE (h, obj->gateway);
+ h = NM_HASH_COMBINE (h, obj->rt_source);
+ h = NM_HASH_COMBINE (h, obj->mss);
+ h = NM_HASH_COMBINE (h, obj->scope_inv);
+ h = NM_HASH_COMBINE (h, obj->pref_src);
+ h = NM_HASH_COMBINE (h, obj->rt_cloned);
+ h = NM_HASH_COMBINE (h, obj->tos);
+ h = NM_HASH_COMBINE (h, obj->lock_window);
+ h = NM_HASH_COMBINE (h, obj->lock_cwnd);
+ h = NM_HASH_COMBINE (h, obj->lock_initcwnd);
+ h = NM_HASH_COMBINE (h, obj->lock_initrwnd);
+ h = NM_HASH_COMBINE (h, obj->lock_mtu);
+ h = NM_HASH_COMBINE (h, obj->window);
+ h = NM_HASH_COMBINE (h, obj->cwnd);
+ h = NM_HASH_COMBINE (h, obj->initcwnd);
+ h = NM_HASH_COMBINE (h, obj->initrwnd);
+ h = NM_HASH_COMBINE (h, obj->mtu);
+ break;
+ }
}
return h;
}
int
-nm_platform_ip4_route_cmp_full (const NMPlatformIP4Route *a, const NMPlatformIP4Route *b, gboolean consider_host_part)
+nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route *b, NMPlatformIPRouteCmpType cmp_type)
{
NM_CMP_SELF (a, b);
- NM_CMP_FIELD (a, b, ifindex);
- if (consider_host_part)
- NM_CMP_FIELD (a, b, network);
- else {
- NM_CMP_DIRECT (nm_utils_ip4_address_clear_host_address (a->network, a->plen),
- nm_utils_ip4_address_clear_host_address (b->network, b->plen));
+ switch (cmp_type) {
+ 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);
+ NM_CMP_FIELD (a, b, metric);
+ NM_CMP_FIELD (a, b, ifindex);
+ break;
+ case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID:
+ case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID:
+ NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX (a->network, b->network, MIN (a->plen, b->plen));
+ NM_CMP_FIELD (a, b, plen);
+ NM_CMP_FIELD (a, b, metric);
+ if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID)
+ NM_CMP_FIELD (a, b, ifindex);
+ break;
+ case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY:
+ case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL:
+ NM_CMP_FIELD (a, b, ifindex);
+ if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY)
+ NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX (a->network, b->network, MIN (a->plen, b->plen));
+ else
+ NM_CMP_FIELD (a, b, network);
+ NM_CMP_FIELD (a, b, plen);
+ NM_CMP_FIELD (a, b, metric);
+ NM_CMP_FIELD (a, b, gateway);
+ NM_CMP_FIELD (a, b, rt_source);
+ NM_CMP_FIELD (a, b, mss);
+ NM_CMP_FIELD (a, b, scope_inv);
+ NM_CMP_FIELD (a, b, pref_src);
+ NM_CMP_FIELD_UNSAFE (a, b, rt_cloned);
+ NM_CMP_FIELD (a, b, tos);
+ NM_CMP_FIELD_UNSAFE (a, b, lock_window);
+ NM_CMP_FIELD_UNSAFE (a, b, lock_cwnd);
+ NM_CMP_FIELD_UNSAFE (a, b, lock_initcwnd);
+ NM_CMP_FIELD_UNSAFE (a, b, lock_initrwnd);
+ NM_CMP_FIELD_UNSAFE (a, b, lock_mtu);
+ NM_CMP_FIELD (a, b, window);
+ NM_CMP_FIELD (a, b, cwnd);
+ NM_CMP_FIELD (a, b, initcwnd);
+ NM_CMP_FIELD (a, b, initrwnd);
+ NM_CMP_FIELD (a, b, mtu);
+ break;
}
- NM_CMP_FIELD (a, b, plen);
- NM_CMP_FIELD (a, b, metric);
- NM_CMP_FIELD (a, b, gateway);
- NM_CMP_FIELD (a, b, rt_source);
- NM_CMP_FIELD (a, b, mss);
- NM_CMP_FIELD (a, b, scope_inv);
- NM_CMP_FIELD (a, b, pref_src);
- NM_CMP_FIELD_UNSAFE (a, b, rt_cloned);
- NM_CMP_FIELD (a, b, tos);
- NM_CMP_FIELD_UNSAFE (a, b, lock_window);
- NM_CMP_FIELD_UNSAFE (a, b, lock_cwnd);
- NM_CMP_FIELD_UNSAFE (a, b, lock_initcwnd);
- NM_CMP_FIELD_UNSAFE (a, b, lock_initrwnd);
- NM_CMP_FIELD_UNSAFE (a, b, lock_mtu);
- NM_CMP_FIELD (a, b, window);
- NM_CMP_FIELD (a, b, cwnd);
- NM_CMP_FIELD (a, b, initcwnd);
- NM_CMP_FIELD (a, b, initrwnd);
- NM_CMP_FIELD (a, b, mtu);
return 0;
}
guint
-nm_platform_ip6_route_hash (const NMPlatformIP6Route *obj)
+nm_platform_ip6_route_hash (const NMPlatformIP6Route *obj, NMPlatformIPRouteCmpType cmp_type)
{
- guint h = 1053326051;
+ guint h = NM_HASH_COMBINE (1053326051, cmp_type);
if (obj) {
- h = NM_HASH_COMBINE (h, obj->ifindex);
- h = NM_HASH_COMBINE (h, nm_utils_in6_addr_hash (&obj->network));
- h = NM_HASH_COMBINE (h, obj->plen);
- h = NM_HASH_COMBINE (h, obj->metric);
- h = NM_HASH_COMBINE (h, nm_utils_in6_addr_hash (&obj->gateway));
- h = NM_HASH_COMBINE (h, nm_utils_in6_addr_hash (&obj->pref_src));
- h = NM_HASH_COMBINE (h, nm_utils_in6_addr_hash (&obj->src));
- h = NM_HASH_COMBINE (h, obj->src_plen);
- h = NM_HASH_COMBINE (h, obj->rt_source);
- h = NM_HASH_COMBINE (h, obj->mss);
- h = NM_HASH_COMBINE (h, obj->rt_cloned);
- h = NM_HASH_COMBINE (h, obj->tos);
- h = NM_HASH_COMBINE (h, obj->lock_window);
- h = NM_HASH_COMBINE (h, obj->lock_cwnd);
- h = NM_HASH_COMBINE (h, obj->lock_initcwnd);
- h = NM_HASH_COMBINE (h, obj->lock_initrwnd);
- h = NM_HASH_COMBINE (h, obj->lock_mtu);
- h = NM_HASH_COMBINE (h, obj->window);
- h = NM_HASH_COMBINE (h, obj->cwnd);
- h = NM_HASH_COMBINE (h, obj->initcwnd);
- h = NM_HASH_COMBINE (h, obj->initrwnd);
- h = NM_HASH_COMBINE (h, obj->mtu);
+ switch (cmp_type) {
+ 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);
+ h = NM_HASH_COMBINE (h, obj->metric);
+ h = NM_HASH_COMBINE (h, obj->ifindex);
+ break;
+ case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID:
+ case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID:
+ h = NM_HASH_COMBINE_IN6ADDR_PREFIX (h, &obj->network, obj->plen);
+ h = NM_HASH_COMBINE (h, obj->plen);
+ h = NM_HASH_COMBINE (h, obj->metric);
+ if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID)
+ h = NM_HASH_COMBINE (h, obj->ifindex);
+ break;
+ case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY:
+ case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL:
+ h = NM_HASH_COMBINE (h, obj->ifindex);
+ if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY)
+ h = NM_HASH_COMBINE_IN6ADDR_PREFIX (h, &obj->network, obj->plen);
+ else
+ h = NM_HASH_COMBINE_IN6ADDR (h, &obj->network);
+ h = NM_HASH_COMBINE (h, obj->plen);
+ h = NM_HASH_COMBINE (h, obj->metric);
+ h = NM_HASH_COMBINE_IN6ADDR (h, &obj->gateway);
+ h = NM_HASH_COMBINE_IN6ADDR (h, &obj->pref_src);
+ h = NM_HASH_COMBINE_IN6ADDR (h, &obj->src);
+ h = NM_HASH_COMBINE (h, obj->src_plen);
+ h = NM_HASH_COMBINE (h, obj->rt_source);
+ h = NM_HASH_COMBINE (h, obj->mss);
+ h = NM_HASH_COMBINE (h, obj->rt_cloned);
+ h = NM_HASH_COMBINE (h, obj->tos);
+ h = NM_HASH_COMBINE (h, obj->lock_window);
+ h = NM_HASH_COMBINE (h, obj->lock_cwnd);
+ h = NM_HASH_COMBINE (h, obj->lock_initcwnd);
+ h = NM_HASH_COMBINE (h, obj->lock_initrwnd);
+ h = NM_HASH_COMBINE (h, obj->lock_mtu);
+ h = NM_HASH_COMBINE (h, obj->window);
+ h = NM_HASH_COMBINE (h, obj->cwnd);
+ h = NM_HASH_COMBINE (h, obj->initcwnd);
+ h = NM_HASH_COMBINE (h, obj->initrwnd);
+ h = NM_HASH_COMBINE (h, obj->mtu);
+ break;
+ }
}
return h;
}
int
-nm_platform_ip6_route_cmp_full (const NMPlatformIP6Route *a, const NMPlatformIP6Route *b, gboolean consider_host_part)
+nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6Route *b, NMPlatformIPRouteCmpType cmp_type)
{
NM_CMP_SELF (a, b);
- NM_CMP_FIELD (a, b, ifindex);
- if (consider_host_part)
- NM_CMP_FIELD_IN6ADDR (a, b, network);
- else {
- struct in6_addr n1, n2;
-
- nm_utils_ip6_address_clear_host_address (&n1, &a->network, a->plen);
- nm_utils_ip6_address_clear_host_address (&n2, &b->network, b->plen);
- NM_CMP_DIRECT_IN6ADDR (&n1, &n2);
+ switch (cmp_type) {
+ 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);
+ NM_CMP_FIELD (a, b, metric);
+ NM_CMP_FIELD (a, b, ifindex);
+ break;
+ case NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID:
+ case NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID:
+ NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX (&a->network, &b->network, MIN (a->plen, b->plen));
+ NM_CMP_FIELD (a, b, plen);
+ NM_CMP_FIELD (a, b, metric);
+ if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID)
+ NM_CMP_FIELD (a, b, ifindex);
+ break;
+ case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY:
+ case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL:
+ NM_CMP_FIELD (a, b, ifindex);
+ if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY)
+ NM_CMP_DIRECT_IN6ADDR_SAME_PREFIX (&a->network, &b->network, MIN (a->plen, b->plen));
+ else
+ NM_CMP_FIELD_IN6ADDR (a, b, network);
+ NM_CMP_FIELD (a, b, plen);
+ NM_CMP_FIELD (a, b, metric);
+ NM_CMP_FIELD_IN6ADDR (a, b, gateway);
+ NM_CMP_FIELD_IN6ADDR (a, b, pref_src);
+ NM_CMP_FIELD_IN6ADDR (a, b, src);
+ NM_CMP_FIELD (a, b, src_plen);
+ NM_CMP_FIELD (a, b, rt_source);
+ NM_CMP_FIELD (a, b, mss);
+ NM_CMP_FIELD_UNSAFE (a, b, rt_cloned);
+ NM_CMP_FIELD (a, b, tos);
+ NM_CMP_FIELD_UNSAFE (a, b, lock_window);
+ NM_CMP_FIELD_UNSAFE (a, b, lock_cwnd);
+ NM_CMP_FIELD_UNSAFE (a, b, lock_initcwnd);
+ NM_CMP_FIELD_UNSAFE (a, b, lock_initrwnd);
+ NM_CMP_FIELD_UNSAFE (a, b, lock_mtu);
+ NM_CMP_FIELD (a, b, window);
+ NM_CMP_FIELD (a, b, cwnd);
+ NM_CMP_FIELD (a, b, initcwnd);
+ NM_CMP_FIELD (a, b, initrwnd);
+ NM_CMP_FIELD (a, b, mtu);
+ break;
}
- NM_CMP_FIELD (a, b, plen);
- NM_CMP_FIELD (a, b, metric);
- NM_CMP_FIELD_IN6ADDR (a, b, gateway);
- NM_CMP_FIELD_IN6ADDR (a, b, pref_src);
- NM_CMP_FIELD_IN6ADDR (a, b, src);
- NM_CMP_FIELD (a, b, src_plen);
- NM_CMP_FIELD (a, b, rt_source);
- NM_CMP_FIELD (a, b, mss);
- NM_CMP_FIELD_UNSAFE (a, b, rt_cloned);
- NM_CMP_FIELD (a, b, tos);
- NM_CMP_FIELD_UNSAFE (a, b, lock_window);
- NM_CMP_FIELD_UNSAFE (a, b, lock_cwnd);
- NM_CMP_FIELD_UNSAFE (a, b, lock_initcwnd);
- NM_CMP_FIELD_UNSAFE (a, b, lock_initrwnd);
- NM_CMP_FIELD_UNSAFE (a, b, lock_mtu);
- NM_CMP_FIELD (a, b, window);
- NM_CMP_FIELD (a, b, cwnd);
- NM_CMP_FIELD (a, b, initcwnd);
- NM_CMP_FIELD (a, b, initrwnd);
- NM_CMP_FIELD (a, b, mtu);
return 0;
}
@@ -5101,7 +5176,7 @@ const NMPlatformVTableRoute nm_platform_vtable_route_v4 = {
.obj_type = NMP_OBJECT_TYPE_IP4_ROUTE,
.addr_family = AF_INET,
.sizeof_route = sizeof (NMPlatformIP4Route),
- .route_cmp = (int (*) (const NMPlatformIPXRoute *a, const NMPlatformIPXRoute *b, gboolean consider_host_part)) nm_platform_ip4_route_cmp_full,
+ .route_cmp = (int (*) (const NMPlatformIPXRoute *a, const NMPlatformIPXRoute *b, NMPlatformIPRouteCmpType cmp_type)) nm_platform_ip4_route_cmp,
.route_to_string = (const char *(*) (const NMPlatformIPXRoute *route, char *buf, gsize len)) nm_platform_ip4_route_to_string,
.route_add = _vtr_v4_route_add,
.metric_normalize = _vtr_v4_metric_normalize,
@@ -5112,7 +5187,7 @@ const NMPlatformVTableRoute nm_platform_vtable_route_v6 = {
.obj_type = NMP_OBJECT_TYPE_IP6_ROUTE,
.addr_family = AF_INET6,
.sizeof_route = sizeof (NMPlatformIP6Route),
- .route_cmp = (int (*) (const NMPlatformIPXRoute *a, const NMPlatformIPXRoute *b, gboolean consider_host_part)) nm_platform_ip6_route_cmp_full,
+ .route_cmp = (int (*) (const NMPlatformIPXRoute *a, const NMPlatformIPXRoute *b, NMPlatformIPRouteCmpType cmp_type)) nm_platform_ip6_route_cmp,
.route_to_string = (const char *(*) (const NMPlatformIPXRoute *route, char *buf, gsize len)) nm_platform_ip6_route_to_string,
.route_add = _vtr_v6_route_add,
.metric_normalize = nm_utils_ip6_route_metric_normalize,
diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h
index 956e718223..e1be802276 100644
--- a/src/platform/nm-platform.h
+++ b/src/platform/nm-platform.h
@@ -73,6 +73,48 @@ struct udev_device;
/* Redefine this in host's endianness */
#define NM_GRE_KEY 0x2000
+typedef enum {
+ /* compare fields which kernel considers as similar routes.
+ * It is a looser comparisong then NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID
+ * and means that `ip route add` would fail to add two routes
+ * that have the same NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID.
+ * On the other hand, `ip route append` would allow that, as
+ * long as NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID differs. */
+ NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID,
+
+ /* compare two routes as kernel would allow to add them with
+ * `ip route append`. In other words, kernel does not allow you to
+ * add two routes (at the same time) which compare equal according
+ * to NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID.
+ *
+ * For the ID we can only recognize route fields that we actually implement.
+ * However, kernel supports more routing options, some of them also part of
+ * the ID. NetworkManager is oblivious to these options and will wrongly think
+ * that two routes are idential, while they are not. That can lead to an
+ * inconsistent platform cache. Not much what we can do about that, except
+ * implementing all options that kernel supports *sigh*. See rh#1337860.
+ */
+ NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID,
+
+ /* FIXME: this type is what NMPCache currently uses for object identity.
+ * Eventually, we want to use NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID,
+ * which is the same what kernel does. */
+ NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID_CACHE,
+
+ /* 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
+ * routes are identical, but NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL will
+ * report them as different. */
+ NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY,
+
+ /* compare all fields. This should have the same effect as memcmp(),
+ * except allowing for undefined data in holes between field alignment.
+ */
+ NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL,
+
+} NMPlatformIPRouteCmpType;
+
typedef enum { /*< skip >*/
/* dummy value, to enforce that the enum type is signed and has a size
@@ -364,7 +406,7 @@ typedef struct {
NMPObjectType obj_type;
int addr_family;
gsize sizeof_route;
- int (*route_cmp) (const NMPlatformIPXRoute *a, const NMPlatformIPXRoute *b, gboolean consider_host_part);
+ int (*route_cmp) (const NMPlatformIPXRoute *a, const NMPlatformIPXRoute *b, NMPlatformIPRouteCmpType cmp_type);
const char *(*route_to_string) (const NMPlatformIPXRoute *route, char *buf, gsize len);
gboolean (*route_add) (NMPlatform *self, int ifindex, const NMPlatformIPXRoute *route, gint64 metric);
guint32 (*metric_normalize) (guint32 metric);
@@ -991,26 +1033,27 @@ int nm_platform_lnk_vlan_cmp (const NMPlatformLnkVlan *a, const NMPlatformLnkVla
int nm_platform_lnk_vxlan_cmp (const NMPlatformLnkVxlan *a, const NMPlatformLnkVxlan *b);
int nm_platform_ip4_address_cmp (const NMPlatformIP4Address *a, const NMPlatformIP4Address *b);
int nm_platform_ip6_address_cmp (const NMPlatformIP6Address *a, const NMPlatformIP6Address *b);
-int nm_platform_ip4_route_cmp_full (const NMPlatformIP4Route *a, const NMPlatformIP4Route *b, gboolean consider_host_part);
-int nm_platform_ip6_route_cmp_full (const NMPlatformIP6Route *a, const NMPlatformIP6Route *b, gboolean consider_host_part);
+
+int nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route *b, NMPlatformIPRouteCmpType cmp_type);
+int nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6Route *b, NMPlatformIPRouteCmpType cmp_type);
static inline int
-nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route *b)
+nm_platform_ip4_route_cmp_full (const NMPlatformIP4Route *a, const NMPlatformIP4Route *b)
{
- return nm_platform_ip4_route_cmp_full (a, b, TRUE);
+ return nm_platform_ip4_route_cmp (a, b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL);
}
static inline int
-nm_platform_ip6_route_cmp (const NMPlatformIP6Route *a, const NMPlatformIP6Route *b)
+nm_platform_ip6_route_cmp_full (const NMPlatformIP6Route *a, const NMPlatformIP6Route *b)
{
- return nm_platform_ip6_route_cmp_full (a, b, TRUE);
+ return nm_platform_ip6_route_cmp (a, b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL);
}
guint nm_platform_link_hash (const NMPlatformLink *obj);
guint nm_platform_ip4_address_hash (const NMPlatformIP4Address *obj);
guint nm_platform_ip6_address_hash (const NMPlatformIP6Address *obj);
-guint nm_platform_ip4_route_hash (const NMPlatformIP4Route *obj);
-guint nm_platform_ip6_route_hash (const NMPlatformIP6Route *obj);
+guint nm_platform_ip4_route_hash (const NMPlatformIP4Route *obj, NMPlatformIPRouteCmpType cmp_type);
+guint nm_platform_ip6_route_hash (const NMPlatformIP6Route *obj, NMPlatformIPRouteCmpType cmp_type);
guint nm_platform_lnk_gre_hash (const NMPlatformLnkGre *obj);
guint nm_platform_lnk_infiniband_hash (const NMPlatformLnkInfiniband *obj);
guint nm_platform_lnk_ip6tnl_hash (const NMPlatformLnkIp6Tnl *obj);
@@ -1021,6 +1064,18 @@ guint nm_platform_lnk_sit_hash (const NMPlatformLnkSit *obj);
guint nm_platform_lnk_vlan_hash (const NMPlatformLnkVlan *obj);
guint nm_platform_lnk_vxlan_hash (const NMPlatformLnkVxlan *obj);
+static inline guint
+nm_platform_ip4_route_hash_full (const NMPlatformIP4Route *obj)
+{
+ return nm_platform_ip4_route_hash (obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL);
+}
+
+static inline guint
+nm_platform_ip6_route_hash_full (const NMPlatformIP6Route *obj)
+{
+ return nm_platform_ip6_route_hash (obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL);
+}
+
gboolean nm_platform_check_support_kernel_extended_ifa_flags (NMPlatform *self);
gboolean nm_platform_check_support_user_ipv6ll (NMPlatform *self);
diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c
index 42a4307978..47ee21394b 100644
--- a/src/platform/nmp-object.c
+++ b/src/platform/nmp-object.c
@@ -225,21 +225,16 @@ _idx_obj_part (const DedupMultiIdxType *idx_type,
if (obj_b) {
return obj_type == NMP_OBJECT_GET_TYPE (obj_b)
&& obj_b->object.ifindex > 0
- && obj_a->ip_route.plen == obj_b->ip_route.plen
- && obj_a->ip_route.metric == obj_b->ip_route.metric
&& (obj_type == NMP_OBJECT_TYPE_IP4_ROUTE
- ? obj_a->ip4_route.network == obj_b->ip4_route.network
- : IN6_ARE_ADDR_EQUAL (&obj_a->ip6_route.network, &obj_b->ip6_route.network));
+ ? (nm_platform_ip4_route_cmp (&obj_a->ip4_route, &obj_b->ip4_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID) == 0)
+ : (nm_platform_ip6_route_cmp (&obj_a->ip6_route, &obj_b->ip6_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID) == 0));
}
if (request_hash) {
h = (guint) idx_type->cache_id_type;
- h = NM_HASH_COMBINE (h, obj_a->ip_route.plen);
- h = NM_HASH_COMBINE (h, obj_a->ip_route.metric);
- h = NM_HASH_COMBINE (h, obj_type);
if (obj_type == NMP_OBJECT_TYPE_IP4_ROUTE)
- h = NM_HASH_COMBINE (h, obj_a->ip4_route.network);
+ h = NM_HASH_COMBINE (h, nm_platform_ip4_route_hash (&obj_a->ip4_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID));
else
- h = NM_HASH_COMBINE (h, nm_utils_in6_addr_hash (&obj_a->ip6_route.network));
+ h = NM_HASH_COMBINE (h, nm_platform_ip6_route_hash (&obj_a->ip6_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID));
return _HASH_NON_ZERO (h);
}
return 1;
@@ -1024,12 +1019,14 @@ _vt_cmd_plobj_id_copy (ip4_route, NMPlatformIP4Route, {
dst->plen = src->plen;
dst->metric = src->metric;
dst->network = src->network;
+ nm_assert (nm_platform_ip4_route_cmp (dst, src, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID_CACHE) == 0);
});
_vt_cmd_plobj_id_copy (ip6_route, NMPlatformIP6Route, {
dst->ifindex = src->ifindex;
dst->plen = src->plen;
dst->metric = src->metric;
dst->network = src->network;
+ nm_assert (nm_platform_ip6_route_cmp (dst, src, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID_CACHE) == 0);
});
/* Uses internally nmp_object_copy(), hence it also violates the const
@@ -1091,20 +1088,9 @@ _vt_cmd_plobj_id_equal (ip6_address, NMPlatformIP6Address,
/* for IPv6 addresses, the prefix length is not part of the primary identifier. */
&& IN6_ARE_ADDR_EQUAL (&obj1->address, &obj2->address));
_vt_cmd_plobj_id_equal (ip4_route, NMPlatformIP4Route,
- obj1->ifindex == obj2->ifindex
- && obj1->plen == obj2->plen
- && obj1->metric == obj2->metric
- && nm_utils_ip4_address_clear_host_address (obj1->network, obj1->plen) == nm_utils_ip4_address_clear_host_address (obj2->network, obj2->plen));
+ nm_platform_ip4_route_cmp (obj1, obj2, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID_CACHE) == 0);
_vt_cmd_plobj_id_equal (ip6_route, NMPlatformIP6Route,
- obj1->ifindex == obj2->ifindex
- && obj1->plen == obj2->plen
- && obj1->metric == obj2->metric
- && ({
- struct in6_addr n1, n2;
-
- IN6_ARE_ADDR_EQUAL(nm_utils_ip6_address_clear_host_address (&n1, &obj1->network, obj1->plen),
- nm_utils_ip6_address_clear_host_address (&n2, &obj2->network, obj2->plen));
- }));
+ nm_platform_ip6_route_cmp (obj1, obj2, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID_CACHE) == 0);
guint
nmp_object_id_hash (const NMPObject *obj)
@@ -1153,22 +1139,10 @@ _vt_cmd_plobj_id_hash (ip6_address, NMPlatformIP6Address, {
hash = NM_HASH_COMBINE (hash, nm_utils_in6_addr_hash (&obj->address));
})
_vt_cmd_plobj_id_hash (ip4_route, NMPlatformIP4Route, {
- hash = (guint) 2569857221u;
- hash = hash + ((guint) obj->ifindex);
- hash = NM_HASH_COMBINE (hash, obj->plen);
- hash = NM_HASH_COMBINE (hash, obj->metric);
- hash = NM_HASH_COMBINE (hash, nm_utils_ip4_address_clear_host_address (obj->network, obj->plen));
+ hash = nm_platform_ip4_route_hash (obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID_CACHE);
})
_vt_cmd_plobj_id_hash (ip6_route, NMPlatformIP6Route, {
- hash = (guint) 3999787007u;
- hash = hash + ((guint) obj->ifindex);
- hash = NM_HASH_COMBINE (hash, obj->plen);
- hash = NM_HASH_COMBINE (hash, obj->metric);
- hash = NM_HASH_COMBINE (hash,
- ({
- struct in6_addr n1;
- nm_utils_in6_addr_hash (nm_utils_ip6_address_clear_host_address (&n1, &obj->network, obj->plen));
- }));
+ hash = nm_platform_ip6_route_hash (obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID_CACHE);
})
gboolean
@@ -2428,8 +2402,8 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
.cmd_plobj_id_hash = _vt_cmd_plobj_id_hash_ip4_route,
.cmd_plobj_to_string_id = _vt_cmd_plobj_to_string_id_ip4_route,
.cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_ip4_route_to_string,
- .cmd_plobj_hash = (guint (*) (const NMPlatformObject *obj)) nm_platform_ip4_route_hash,
- .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_ip4_route_cmp,
+ .cmd_plobj_hash = (guint (*) (const NMPlatformObject *obj)) nm_platform_ip4_route_hash_full,
+ .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_ip4_route_cmp_full,
},
[NMP_OBJECT_TYPE_IP6_ROUTE - 1] = {
.parent = DEDUP_MULTI_OBJ_CLASS_INIT(),
@@ -2449,8 +2423,8 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
.cmd_plobj_id_hash = _vt_cmd_plobj_id_hash_ip6_route,
.cmd_plobj_to_string_id = _vt_cmd_plobj_to_string_id_ip6_route,
.cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_ip6_route_to_string,
- .cmd_plobj_hash = (guint (*) (const NMPlatformObject *obj)) nm_platform_ip6_route_hash,
- .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_ip6_route_cmp,
+ .cmd_plobj_hash = (guint (*) (const NMPlatformObject *obj)) nm_platform_ip6_route_hash_full,
+ .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_ip6_route_cmp_full,
},
[NMP_OBJECT_TYPE_LNK_GRE - 1] = {
.parent = DEDUP_MULTI_OBJ_CLASS_INIT(),
diff --git a/src/platform/tests/test-route.c b/src/platform/tests/test-route.c
index adaf7e538a..ac3aa80b8b 100644
--- a/src/platform/tests/test-route.c
+++ b/src/platform/tests/test-route.c
@@ -69,6 +69,8 @@ ip4_route_callback (NMPlatform *platform, int obj_type_i, int ifindex, const NMP
{
const NMPObjectType obj_type = obj_type_i;
const NMPlatformSignalChangeType change_type = change_type_i;
+ NMPObject o_id;
+ nm_auto_nmpobj NMPObject *o_id_p = nmp_object_new (NMP_OBJECT_TYPE_IP4_ROUTE, NULL);
g_assert_cmpint (obj_type, ==, NMP_OBJECT_TYPE_IP4_ROUTE);
g_assert (received);
@@ -76,6 +78,11 @@ ip4_route_callback (NMPlatform *platform, int obj_type_i, int ifindex, const NMP
g_assert (data && data->name);
g_assert_cmpstr (data->name, ==, NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED);
+ /* run code for initializing the ID only */
+ nmp_object_stackinit_id (&o_id, NMP_OBJECT_UP_CAST (received));
+ nmp_object_copy (o_id_p, NMP_OBJECT_UP_CAST (received), TRUE);
+ nmp_object_copy (o_id_p, NMP_OBJECT_UP_CAST (received), FALSE);
+
if (data->ifindex && data->ifindex != received->ifindex)
return;
if (data->change_type != change_type)
@@ -93,6 +100,8 @@ ip6_route_callback (NMPlatform *platform, int obj_type_i, int ifindex, const NMP
{
const NMPObjectType obj_type = obj_type_i;
const NMPlatformSignalChangeType change_type = change_type_i;
+ NMPObject o_id;
+ nm_auto_nmpobj NMPObject *o_id_p = nmp_object_new (NMP_OBJECT_TYPE_IP6_ROUTE, NULL);
g_assert_cmpint (obj_type, ==, NMP_OBJECT_TYPE_IP6_ROUTE);
g_assert (received);
@@ -100,6 +109,11 @@ ip6_route_callback (NMPlatform *platform, int obj_type_i, int ifindex, const NMP
g_assert (data && data->name);
g_assert_cmpstr (data->name, ==, NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED);
+ /* run code for initializing the ID only */
+ nmp_object_stackinit_id (&o_id, NMP_OBJECT_UP_CAST (received));
+ nmp_object_copy (o_id_p, NMP_OBJECT_UP_CAST (received), TRUE);
+ nmp_object_copy (o_id_p, NMP_OBJECT_UP_CAST (received), FALSE);
+
if (data->ifindex && data->ifindex != received->ifindex)
return;
if (data->change_type != change_type)
diff --git a/src/tests/test-route-manager.c b/src/tests/test-route-manager.c
index cf771f80ea..e6b72ac87e 100644
--- a/src/tests/test-route-manager.c
+++ b/src/tests/test-route-manager.c
@@ -822,7 +822,7 @@ _assert_route_check (const NMPlatformVTableRoute *vtable, gboolean has, const NM
c.r6 = route->r6;
c.rx.rt_source = nmp_utils_ip_config_source_round_trip_rtprot (c.rx.rt_source);
}
- if (!r || vtable->route_cmp (r, &c, TRUE) != 0) {
+ if (!r || vtable->route_cmp (r, &c, NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL) != 0) {
g_error ("Invalid route. Expect %s, has %s",
vtable->route_to_string (&c, NULL, 0),
vtable->route_to_string (r, buf, sizeof (buf)));