diff options
author | Thomas Haller <thaller@redhat.com> | 2017-07-26 10:50:23 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2017-08-03 18:32:59 +0200 |
commit | 372f14a6ef724c407c7e1ff1f52d8777c16bd33e (patch) | |
tree | 97bb64071c202dceac6d8b4dfeb1ee6838c6b669 | |
parent | 54f8c2ac22b0df9d7316744808163e95f573dfbd (diff) | |
download | NetworkManager-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.h | 26 | ||||
-rw-r--r-- | src/nm-default-route-manager.c | 4 | ||||
-rw-r--r-- | src/nm-ip4-config.c | 6 | ||||
-rw-r--r-- | src/nm-ip6-config.c | 2 | ||||
-rw-r--r-- | src/nm-route-manager.c | 2 | ||||
-rw-r--r-- | src/nm-test-utils-core.h | 8 | ||||
-rw-r--r-- | src/platform/nm-platform.c | 297 | ||||
-rw-r--r-- | src/platform/nm-platform.h | 73 | ||||
-rw-r--r-- | src/platform/nmp-object.c | 54 | ||||
-rw-r--r-- | src/platform/tests/test-route.c | 14 | ||||
-rw-r--r-- | src/tests/test-route-manager.c | 2 |
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))); |