Commit 372f14a6 authored by Thomas Haller's avatar Thomas Haller

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.
parent 54f8c2ac
......@@ -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);
/**
......
......@@ -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;
}
}
......
......@@ -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
......
......@@ -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
......
......@@ -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 *
......
......@@ -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,
......
This diff is collapsed.
......@@ -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);
......
......@@ -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(),
......
......@@ -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)
......
......@@ -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)));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment