diff options
| author | Michael Biebl <biebl@debian.org> | 2020-10-05 22:27:18 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2020-10-05 22:27:18 +0200 |
| commit | aafc1dbe4712c86189bbc1d4d54ad8cb4c69be7e (patch) | |
| tree | a2a9bb4d007339a0b1304540388230ccedac32bd /src/platform/nmp-object.c | |
| parent | e7b44ef4c80907346ec7492a09c45277459924fc (diff) | |
New upstream version 1.27.90 upstream/1.27.90
Diffstat (limited to 'src/platform/nmp-object.c')
| -rw-r--r-- | src/platform/nmp-object.c | 5283 |
1 files changed, 2681 insertions, 2602 deletions
diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c index a6aa5e22..6eea732f 100644 --- a/src/platform/nmp-object.c +++ b/src/platform/nmp-object.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2015 - 2018 Red Hat, Inc. */ @@ -24,109 +24,112 @@ /*****************************************************************************/ #define _NMLOG_DOMAIN LOGD_PLATFORM -#define _NMLOG(level, obj, ...) \ - G_STMT_START { \ - const NMLogLevel __level = (level); \ - \ - if (nm_logging_enabled (__level, _NMLOG_DOMAIN)) { \ - const NMPObject *const __obj = (obj); \ - \ - _nm_log (__level, _NMLOG_DOMAIN, 0, NULL, NULL, \ - "nmp-object[%p/%s]: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ - __obj, \ - (__obj ? NMP_OBJECT_GET_CLASS (__obj)->obj_type_name : "???") \ - _NM_UTILS_MACRO_REST (__VA_ARGS__)); \ - } \ - } G_STMT_END +#define _NMLOG(level, obj, ...) \ + G_STMT_START \ + { \ + const NMLogLevel __level = (level); \ + \ + if (nm_logging_enabled(__level, _NMLOG_DOMAIN)) { \ + const NMPObject *const __obj = (obj); \ + \ + _nm_log(__level, \ + _NMLOG_DOMAIN, \ + 0, \ + NULL, \ + NULL, \ + "nmp-object[%p/%s]: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + __obj, \ + (__obj ? NMP_OBJECT_GET_CLASS(__obj)->obj_type_name \ + : "???") _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } \ + G_STMT_END /*****************************************************************************/ typedef struct { - NMDedupMultiIdxType parent; - NMPCacheIdType cache_id_type; + NMDedupMultiIdxType parent; + NMPCacheIdType cache_id_type; } DedupMultiIdxType; struct _NMPCache { - /* the cache contains only one hash table for all object types, and similarly - * it contains only one NMMultiIndex. - * This works, because different object types don't ever compare equal and - * because their index ids also don't overlap. - * - * For routes and addresses, the cache contains an address if (and only if) the - * object was reported via netlink. - * For links, the cache contain a link if it was reported by either netlink - * or udev. That means, a link object can be alive, even if it was already - * removed via netlink. - * - * This effectively merges the udev-device cache into the NMPCache. - */ - - NMDedupMultiIndex *multi_idx; - - /* an idx_type entry for each NMP_CACHE_ID_TYPE. Note that NONE (zero) - * is skipped, so the index is shifted by one: idx_type[cache_id_type - 1]. - * - * Don't bother, use _idx_type_get() instead! */ - DedupMultiIdxType idx_types[NMP_CACHE_ID_TYPE_MAX]; - - gboolean use_udev; + /* the cache contains only one hash table for all object types, and similarly + * it contains only one NMMultiIndex. + * This works, because different object types don't ever compare equal and + * because their index ids also don't overlap. + * + * For routes and addresses, the cache contains an address if (and only if) the + * object was reported via netlink. + * For links, the cache contain a link if it was reported by either netlink + * or udev. That means, a link object can be alive, even if it was already + * removed via netlink. + * + * This effectively merges the udev-device cache into the NMPCache. + */ + + NMDedupMultiIndex *multi_idx; + + /* an idx_type entry for each NMP_CACHE_ID_TYPE. Note that NONE (zero) + * is skipped, so the index is shifted by one: idx_type[cache_id_type - 1]. + * + * Don't bother, use _idx_type_get() instead! */ + DedupMultiIdxType idx_types[NMP_CACHE_ID_TYPE_MAX]; + + gboolean use_udev; }; /*****************************************************************************/ int -nm_sock_addr_union_cmp (const NMSockAddrUnion *a, const NMSockAddrUnion *b) +nm_sock_addr_union_cmp(const NMSockAddrUnion *a, const NMSockAddrUnion *b) { - nm_assert (!a || NM_IN_SET (a->sa.sa_family, AF_UNSPEC, AF_INET, AF_INET6)); - nm_assert (!b || NM_IN_SET (b->sa.sa_family, AF_UNSPEC, AF_INET, AF_INET6)); + nm_assert(!a || NM_IN_SET(a->sa.sa_family, AF_UNSPEC, AF_INET, AF_INET6)); + nm_assert(!b || NM_IN_SET(b->sa.sa_family, AF_UNSPEC, AF_INET, AF_INET6)); - NM_CMP_SELF (a, b); + NM_CMP_SELF(a, b); - NM_CMP_FIELD (a, b, sa.sa_family); - switch (a->sa.sa_family) { - case AF_INET: - NM_CMP_DIRECT (ntohl (a->in.sin_addr.s_addr), ntohl (b->in.sin_addr.s_addr)); - NM_CMP_DIRECT (htons (a->in.sin_port), htons (b->in.sin_port)); - break; - case AF_INET6: - NM_CMP_DIRECT_IN6ADDR (&a->in6.sin6_addr, &b->in6.sin6_addr); - NM_CMP_DIRECT (htons (a->in6.sin6_port), htons (b->in6.sin6_port)); - NM_CMP_FIELD (a, b, in6.sin6_scope_id); - NM_CMP_FIELD (a, b, in6.sin6_flowinfo); - break; - } - return 0; + NM_CMP_FIELD(a, b, sa.sa_family); + switch (a->sa.sa_family) { + case AF_INET: + NM_CMP_DIRECT(ntohl(a->in.sin_addr.s_addr), ntohl(b->in.sin_addr.s_addr)); + NM_CMP_DIRECT(htons(a->in.sin_port), htons(b->in.sin_port)); + break; + case AF_INET6: + NM_CMP_DIRECT_IN6ADDR(&a->in6.sin6_addr, &b->in6.sin6_addr); + NM_CMP_DIRECT(htons(a->in6.sin6_port), htons(b->in6.sin6_port)); + NM_CMP_FIELD(a, b, in6.sin6_scope_id); + NM_CMP_FIELD(a, b, in6.sin6_flowinfo); + break; + } + return 0; } void -nm_sock_addr_union_hash_update (const NMSockAddrUnion *a, NMHashState *h) -{ - if (!a) { - nm_hash_update_val (h, 1241364739u); - return; - } - - nm_assert (NM_IN_SET (a->sa.sa_family, AF_UNSPEC, AF_INET, AF_INET6)); - - switch (a->sa.sa_family) { - case AF_INET: - nm_hash_update_vals (h, - a->in.sin_family, - a->in.sin_addr.s_addr, - a->in.sin_port); - return; - case AF_INET6: - nm_hash_update_vals (h, - a->in6.sin6_family, - a->in6.sin6_addr, - a->in6.sin6_port, - a->in6.sin6_scope_id, - a->in6.sin6_flowinfo); - return; - default: - nm_hash_update_val (h, a->sa.sa_family); - return; - } +nm_sock_addr_union_hash_update(const NMSockAddrUnion *a, NMHashState *h) +{ + if (!a) { + nm_hash_update_val(h, 1241364739u); + return; + } + + nm_assert(NM_IN_SET(a->sa.sa_family, AF_UNSPEC, AF_INET, AF_INET6)); + + switch (a->sa.sa_family) { + case AF_INET: + nm_hash_update_vals(h, a->in.sin_family, a->in.sin_addr.s_addr, a->in.sin_port); + return; + case AF_INET6: + nm_hash_update_vals(h, + a->in6.sin6_family, + a->in6.sin6_addr, + a->in6.sin6_port, + a->in6.sin6_scope_id, + a->in6.sin6_flowinfo); + return; + default: + nm_hash_update_val(h, a->sa.sa_family); + return; + } } /** @@ -142,30 +145,30 @@ nm_sock_addr_union_hash_update (const NMSockAddrUnion *a, NMHashState *h) * @dst will always be fully initialized (including setting all un-used bytes to zero). */ void -nm_sock_addr_union_cpy (NMSockAddrUnion *dst, - gconstpointer src /* unaligned (const NMSockAddrUnion *) */) +nm_sock_addr_union_cpy(NMSockAddrUnion *dst, + gconstpointer src /* unaligned (const NMSockAddrUnion *) */) { - struct sockaddr sa; - gsize src_len; + struct sockaddr sa; + gsize src_len; - nm_assert (dst); + nm_assert(dst); - *dst = (NMSockAddrUnion) NM_SOCK_ADDR_UNION_INIT_UNSPEC; + *dst = (NMSockAddrUnion) NM_SOCK_ADDR_UNION_INIT_UNSPEC; - if (!src) - return; + if (!src) + return; - memcpy (&sa.sa_family, &((struct sockaddr *) src)->sa_family, sizeof (sa.sa_family)); + memcpy(&sa.sa_family, &((struct sockaddr *) src)->sa_family, sizeof(sa.sa_family)); - if (sa.sa_family == AF_INET) - src_len = sizeof (struct sockaddr_in); - else if (sa.sa_family == AF_INET6) - src_len = sizeof (struct sockaddr_in6); - else - return; + if (sa.sa_family == AF_INET) + src_len = sizeof(struct sockaddr_in); + else if (sa.sa_family == AF_INET6) + src_len = sizeof(struct sockaddr_in6); + else + return; - memcpy (dst, src, src_len); - nm_assert (dst->sa.sa_family == sa.sa_family); + memcpy(dst, src, src_len); + nm_assert(dst->sa.sa_family == sa.sa_family); } /** @@ -186,76 +189,74 @@ nm_sock_addr_union_cpy (NMSockAddrUnion *dst, * @dst will always be fully initialized (including setting all un-used bytes to zero). */ void -nm_sock_addr_union_cpy_untrusted (NMSockAddrUnion *dst, - gconstpointer src /* unaligned (const NMSockAddrUnion *) */, - gsize src_len) +nm_sock_addr_union_cpy_untrusted(NMSockAddrUnion *dst, + gconstpointer src /* unaligned (const NMSockAddrUnion *) */, + gsize src_len) { - int f_expected; - struct sockaddr sa; + int f_expected; + struct sockaddr sa; - nm_assert (dst); + nm_assert(dst); - *dst = (NMSockAddrUnion) NM_SOCK_ADDR_UNION_INIT_UNSPEC; + *dst = (NMSockAddrUnion) NM_SOCK_ADDR_UNION_INIT_UNSPEC; - if (src_len == sizeof (struct sockaddr_in)) - f_expected = AF_INET; - else if (src_len == sizeof (struct sockaddr_in6)) - f_expected = AF_INET6; - else - return; + if (src_len == sizeof(struct sockaddr_in)) + f_expected = AF_INET; + else if (src_len == sizeof(struct sockaddr_in6)) + f_expected = AF_INET6; + else + return; - memcpy (&sa.sa_family, &((struct sockaddr *) src)->sa_family, sizeof (sa.sa_family)); + memcpy(&sa.sa_family, &((struct sockaddr *) src)->sa_family, sizeof(sa.sa_family)); - if (sa.sa_family != f_expected) - return; + if (sa.sa_family != f_expected) + return; - memcpy (dst, src, src_len); - nm_assert (dst->sa.sa_family == sa.sa_family); + memcpy(dst, src, src_len); + nm_assert(dst->sa.sa_family == sa.sa_family); } const char * -nm_sock_addr_union_to_string (const NMSockAddrUnion *sa, - char *buf, - gsize len) -{ - char s_addr[NM_UTILS_INET_ADDRSTRLEN]; - char s_scope_id[40]; - - if (!nm_utils_to_string_buffer_init_null (sa, &buf, &len)) - return buf; - - /* maybe we should use getnameinfo(), but here implement it ourself. - * - * We want to see the actual bytes for debugging (as we understand them), - * and now what getnameinfo() makes of it. Also, it's simpler this way. */ - - switch (sa->sa.sa_family) { - case AF_INET: - g_snprintf (buf, len, - "%s:%u", - _nm_utils_inet4_ntop (sa->in.sin_addr.s_addr, s_addr), - (guint) htons (sa->in.sin_port)); - break; - case AF_INET6: - g_snprintf (buf, len, - "[%s%s]:%u", - _nm_utils_inet6_ntop (&sa->in6.sin6_addr, s_addr), - ( sa->in6.sin6_scope_id != 0 - ? nm_sprintf_buf (s_scope_id, "%u", sa->in6.sin6_scope_id) - : ""), - (guint) htons (sa->in6.sin6_port)); - break; - case AF_UNSPEC: - g_snprintf (buf, len, "unspec"); - break; - default: - g_snprintf (buf, len, - "{addr-family:%u}", - (unsigned) sa->sa.sa_family); - break; - } - - return buf; +nm_sock_addr_union_to_string(const NMSockAddrUnion *sa, char *buf, gsize len) +{ + char s_addr[NM_UTILS_INET_ADDRSTRLEN]; + char s_scope_id[40]; + + if (!nm_utils_to_string_buffer_init_null(sa, &buf, &len)) + return buf; + + /* maybe we should use getnameinfo(), but here implement it ourself. + * + * We want to see the actual bytes for debugging (as we understand them), + * and now what getnameinfo() makes of it. Also, it's simpler this way. */ + + switch (sa->sa.sa_family) { + case AF_INET: + g_snprintf(buf, + len, + "%s:%u", + _nm_utils_inet4_ntop(sa->in.sin_addr.s_addr, s_addr), + (guint) htons(sa->in.sin_port)); + break; + case AF_INET6: + g_snprintf(buf, + len, + "[%s%s]:%u", + _nm_utils_inet6_ntop(&sa->in6.sin6_addr, s_addr), + (sa->in6.sin6_scope_id != 0 + ? nm_sprintf_buf(s_scope_id, "%u", sa->in6.sin6_scope_id) + : ""), + (guint) htons(sa->in6.sin6_port)); + break; + case AF_UNSPEC: + g_snprintf(buf, len, "unspec"); + break; + default: + g_snprintf(buf, len, "{addr-family:%u}", (unsigned) sa->sa.sa_family); + break; + } + + return buf; } /*****************************************************************************/ @@ -263,974 +264,1014 @@ nm_sock_addr_union_to_string (const NMSockAddrUnion *sa, static const NMDedupMultiIdxTypeClass _dedup_multi_idx_type_class; static void -_idx_obj_id_hash_update (const NMDedupMultiIdxType *idx_type, - const NMDedupMultiObj *obj, - NMHashState *h) +_idx_obj_id_hash_update(const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj * obj, + NMHashState * h) { - const NMPObject *o = (NMPObject *) obj; + const NMPObject *o = (NMPObject *) obj; - nm_assert (idx_type && idx_type->klass == &_dedup_multi_idx_type_class); - nm_assert (NMP_OBJECT_GET_TYPE (o) != NMP_OBJECT_TYPE_UNKNOWN); + nm_assert(idx_type && idx_type->klass == &_dedup_multi_idx_type_class); + nm_assert(NMP_OBJECT_GET_TYPE(o) != NMP_OBJECT_TYPE_UNKNOWN); - nmp_object_id_hash_update (o, h); + nmp_object_id_hash_update(o, h); } static gboolean -_idx_obj_id_equal (const NMDedupMultiIdxType *idx_type, - const NMDedupMultiObj *obj_a, - const NMDedupMultiObj *obj_b) +_idx_obj_id_equal(const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj * obj_a, + const NMDedupMultiObj * obj_b) { - const NMPObject *o_a = (NMPObject *) obj_a; - const NMPObject *o_b = (NMPObject *) obj_b; + const NMPObject *o_a = (NMPObject *) obj_a; + const NMPObject *o_b = (NMPObject *) obj_b; - nm_assert (idx_type && idx_type->klass == &_dedup_multi_idx_type_class); - nm_assert (NMP_OBJECT_GET_TYPE (o_a) != NMP_OBJECT_TYPE_UNKNOWN); - nm_assert (NMP_OBJECT_GET_TYPE (o_b) != NMP_OBJECT_TYPE_UNKNOWN); + nm_assert(idx_type && idx_type->klass == &_dedup_multi_idx_type_class); + nm_assert(NMP_OBJECT_GET_TYPE(o_a) != NMP_OBJECT_TYPE_UNKNOWN); + nm_assert(NMP_OBJECT_GET_TYPE(o_b) != NMP_OBJECT_TYPE_UNKNOWN); - return nmp_object_id_equal (o_a, o_b); + return nmp_object_id_equal(o_a, o_b); } static guint -_idx_obj_part (const DedupMultiIdxType *idx_type, - const NMPObject *obj_a, - const NMPObject *obj_b, - NMHashState *h) -{ - NMPObjectType obj_type; - - /* the hash/equals functions are strongly related. So, keep them - * side-by-side and do it all in _idx_obj_part(). */ - - nm_assert (idx_type); - nm_assert (idx_type->parent.klass == &_dedup_multi_idx_type_class); - nm_assert (obj_a); - nm_assert (NMP_OBJECT_GET_TYPE (obj_a) != NMP_OBJECT_TYPE_UNKNOWN); - nm_assert (!obj_b || (NMP_OBJECT_GET_TYPE (obj_b) != NMP_OBJECT_TYPE_UNKNOWN)); - nm_assert (!h || !obj_b); - - switch (idx_type->cache_id_type) { - - case NMP_CACHE_ID_TYPE_OBJECT_TYPE: - if (obj_b) - return NMP_OBJECT_GET_TYPE (obj_a) == NMP_OBJECT_GET_TYPE (obj_b); - if (h) { - nm_hash_update_vals (h, - idx_type->cache_id_type, - NMP_OBJECT_GET_TYPE (obj_a)); - } - return 1; - - case NMP_CACHE_ID_TYPE_LINK_BY_IFNAME: - if (NMP_OBJECT_GET_TYPE (obj_a) != NMP_OBJECT_TYPE_LINK) { - /* first check, whether obj_a is suitable for this idx_type. - * If not, return 0 (which is correct for partitionable(), hash() and equal() - * functions. */ - if (h) - nm_hash_update_val (h, obj_a); - return 0; - } - if (obj_b) { - /* we are in equal() mode. Compare obj_b with obj_a. */ - return NMP_OBJECT_GET_TYPE (obj_b) == NMP_OBJECT_TYPE_LINK - && nm_streq (obj_a->link.name, obj_b->link.name); - } - if (h) { - nm_hash_update_val (h, idx_type->cache_id_type); - nm_hash_update_strarr (h, obj_a->link.name); - } - /* just return 1, to indicate that obj_a is partitionable by this idx_type. */ - return 1; - - case NMP_CACHE_ID_TYPE_DEFAULT_ROUTES: - if ( !NM_IN_SET (NMP_OBJECT_GET_TYPE (obj_a), NMP_OBJECT_TYPE_IP4_ROUTE, - NMP_OBJECT_TYPE_IP6_ROUTE) - || !NM_PLATFORM_IP_ROUTE_IS_DEFAULT (&obj_a->ip_route) - || !nmp_object_is_visible (obj_a)) { - if (h) - nm_hash_update_val (h, obj_a); - return 0; - } - if (obj_b) { - return NMP_OBJECT_GET_TYPE (obj_a) == NMP_OBJECT_GET_TYPE (obj_b) - && NM_PLATFORM_IP_ROUTE_IS_DEFAULT (&obj_b->ip_route) - && nmp_object_is_visible (obj_b); - } - if (h) { - nm_hash_update_vals (h, - idx_type->cache_id_type, - NMP_OBJECT_GET_TYPE (obj_a)); - } - return 1; - - case NMP_CACHE_ID_TYPE_OBJECT_BY_IFINDEX: - if ( !NM_IN_SET (NMP_OBJECT_GET_TYPE (obj_a), NMP_OBJECT_TYPE_IP4_ADDRESS, - NMP_OBJECT_TYPE_IP6_ADDRESS, - NMP_OBJECT_TYPE_IP4_ROUTE, - NMP_OBJECT_TYPE_IP6_ROUTE, - NMP_OBJECT_TYPE_QDISC, - NMP_OBJECT_TYPE_TFILTER) - || !nmp_object_is_visible (obj_a)) { - if (h) - nm_hash_update_val (h, obj_a); - return 0; - } - nm_assert (NMP_OBJECT_CAST_OBJ_WITH_IFINDEX (obj_a)->ifindex > 0); - if (obj_b) { - return NMP_OBJECT_GET_TYPE (obj_a) == NMP_OBJECT_GET_TYPE (obj_b) - && NMP_OBJECT_CAST_OBJ_WITH_IFINDEX (obj_a)->ifindex == NMP_OBJECT_CAST_OBJ_WITH_IFINDEX (obj_b)->ifindex - && nmp_object_is_visible (obj_b); - } - if (h) { - nm_hash_update_vals (h, - idx_type->cache_id_type, - obj_a->obj_with_ifindex.ifindex); - } - return 1; - - case NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID: - obj_type = NMP_OBJECT_GET_TYPE (obj_a); - if ( !NM_IN_SET (obj_type, NMP_OBJECT_TYPE_IP4_ROUTE, - NMP_OBJECT_TYPE_IP6_ROUTE) - || NMP_OBJECT_CAST_IP_ROUTE (obj_a)->ifindex <= 0) { - if (h) - nm_hash_update_val (h, obj_a); - return 0; - } - if (obj_b) { - return obj_type == NMP_OBJECT_GET_TYPE (obj_b) - && NMP_OBJECT_CAST_IP_ROUTE (obj_b)->ifindex > 0 - && (obj_type == NMP_OBJECT_TYPE_IP4_ROUTE - ? (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 (h) { - nm_hash_update_val (h, idx_type->cache_id_type); - if (obj_type == NMP_OBJECT_TYPE_IP4_ROUTE) - nm_platform_ip4_route_hash_update (&obj_a->ip4_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID, h); - else - nm_platform_ip6_route_hash_update (&obj_a->ip6_route, NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID, h); - } - return 1; - - case NMP_CACHE_ID_TYPE_OBJECT_BY_ADDR_FAMILY: - obj_type = NMP_OBJECT_GET_TYPE (obj_a); - /* currently, only routing rules are supported for this cache-id-type. */ - if ( obj_type != NMP_OBJECT_TYPE_ROUTING_RULE - || !NM_IN_SET (obj_a->routing_rule.addr_family, AF_INET, AF_INET6)) { - if (h) - nm_hash_update_val (h, obj_a); - return 0; - } - if (obj_b) { - return NMP_OBJECT_GET_TYPE (obj_b) == NMP_OBJECT_TYPE_ROUTING_RULE - && obj_a->routing_rule.addr_family == obj_b->routing_rule.addr_family; - } - if (h) { - nm_hash_update_vals (h, idx_type->cache_id_type, - obj_a->routing_rule.addr_family); - } - return 1; - - case NMP_CACHE_ID_TYPE_NONE: - case __NMP_CACHE_ID_TYPE_MAX: - break; - } - nm_assert_not_reached (); - return 0; +_idx_obj_part(const DedupMultiIdxType *idx_type, + const NMPObject * obj_a, + const NMPObject * obj_b, + NMHashState * h) +{ + NMPObjectType obj_type; + + /* the hash/equals functions are strongly related. So, keep them + * side-by-side and do it all in _idx_obj_part(). */ + + nm_assert(idx_type); + nm_assert(idx_type->parent.klass == &_dedup_multi_idx_type_class); + nm_assert(obj_a); + nm_assert(NMP_OBJECT_GET_TYPE(obj_a) != NMP_OBJECT_TYPE_UNKNOWN); + nm_assert(!obj_b || (NMP_OBJECT_GET_TYPE(obj_b) != NMP_OBJECT_TYPE_UNKNOWN)); + nm_assert(!h || !obj_b); + + switch (idx_type->cache_id_type) { + case NMP_CACHE_ID_TYPE_OBJECT_TYPE: + if (obj_b) + return NMP_OBJECT_GET_TYPE(obj_a) == NMP_OBJECT_GET_TYPE(obj_b); + if (h) { + nm_hash_update_vals(h, idx_type->cache_id_type, NMP_OBJECT_GET_TYPE(obj_a)); + } + return 1; + + case NMP_CACHE_ID_TYPE_LINK_BY_IFNAME: + if (NMP_OBJECT_GET_TYPE(obj_a) != NMP_OBJECT_TYPE_LINK) { + /* first check, whether obj_a is suitable for this idx_type. + * If not, return 0 (which is correct for partitionable(), hash() and equal() + * functions. */ + if (h) + nm_hash_update_val(h, obj_a); + return 0; + } + if (obj_b) { + /* we are in equal() mode. Compare obj_b with obj_a. */ + return NMP_OBJECT_GET_TYPE(obj_b) == NMP_OBJECT_TYPE_LINK + && nm_streq(obj_a->link.name, obj_b->link.name); + } + if (h) { + nm_hash_update_val(h, idx_type->cache_id_type); + nm_hash_update_strarr(h, obj_a->link.name); + } + /* just return 1, to indicate that obj_a is partitionable by this idx_type. */ + return 1; + + case NMP_CACHE_ID_TYPE_DEFAULT_ROUTES: + if (!NM_IN_SET(NMP_OBJECT_GET_TYPE(obj_a), + NMP_OBJECT_TYPE_IP4_ROUTE, + NMP_OBJECT_TYPE_IP6_ROUTE) + || !NM_PLATFORM_IP_ROUTE_IS_DEFAULT(&obj_a->ip_route) + || !nmp_object_is_visible(obj_a)) { + if (h) + nm_hash_update_val(h, obj_a); + return 0; + } + if (obj_b) { + return NMP_OBJECT_GET_TYPE(obj_a) == NMP_OBJECT_GET_TYPE(obj_b) + && NM_PLATFORM_IP_ROUTE_IS_DEFAULT(&obj_b->ip_route) + && nmp_object_is_visible(obj_b); + } + if (h) { + nm_hash_update_vals(h, idx_type->cache_id_type, NMP_OBJECT_GET_TYPE(obj_a)); + } + return 1; + + case NMP_CACHE_ID_TYPE_OBJECT_BY_IFINDEX: + if (!NM_IN_SET(NMP_OBJECT_GET_TYPE(obj_a), + NMP_OBJECT_TYPE_IP4_ADDRESS, + NMP_OBJECT_TYPE_IP6_ADDRESS, + NMP_OBJECT_TYPE_IP4_ROUTE, + NMP_OBJECT_TYPE_IP6_ROUTE, + NMP_OBJECT_TYPE_QDISC, + NMP_OBJECT_TYPE_TFILTER) + || !nmp_object_is_visible(obj_a)) { + if (h) + nm_hash_update_val(h, obj_a); + return 0; + } + nm_assert(NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(obj_a)->ifindex > 0); + if (obj_b) { + return NMP_OBJECT_GET_TYPE(obj_a) == NMP_OBJECT_GET_TYPE(obj_b) + && NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(obj_a)->ifindex + == NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(obj_b)->ifindex + && nmp_object_is_visible(obj_b); + } + if (h) { + nm_hash_update_vals(h, idx_type->cache_id_type, obj_a->obj_with_ifindex.ifindex); + } + return 1; + + case NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID: + obj_type = NMP_OBJECT_GET_TYPE(obj_a); + if (!NM_IN_SET(obj_type, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE) + || NMP_OBJECT_CAST_IP_ROUTE(obj_a)->ifindex <= 0) { + if (h) + nm_hash_update_val(h, obj_a); + return 0; + } + if (obj_b) { + return obj_type == NMP_OBJECT_GET_TYPE(obj_b) + && NMP_OBJECT_CAST_IP_ROUTE(obj_b)->ifindex > 0 + && (obj_type == NMP_OBJECT_TYPE_IP4_ROUTE + ? (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 (h) { + nm_hash_update_val(h, idx_type->cache_id_type); + if (obj_type == NMP_OBJECT_TYPE_IP4_ROUTE) + nm_platform_ip4_route_hash_update(&obj_a->ip4_route, + NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID, + h); + else + nm_platform_ip6_route_hash_update(&obj_a->ip6_route, + NM_PLATFORM_IP_ROUTE_CMP_TYPE_WEAK_ID, + h); + } + return 1; + + case NMP_CACHE_ID_TYPE_OBJECT_BY_ADDR_FAMILY: + obj_type = NMP_OBJECT_GET_TYPE(obj_a); + /* currently, only routing rules are supported for this cache-id-type. */ + if (obj_type != NMP_OBJECT_TYPE_ROUTING_RULE + || !NM_IN_SET(obj_a->routing_rule.addr_family, AF_INET, AF_INET6)) { + if (h) + nm_hash_update_val(h, obj_a); + return 0; + } + if (obj_b) { + return NMP_OBJECT_GET_TYPE(obj_b) == NMP_OBJECT_TYPE_ROUTING_RULE + && obj_a->routing_rule.addr_family == obj_b->routing_rule.addr_family; + } + if (h) { + nm_hash_update_vals(h, idx_type->cache_id_type, obj_a->routing_rule.addr_family); + } + return 1; + + case NMP_CACHE_ID_TYPE_NONE: + case __NMP_CACHE_ID_TYPE_MAX: + break; + } + nm_assert_not_reached(); + return 0; } static gboolean -_idx_obj_partitionable (const NMDedupMultiIdxType *idx_type, - const NMDedupMultiObj *obj) +_idx_obj_partitionable(const NMDedupMultiIdxType *idx_type, const NMDedupMultiObj *obj) { - return _idx_obj_part ((DedupMultiIdxType *) idx_type, - (NMPObject *) obj, - NULL, - NULL) != 0; + return _idx_obj_part((DedupMultiIdxType *) idx_type, (NMPObject *) obj, NULL, NULL) != 0; } static void -_idx_obj_partition_hash_update (const NMDedupMultiIdxType *idx_type, - const NMDedupMultiObj *obj, - NMHashState *h) +_idx_obj_partition_hash_update(const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj * obj, + NMHashState * h) { - _idx_obj_part ((DedupMultiIdxType *) idx_type, - (NMPObject *) obj, - NULL, - h); + _idx_obj_part((DedupMultiIdxType *) idx_type, (NMPObject *) obj, NULL, h); } static gboolean -_idx_obj_partition_equal (const NMDedupMultiIdxType *idx_type, - const NMDedupMultiObj *obj_a, - const NMDedupMultiObj *obj_b) +_idx_obj_partition_equal(const NMDedupMultiIdxType *idx_type, + const NMDedupMultiObj * obj_a, + const NMDedupMultiObj * obj_b) { - return _idx_obj_part ((DedupMultiIdxType *) idx_type, - (NMPObject *) obj_a, - (NMPObject *) obj_b, - NULL); + return _idx_obj_part((DedupMultiIdxType *) idx_type, + (NMPObject *) obj_a, + (NMPObject *) obj_b, + NULL); } static const NMDedupMultiIdxTypeClass _dedup_multi_idx_type_class = { - .idx_obj_id_hash_update = _idx_obj_id_hash_update, - .idx_obj_id_equal = _idx_obj_id_equal, - .idx_obj_partitionable = _idx_obj_partitionable, - .idx_obj_partition_hash_update = _idx_obj_partition_hash_update, - .idx_obj_partition_equal = _idx_obj_partition_equal, + .idx_obj_id_hash_update = _idx_obj_id_hash_update, + .idx_obj_id_equal = _idx_obj_id_equal, + .idx_obj_partitionable = _idx_obj_partitionable, + .idx_obj_partition_hash_update = _idx_obj_partition_hash_update, + .idx_obj_partition_equal = _idx_obj_partition_equal, }; static void -_dedup_multi_idx_type_init (DedupMultiIdxType *idx_type, NMPCacheIdType cache_id_type) +_dedup_multi_idx_type_init(DedupMultiIdxType *idx_type, NMPCacheIdType cache_id_type) { - nm_dedup_multi_idx_type_init ((NMDedupMultiIdxType *) idx_type, - &_dedup_multi_idx_type_class); - idx_type->cache_id_type = cache_id_type; + nm_dedup_multi_idx_type_init((NMDedupMultiIdxType *) idx_type, &_dedup_multi_idx_type_class); + idx_type->cache_id_type = cache_id_type; } /*****************************************************************************/ static void -_vlan_xgress_qos_mappings_hash_update (guint n_map, - const NMVlanQosMapping *map, - NMHashState *h) +_vlan_xgress_qos_mappings_hash_update(guint n_map, const NMVlanQosMapping *map, NMHashState *h) { - /* ensure no padding. */ - G_STATIC_ASSERT (sizeof (NMVlanQosMapping) == 2 * sizeof (guint32)); + /* ensure no padding. */ + G_STATIC_ASSERT(sizeof(NMVlanQosMapping) == 2 * sizeof(guint32)); - nm_hash_update_val (h, n_map); - if (n_map) - nm_hash_update (h, map, n_map * sizeof (*map)); + nm_hash_update_val(h, n_map); + if (n_map) + nm_hash_update(h, map, n_map * sizeof(*map)); } static int -_vlan_xgress_qos_mappings_cmp (guint n_map, - const NMVlanQosMapping *map1, - const NMVlanQosMapping *map2) +_vlan_xgress_qos_mappings_cmp(guint n_map, + const NMVlanQosMapping *map1, + const NMVlanQosMapping *map2) { - guint i; + guint i; - for (i = 0; i < n_map; i++) { - if (map1[i].from != map2[i].from) - return map1[i].from < map2[i].from ? -1 : 1; - if (map1[i].to != map2[i].to) - return map1[i].to < map2[i].to ? -1 : 1; - } - return 0; + for (i = 0; i < n_map; i++) { + if (map1[i].from != map2[i].from) + return map1[i].from < map2[i].from ? -1 : 1; + if (map1[i].to != map2[i].to) + return map1[i].to < map2[i].to ? -1 : 1; + } + return 0; } static void -_vlan_xgress_qos_mappings_cpy (guint *dst_n_map, - NMVlanQosMapping **dst_map, - guint src_n_map, - const NMVlanQosMapping *src_map) -{ - if (src_n_map == 0) { - nm_clear_g_free (dst_map); - *dst_n_map = 0; - } else if ( src_n_map != *dst_n_map - || _vlan_xgress_qos_mappings_cmp (src_n_map, *dst_map, src_map) != 0) { - nm_clear_g_free (dst_map); - *dst_n_map = src_n_map; - if (src_n_map > 0) - *dst_map = nm_memdup (src_map, sizeof (*src_map) * src_n_map); - } +_vlan_xgress_qos_mappings_cpy(guint * dst_n_map, + NMVlanQosMapping ** dst_map, + guint src_n_map, + const NMVlanQosMapping *src_map) +{ + if (src_n_map == 0) { + nm_clear_g_free(dst_map); + *dst_n_map = 0; + } else if (src_n_map != *dst_n_map + || _vlan_xgress_qos_mappings_cmp(src_n_map, *dst_map, src_map) != 0) { + nm_clear_g_free(dst_map); + *dst_n_map = src_n_map; + if (src_n_map > 0) + *dst_map = nm_memdup(src_map, sizeof(*src_map) * src_n_map); + } } /*****************************************************************************/ static void -_wireguard_allowed_ip_hash_update (const NMPWireGuardAllowedIP *ip, - NMHashState *h) +_wireguard_allowed_ip_hash_update(const NMPWireGuardAllowedIP *ip, NMHashState *h) { - nm_hash_update_vals (h, ip->family, - ip->mask); + nm_hash_update_vals(h, ip->family, ip->mask); - if (ip->family == AF_INET) - nm_hash_update_val (h, ip->addr.addr4); - else if (ip->family == AF_INET6) - nm_hash_update_val (h, ip->addr.addr6); + if (ip->family == AF_INET) + nm_hash_update_val(h, ip->addr.addr4); + else if (ip->family == AF_INET6) + nm_hash_update_val(h, ip->addr.addr6); } static int -_wireguard_allowed_ip_cmp (const NMPWireGuardAllowedIP *a, - const NMPWireGuardAllowedIP *b) +_wireguard_allowed_ip_cmp(const NMPWireGuardAllowedIP *a, const NMPWireGuardAllowedIP *b) { - NM_CMP_SELF (a, b); + NM_CMP_SELF(a, b); - NM_CMP_FIELD (a, b, family); - NM_CMP_FIELD (a, b, mask); + NM_CMP_FIELD(a, b, family); + NM_CMP_FIELD(a, b, mask); - if (a->family == AF_INET) - NM_CMP_FIELD (a, b, addr.addr4); - else if (a->family == AF_INET6) - NM_CMP_FIELD_IN6ADDR (a, b, addr.addr6); + if (a->family == AF_INET) + NM_CMP_FIELD(a, b, addr.addr4); + else if (a->family == AF_INET6) + NM_CMP_FIELD_IN6ADDR(a, b, addr.addr6); - return 0; + return 0; } static void -_wireguard_peer_hash_update (const NMPWireGuardPeer *peer, - NMHashState *h) +_wireguard_peer_hash_update(const NMPWireGuardPeer *peer, NMHashState *h) { - guint i; + guint i; - nm_hash_update (h, peer->public_key, sizeof (peer->public_key)); - nm_hash_update (h, peer->preshared_key, sizeof (peer->preshared_key)); - nm_hash_update_vals (h, - peer->persistent_keepalive_interval, - peer->allowed_ips_len, - peer->rx_bytes, - peer->tx_bytes, - peer->last_handshake_time.tv_sec, - peer->last_handshake_time.tv_nsec); + nm_hash_update(h, peer->public_key, sizeof(peer->public_key)); + nm_hash_update(h, peer->preshared_key, sizeof(peer->preshared_key)); + nm_hash_update_vals(h, + peer->persistent_keepalive_interval, + peer->allowed_ips_len, + peer->rx_bytes, + peer->tx_bytes, + peer->last_handshake_time.tv_sec, + peer->last_handshake_time.tv_nsec); - nm_sock_addr_union_hash_update (&peer->endpoint, h); + nm_sock_addr_union_hash_update(&peer->endpoint, h); - for (i = 0; i < peer->allowed_ips_len; i++) - _wireguard_allowed_ip_hash_update (&peer->allowed_ips[i], h); + for (i = 0; i < peer->allowed_ips_len; i++) + _wireguard_allowed_ip_hash_update(&peer->allowed_ips[i], h); } static int -_wireguard_peer_cmp (const NMPWireGuardPeer *a, - const NMPWireGuardPeer *b) +_wireguard_peer_cmp(const NMPWireGuardPeer *a, const NMPWireGuardPeer *b) { - guint i; + guint i; - NM_CMP_SELF (a, b); + NM_CMP_SELF(a, b); - NM_CMP_FIELD (a, b, last_handshake_time.tv_sec); - NM_CMP_FIELD (a, b, last_handshake_time.tv_nsec); - NM_CMP_FIELD (a, b, rx_bytes); - NM_CMP_FIELD (a, b, tx_bytes); - NM_CMP_FIELD (a, b, allowed_ips_len); - NM_CMP_FIELD (a, b, persistent_keepalive_interval); - NM_CMP_FIELD (a, b, endpoint.sa.sa_family); - NM_CMP_FIELD_MEMCMP (a, b, public_key); - NM_CMP_FIELD_MEMCMP (a, b, preshared_key); + NM_CMP_FIELD(a, b, last_handshake_time.tv_sec); + NM_CMP_FIELD(a, b, last_handshake_time.tv_nsec); + NM_CMP_FIELD(a, b, rx_bytes); + NM_CMP_FIELD(a, b, tx_bytes); + NM_CMP_FIELD(a, b, allowed_ips_len); + NM_CMP_FIELD(a, b, persistent_keepalive_interval); + NM_CMP_FIELD(a, b, endpoint.sa.sa_family); + NM_CMP_FIELD_MEMCMP(a, b, public_key); + NM_CMP_FIELD_MEMCMP(a, b, preshared_key); - NM_CMP_RETURN (nm_sock_addr_union_cmp (&a->endpoint, &b->endpoint)); + NM_CMP_RETURN(nm_sock_addr_union_cmp(&a->endpoint, &b->endpoint)); - for (i = 0; i < a->allowed_ips_len; i++) { - NM_CMP_RETURN (_wireguard_allowed_ip_cmp (&a->allowed_ips[i], - &b->allowed_ips[i])); - } + for (i = 0; i < a->allowed_ips_len; i++) { + NM_CMP_RETURN(_wireguard_allowed_ip_cmp(&a->allowed_ips[i], &b->allowed_ips[i])); + } - return 0; + return 0; } /*****************************************************************************/ static const char * -_link_get_driver (struct udev_device *udevice, const char *kind, int ifindex) +_link_get_driver(struct udev_device *udevice, const char *kind, int ifindex) { - const char *driver = NULL; + const char *driver = NULL; - nm_assert (kind == g_intern_string (kind)); + nm_assert(kind == g_intern_string(kind)); - if (udevice) { - driver = nmp_utils_udev_get_driver (udevice); - if (driver) - return driver; - } + if (udevice) { + driver = nmp_utils_udev_get_driver(udevice); + if (driver) + return driver; + } - if (kind) - return kind; + if (kind) + return kind; - if (ifindex > 0) { - NMPUtilsEthtoolDriverInfo driver_info; + if (ifindex > 0) { + NMPUtilsEthtoolDriverInfo driver_info; - if (nmp_utils_ethtool_get_driver_info (ifindex, &driver_info)) { - if (driver_info.driver[0]) - return g_intern_string (driver_info.driver); - } - } + if (nmp_utils_ethtool_get_driver_info(ifindex, &driver_info)) { + if (driver_info.driver[0]) + return g_intern_string(driver_info.driver); + } + } - return "unknown"; + return "unknown"; } void -_nmp_object_fixup_link_udev_fields (NMPObject **obj_new, NMPObject *obj_orig, gboolean use_udev) -{ - const char *driver = NULL; - gboolean initialized = FALSE; - NMPObject *obj; - - nm_assert (obj_orig || *obj_new); - nm_assert (obj_new); - nm_assert (!obj_orig || NMP_OBJECT_GET_TYPE (obj_orig) == NMP_OBJECT_TYPE_LINK); - nm_assert (!*obj_new || NMP_OBJECT_GET_TYPE (*obj_new) == NMP_OBJECT_TYPE_LINK); - - obj = *obj_new ?: obj_orig; - - /* The link contains internal fields that are combined by - * properties from netlink and udev. Update those properties */ - - /* When a link is not in netlink, its udev fields don't matter. */ - if (obj->_link.netlink.is_in_netlink) { - driver = _link_get_driver (obj->_link.udev.device, - obj->link.kind, - obj->link.ifindex); - if (obj->_link.udev.device) - initialized = TRUE; - else if (!use_udev) { - /* If we don't use udev, we immediately mark the link as initialized. - * - * For that, we consult @use_udev argument, that is cached via - * nmp_cache_use_udev_get(). It is on purpose not to test - * for a writable /sys on every call. A minor reason for that is - * performance, but the real reason is reproducibility. - * */ - initialized = TRUE; - } - } - - if ( nm_streq0 (obj->link.driver, driver) - && obj->link.initialized == initialized) - return; - - if (!*obj_new) - obj = *obj_new = nmp_object_clone (obj, FALSE); - - obj->link.driver = driver; - obj->link.initialized = initialized; +_nmp_object_fixup_link_udev_fields(NMPObject **obj_new, NMPObject *obj_orig, gboolean use_udev) +{ + const char *driver = NULL; + gboolean initialized = FALSE; + NMPObject * obj; + + nm_assert(obj_orig || *obj_new); + nm_assert(obj_new); + nm_assert(!obj_orig || NMP_OBJECT_GET_TYPE(obj_orig) == NMP_OBJECT_TYPE_LINK); + nm_assert(!*obj_new || NMP_OBJECT_GET_TYPE(*obj_new) == NMP_OBJECT_TYPE_LINK); + + obj = *obj_new ?: obj_orig; + + /* The link contains internal fields that are combined by + * properties from netlink and udev. Update those properties */ + + /* When a link is not in netlink, its udev fields don't matter. */ + if (obj->_link.netlink.is_in_netlink) { + driver = _link_get_driver(obj->_link.udev.device, obj->link.kind, obj->link.ifindex); + if (obj->_link.udev.device) + initialized = TRUE; + else if (!use_udev) { + /* If we don't use udev, we immediately mark the link as initialized. + * + * For that, we consult @use_udev argument, that is cached via + * nmp_cache_use_udev_get(). It is on purpose not to test + * for a writable /sys on every call. A minor reason for that is + * performance, but the real reason is reproducibility. + * */ + initialized = TRUE; + } + } + + if (nm_streq0(obj->link.driver, driver) && obj->link.initialized == initialized) + return; + + if (!*obj_new) + obj = *obj_new = nmp_object_clone(obj, FALSE); + + obj->link.driver = driver; + obj->link.initialized = initialized; } static void -_nmp_object_fixup_link_master_connected (NMPObject **obj_new, NMPObject *obj_orig, const NMPCache *cache) +_nmp_object_fixup_link_master_connected(NMPObject ** obj_new, + NMPObject * obj_orig, + const NMPCache *cache) { - NMPObject *obj; + NMPObject *obj; - nm_assert (obj_orig || *obj_new); - nm_assert (obj_new); - nm_assert (!obj_orig || NMP_OBJECT_GET_TYPE (obj_orig) == NMP_OBJECT_TYPE_LINK); - nm_assert (!*obj_new || NMP_OBJECT_GET_TYPE (*obj_new) == NMP_OBJECT_TYPE_LINK); + nm_assert(obj_orig || *obj_new); + nm_assert(obj_new); + nm_assert(!obj_orig || NMP_OBJECT_GET_TYPE(obj_orig) == NMP_OBJECT_TYPE_LINK); + nm_assert(!*obj_new || NMP_OBJECT_GET_TYPE(*obj_new) == NMP_OBJECT_TYPE_LINK); - obj = *obj_new ?: obj_orig; + obj = *obj_new ?: obj_orig; - if (nmp_cache_link_connected_needs_toggle (cache, obj, NULL, NULL)) { - if (!*obj_new) - obj = *obj_new = nmp_object_clone (obj, FALSE); - obj->link.connected = !obj->link.connected; - } + if (nmp_cache_link_connected_needs_toggle(cache, obj, NULL, NULL)) { + if (!*obj_new) + obj = *obj_new = nmp_object_clone(obj, FALSE); + obj->link.connected = !obj->link.connected; + } } /*****************************************************************************/ static void -_vt_cmd_obj_dispose_link (NMPObject *obj) +_vt_cmd_obj_dispose_link(NMPObject *obj) { - if (obj->_link.udev.device) { - udev_device_unref (obj->_link.udev.device); - obj->_link.udev.device = NULL; - } - g_clear_object (&obj->_link.ext_data); - nmp_object_unref (obj->_link.netlink.lnk); + if (obj->_link.udev.device) { + udev_device_unref(obj->_link.udev.device); + obj->_link.udev.device = NULL; + } + g_clear_object(&obj->_link.ext_data); + nmp_object_unref(obj->_link.netlink.lnk); } static void -_vt_cmd_obj_dispose_lnk_vlan (NMPObject *obj) +_vt_cmd_obj_dispose_lnk_vlan(NMPObject *obj) { - g_free ((gpointer) obj->_lnk_vlan.ingress_qos_map); - g_free ((gpointer) obj->_lnk_vlan.egress_qos_map); + g_free((gpointer) obj->_lnk_vlan.ingress_qos_map); + g_free((gpointer) obj->_lnk_vlan.egress_qos_map); } static void -_wireguard_clear (NMPObjectLnkWireGuard *lnk) +_wireguard_clear(NMPObjectLnkWireGuard *lnk) { - guint i; + guint i; - nm_explicit_bzero (lnk->_public.private_key, - sizeof (lnk->_public.private_key)); - for (i = 0; i < lnk->peers_len; i++) { - NMPWireGuardPeer *peer = (NMPWireGuardPeer *) &lnk->peers[i]; + nm_explicit_bzero(lnk->_public.private_key, sizeof(lnk->_public.private_key)); + for (i = 0; i < lnk->peers_len; i++) { + NMPWireGuardPeer *peer = (NMPWireGuardPeer *) &lnk->peers[i]; - nm_explicit_bzero (peer->preshared_key, sizeof (peer->preshared_key)); - } - g_free ((gpointer) lnk->peers); - g_free ((gpointer) lnk->_allowed_ips_buf); + nm_explicit_bzero(peer->preshared_key, sizeof(peer->preshared_key)); + } + g_free((gpointer) lnk->peers); + g_free((gpointer) lnk->_allowed_ips_buf); } static void -_vt_cmd_obj_dispose_lnk_wireguard (NMPObject *obj) +_vt_cmd_obj_dispose_lnk_wireguard(NMPObject *obj) { - _wireguard_clear (&obj->_lnk_wireguard); + _wireguard_clear(&obj->_lnk_wireguard); } static NMPObject * -_nmp_object_new_from_class (const NMPClass *klass) +_nmp_object_new_from_class(const NMPClass *klass) { - NMPObject *obj; + NMPObject *obj; - nm_assert (klass); - nm_assert (klass->sizeof_data > 0); - nm_assert (klass->sizeof_public > 0 && klass->sizeof_public <= klass->sizeof_data); + nm_assert(klass); + nm_assert(klass->sizeof_data > 0); + nm_assert(klass->sizeof_public > 0 && klass->sizeof_public <= klass->sizeof_data); - obj = g_slice_alloc0 (klass->sizeof_data + G_STRUCT_OFFSET (NMPObject, object)); - obj->_class = klass; - obj->parent._ref_count = 1; - return obj; + obj = g_slice_alloc0(klass->sizeof_data + G_STRUCT_OFFSET(NMPObject, object)); + obj->_class = klass; + obj->parent._ref_count = 1; + return obj; } NMPObject * -nmp_object_new (NMPObjectType obj_type, gconstpointer plobj) +nmp_object_new(NMPObjectType obj_type, gconstpointer plobj) { - const NMPClass *klass = nmp_class_from_type (obj_type); - NMPObject *obj; + const NMPClass *klass = nmp_class_from_type(obj_type); + NMPObject * obj; - obj = _nmp_object_new_from_class (klass); - if (plobj) - memcpy (&obj->object, plobj, klass->sizeof_public); - return obj; + obj = _nmp_object_new_from_class(klass); + if (plobj) + memcpy(&obj->object, plobj, klass->sizeof_public); + return obj; } NMPObject * -nmp_object_new_link (int ifindex) +nmp_object_new_link(int ifindex) { - NMPObject *obj; + NMPObject *obj; - obj = nmp_object_new (NMP_OBJECT_TYPE_LINK, NULL); - obj->link.ifindex = ifindex; - return obj; + obj = nmp_object_new(NMP_OBJECT_TYPE_LINK, NULL); + obj->link.ifindex = ifindex; + return obj; } /*****************************************************************************/ static void -_nmp_object_stackinit_from_class (NMPObject *obj, const NMPClass *klass) +_nmp_object_stackinit_from_class(NMPObject *obj, const NMPClass *klass) { - nm_assert (obj); - nm_assert (klass); + nm_assert(obj); + nm_assert(klass); - *obj = (NMPObject) { - .parent = { - .klass = (const NMDedupMultiObjClass *) klass, - ._ref_count = NM_OBJ_REF_COUNT_STACKINIT, - }, - }; + *obj = (NMPObject){ + .parent = + { + .klass = (const NMDedupMultiObjClass *) klass, + ._ref_count = NM_OBJ_REF_COUNT_STACKINIT, + }, + }; } static NMPObject * -_nmp_object_stackinit_from_type (NMPObject *obj, NMPObjectType obj_type) +_nmp_object_stackinit_from_type(NMPObject *obj, NMPObjectType obj_type) { - const NMPClass *klass; + const NMPClass *klass; - nm_assert (obj); - klass = nmp_class_from_type (obj_type); - nm_assert (klass); + nm_assert(obj); + klass = nmp_class_from_type(obj_type); + nm_assert(klass); - *obj = (NMPObject) { - .parent = { - .klass = (const NMDedupMultiObjClass *) klass, - ._ref_count = NM_OBJ_REF_COUNT_STACKINIT, - }, - }; - return obj; + *obj = (NMPObject){ + .parent = + { + .klass = (const NMDedupMultiObjClass *) klass, + ._ref_count = NM_OBJ_REF_COUNT_STACKINIT, + }, + }; + return obj; } const NMPObject * -nmp_object_stackinit (NMPObject *obj, NMPObjectType obj_type, gconstpointer plobj) +nmp_object_stackinit(NMPObject *obj, NMPObjectType obj_type, gconstpointer plobj) { - const NMPClass *klass = nmp_class_from_type (obj_type); + const NMPClass *klass = nmp_class_from_type(obj_type); - _nmp_object_stackinit_from_class (obj, klass); - if (plobj) - memcpy (&obj->object, plobj, klass->sizeof_public); - return obj; + _nmp_object_stackinit_from_class(obj, klass); + if (plobj) + memcpy(&obj->object, plobj, klass->sizeof_public); + return obj; } const NMPObject * -nmp_object_stackinit_id (NMPObject *obj, const NMPObject *src) +nmp_object_stackinit_id(NMPObject *obj, const NMPObject *src) { - const NMPClass *klass; + const NMPClass *klass; - nm_assert (NMP_OBJECT_IS_VALID (src)); - nm_assert (obj); + nm_assert(NMP_OBJECT_IS_VALID(src)); + nm_assert(obj); - klass = NMP_OBJECT_GET_CLASS (src); - _nmp_object_stackinit_from_class (obj, klass); - if (klass->cmd_plobj_id_copy) - klass->cmd_plobj_id_copy (&obj->object, &src->object); - return obj; + klass = NMP_OBJECT_GET_CLASS(src); + _nmp_object_stackinit_from_class(obj, klass); + if (klass->cmd_plobj_id_copy) + klass->cmd_plobj_id_copy(&obj->object, &src->object); + return obj; } const NMPObject * -nmp_object_stackinit_id_link (NMPObject *obj, int ifindex) +nmp_object_stackinit_id_link(NMPObject *obj, int ifindex) { - _nmp_object_stackinit_from_type (obj, NMP_OBJECT_TYPE_LINK); - obj->link.ifindex = ifindex; - return obj; + _nmp_object_stackinit_from_type(obj, NMP_OBJECT_TYPE_LINK); + obj->link.ifindex = ifindex; + return obj; } const NMPObject * -nmp_object_stackinit_id_ip4_address (NMPObject *obj, int ifindex, guint32 address, guint8 plen, guint32 peer_address) +nmp_object_stackinit_id_ip4_address(NMPObject *obj, + int ifindex, + guint32 address, + guint8 plen, + guint32 peer_address) { - _nmp_object_stackinit_from_type (obj, NMP_OBJECT_TYPE_IP4_ADDRESS); - obj->ip4_address.ifindex = ifindex; - obj->ip4_address.address = address; - obj->ip4_address.plen = plen; - obj->ip4_address.peer_address = peer_address; - return obj; + _nmp_object_stackinit_from_type(obj, NMP_OBJECT_TYPE_IP4_ADDRESS); + obj->ip4_address.ifindex = ifindex; + obj->ip4_address.address = address; + obj->ip4_address.plen = plen; + obj->ip4_address.peer_address = peer_address; + return obj; } const NMPObject * -nmp_object_stackinit_id_ip6_address (NMPObject *obj, int ifindex, const struct in6_addr *address) +nmp_object_stackinit_id_ip6_address(NMPObject *obj, int ifindex, const struct in6_addr *address) { - _nmp_object_stackinit_from_type (obj, NMP_OBJECT_TYPE_IP6_ADDRESS); - obj->ip4_address.ifindex = ifindex; - if (address) - obj->ip6_address.address = *address; - return obj; + _nmp_object_stackinit_from_type(obj, NMP_OBJECT_TYPE_IP6_ADDRESS); + obj->ip4_address.ifindex = ifindex; + if (address) + obj->ip6_address.address = *address; + return obj; } /*****************************************************************************/ const char * -nmp_object_to_string (const NMPObject *obj, NMPObjectToStringMode to_string_mode, char *buf, gsize buf_size) -{ - const NMPClass *klass; - char buf2[sizeof (_nm_utils_to_string_buffer)]; - - if (!nm_utils_to_string_buffer_init_null (obj, &buf, &buf_size)) - return buf; - - g_return_val_if_fail (NMP_OBJECT_IS_VALID (obj), NULL); - - klass = NMP_OBJECT_GET_CLASS (obj); - - if (klass->cmd_obj_to_string) - return klass->cmd_obj_to_string (obj, to_string_mode, buf, buf_size); - - switch (to_string_mode) { - case NMP_OBJECT_TO_STRING_ID: - if (!klass->cmd_plobj_to_string_id) { - g_snprintf (buf, buf_size, "%p", obj); - return buf; - } - return klass->cmd_plobj_to_string_id (&obj->object, buf, buf_size); - case NMP_OBJECT_TO_STRING_ALL: - g_snprintf (buf, buf_size, - "[%s,%p,%u,%calive,%cvisible; %s]", - klass->obj_type_name, obj, obj->parent._ref_count, - nmp_object_is_alive (obj) ? '+' : '-', - nmp_object_is_visible (obj) ? '+' : '-', - NMP_OBJECT_GET_CLASS (obj)->cmd_plobj_to_string (&obj->object, buf2, sizeof (buf2))); - return buf; - case NMP_OBJECT_TO_STRING_PUBLIC: - NMP_OBJECT_GET_CLASS (obj)->cmd_plobj_to_string (&obj->object, buf, buf_size); - return buf; - default: - g_return_val_if_reached ("ERROR"); - } +nmp_object_to_string(const NMPObject * obj, + NMPObjectToStringMode to_string_mode, + char * buf, + gsize buf_size) +{ + const NMPClass *klass; + char buf2[sizeof(_nm_utils_to_string_buffer)]; + + if (!nm_utils_to_string_buffer_init_null(obj, &buf, &buf_size)) + return buf; + + g_return_val_if_fail(NMP_OBJECT_IS_VALID(obj), NULL); + + klass = NMP_OBJECT_GET_CLASS(obj); + + if (klass->cmd_obj_to_string) + return klass->cmd_obj_to_string(obj, to_string_mode, buf, buf_size); + + switch (to_string_mode) { + case NMP_OBJECT_TO_STRING_ID: + if (!klass->cmd_plobj_to_string_id) { + g_snprintf(buf, buf_size, "%p", obj); + return buf; + } + return klass->cmd_plobj_to_string_id(&obj->object, buf, buf_size); + case NMP_OBJECT_TO_STRING_ALL: + g_snprintf( + buf, + buf_size, + "[%s,%p,%u,%calive,%cvisible; %s]", + klass->obj_type_name, + obj, + obj->parent._ref_count, + nmp_object_is_alive(obj) ? '+' : '-', + nmp_object_is_visible(obj) ? '+' : '-', + NMP_OBJECT_GET_CLASS(obj)->cmd_plobj_to_string(&obj->object, buf2, sizeof(buf2))); + return buf; + case NMP_OBJECT_TO_STRING_PUBLIC: + NMP_OBJECT_GET_CLASS(obj)->cmd_plobj_to_string(&obj->object, buf, buf_size); + return buf; + default: + g_return_val_if_reached("ERROR"); + } } static const char * -_vt_cmd_obj_to_string_link (const NMPObject *obj, NMPObjectToStringMode to_string_mode, char *buf, gsize buf_size) -{ - const NMPClass *klass = NMP_OBJECT_GET_CLASS (obj); - char *b = buf; - - switch (to_string_mode) { - case NMP_OBJECT_TO_STRING_ID: - return klass->cmd_plobj_to_string_id (&obj->object, buf, buf_size); - case NMP_OBJECT_TO_STRING_ALL: - nm_utils_strbuf_append (&b, &buf_size, - "[%s,%p,%u,%calive,%cvisible,%cin-nl,%p; ", - klass->obj_type_name, obj, obj->parent._ref_count, - nmp_object_is_alive (obj) ? '+' : '-', - nmp_object_is_visible (obj) ? '+' : '-', - obj->_link.netlink.is_in_netlink ? '+' : '-', - obj->_link.udev.device); - NMP_OBJECT_GET_CLASS (obj)->cmd_plobj_to_string (&obj->object, b, buf_size); - nm_utils_strbuf_seek_end (&b, &buf_size); - if (obj->_link.netlink.lnk) { - nm_utils_strbuf_append_str (&b, &buf_size, "; "); - nmp_object_to_string (obj->_link.netlink.lnk, NMP_OBJECT_TO_STRING_ALL, b, buf_size); - nm_utils_strbuf_seek_end (&b, &buf_size); - } - nm_utils_strbuf_append_c (&b, &buf_size, ']'); - return buf; - case NMP_OBJECT_TO_STRING_PUBLIC: - NMP_OBJECT_GET_CLASS (obj)->cmd_plobj_to_string (&obj->object, b, buf_size); - if (obj->_link.netlink.lnk) { - nm_utils_strbuf_seek_end (&b, &buf_size); - nm_utils_strbuf_append_str (&b, &buf_size, "; "); - nmp_object_to_string (obj->_link.netlink.lnk, NMP_OBJECT_TO_STRING_PUBLIC, b, buf_size); - } - return buf; - default: - g_return_val_if_reached ("ERROR"); - } +_vt_cmd_obj_to_string_link(const NMPObject * obj, + NMPObjectToStringMode to_string_mode, + char * buf, + gsize buf_size) +{ + const NMPClass *klass = NMP_OBJECT_GET_CLASS(obj); + char * b = buf; + + switch (to_string_mode) { + case NMP_OBJECT_TO_STRING_ID: + return klass->cmd_plobj_to_string_id(&obj->object, buf, buf_size); + case NMP_OBJECT_TO_STRING_ALL: + nm_utils_strbuf_append(&b, + &buf_size, + "[%s,%p,%u,%calive,%cvisible,%cin-nl,%p; ", + klass->obj_type_name, + obj, + obj->parent._ref_count, + nmp_object_is_alive(obj) ? '+' : '-', + nmp_object_is_visible(obj) ? '+' : '-', + obj->_link.netlink.is_in_netlink ? '+' : '-', + obj->_link.udev.device); + NMP_OBJECT_GET_CLASS(obj)->cmd_plobj_to_string(&obj->object, b, buf_size); + nm_utils_strbuf_seek_end(&b, &buf_size); + if (obj->_link.netlink.lnk) { + nm_utils_strbuf_append_str(&b, &buf_size, "; "); + nmp_object_to_string(obj->_link.netlink.lnk, NMP_OBJECT_TO_STRING_ALL, b, buf_size); + nm_utils_strbuf_seek_end(&b, &buf_size); + } + nm_utils_strbuf_append_c(&b, &buf_size, ']'); + return buf; + case NMP_OBJECT_TO_STRING_PUBLIC: + NMP_OBJECT_GET_CLASS(obj)->cmd_plobj_to_string(&obj->object, b, buf_size); + if (obj->_link.netlink.lnk) { + nm_utils_strbuf_seek_end(&b, &buf_size); + nm_utils_strbuf_append_str(&b, &buf_size, "; "); + nmp_object_to_string(obj->_link.netlink.lnk, NMP_OBJECT_TO_STRING_PUBLIC, b, buf_size); + } + return buf; + default: + g_return_val_if_reached("ERROR"); + } } static const char * -_vt_cmd_obj_to_string_lnk_vlan (const NMPObject *obj, NMPObjectToStringMode to_string_mode, char *buf, gsize buf_size) -{ - const NMPClass *klass; - char buf2[sizeof (_nm_utils_to_string_buffer)]; - char *b; - gsize l; - - klass = NMP_OBJECT_GET_CLASS (obj); - - switch (to_string_mode) { - case NMP_OBJECT_TO_STRING_ID: - g_snprintf (buf, buf_size, "%p", obj); - return buf; - case NMP_OBJECT_TO_STRING_ALL: - - g_snprintf (buf, buf_size, - "[%s,%p,%u,%calive,%cvisible; %s]", - klass->obj_type_name, obj, obj->parent._ref_count, - nmp_object_is_alive (obj) ? '+' : '-', - nmp_object_is_visible (obj) ? '+' : '-', - nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_PUBLIC, buf2, sizeof (buf2))); - return buf; - case NMP_OBJECT_TO_STRING_PUBLIC: - NMP_OBJECT_GET_CLASS (obj)->cmd_plobj_to_string (&obj->object, buf, buf_size); - - b = buf; - l = strlen (b); - b += l; - buf_size -= l; - - if (obj->_lnk_vlan.n_ingress_qos_map) { - nm_platform_vlan_qos_mapping_to_string (" ingress-qos-map", - obj->_lnk_vlan.ingress_qos_map, - obj->_lnk_vlan.n_ingress_qos_map, - b, - buf_size); - l = strlen (b); - b += l; - buf_size -= l; - } - if (obj->_lnk_vlan.n_egress_qos_map) { - nm_platform_vlan_qos_mapping_to_string (" egress-qos-map", - obj->_lnk_vlan.egress_qos_map, - obj->_lnk_vlan.n_egress_qos_map, - b, - buf_size); - l = strlen (b); - b += l; - buf_size -= l; - } - - return buf; - default: - g_return_val_if_reached ("ERROR"); - } +_vt_cmd_obj_to_string_lnk_vlan(const NMPObject * obj, + NMPObjectToStringMode to_string_mode, + char * buf, + gsize buf_size) +{ + const NMPClass *klass; + char buf2[sizeof(_nm_utils_to_string_buffer)]; + char * b; + gsize l; + + klass = NMP_OBJECT_GET_CLASS(obj); + + switch (to_string_mode) { + case NMP_OBJECT_TO_STRING_ID: + g_snprintf(buf, buf_size, "%p", obj); + return buf; + case NMP_OBJECT_TO_STRING_ALL: + + g_snprintf(buf, + buf_size, + "[%s,%p,%u,%calive,%cvisible; %s]", + klass->obj_type_name, + obj, + obj->parent._ref_count, + nmp_object_is_alive(obj) ? '+' : '-', + nmp_object_is_visible(obj) ? '+' : '-', + nmp_object_to_string(obj, NMP_OBJECT_TO_STRING_PUBLIC, buf2, sizeof(buf2))); + return buf; + case NMP_OBJECT_TO_STRING_PUBLIC: + NMP_OBJECT_GET_CLASS(obj)->cmd_plobj_to_string(&obj->object, buf, buf_size); + + b = buf; + l = strlen(b); + b += l; + buf_size -= l; + + if (obj->_lnk_vlan.n_ingress_qos_map) { + nm_platform_vlan_qos_mapping_to_string(" ingress-qos-map", + obj->_lnk_vlan.ingress_qos_map, + obj->_lnk_vlan.n_ingress_qos_map, + b, + buf_size); + l = strlen(b); + b += l; + buf_size -= l; + } + if (obj->_lnk_vlan.n_egress_qos_map) { + nm_platform_vlan_qos_mapping_to_string(" egress-qos-map", + obj->_lnk_vlan.egress_qos_map, + obj->_lnk_vlan.n_egress_qos_map, + b, + buf_size); + l = strlen(b); + b += l; + buf_size -= l; + } + + return buf; + default: + g_return_val_if_reached("ERROR"); + } } static const char * -_vt_cmd_obj_to_string_lnk_wireguard (const NMPObject *obj, NMPObjectToStringMode to_string_mode, char *buf, gsize buf_size) -{ - const NMPClass *klass; - char buf2[sizeof (_nm_utils_to_string_buffer)]; - char *b; - guint i; - - klass = NMP_OBJECT_GET_CLASS (obj); - - switch (to_string_mode) { - case NMP_OBJECT_TO_STRING_ID: - g_snprintf (buf, buf_size, "%p", obj); - return buf; - case NMP_OBJECT_TO_STRING_ALL: - b = buf; - - nm_utils_strbuf_append (&b, &buf_size, - "[%s,%p,%u,%calive,%cvisible; %s" - "%s", - klass->obj_type_name, obj, obj->parent._ref_count, - nmp_object_is_alive (obj) ? '+' : '-', - nmp_object_is_visible (obj) ? '+' : '-', - nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_PUBLIC, buf2, sizeof (buf2)), - obj->_lnk_wireguard.peers_len > 0 - ? " peers {" - : ""); - - for (i = 0; i < obj->_lnk_wireguard.peers_len; i++) { - const NMPWireGuardPeer *peer = &obj->_lnk_wireguard.peers[i]; - - nm_utils_strbuf_append_str (&b, &buf_size, " { "); - nm_platform_wireguard_peer_to_string (peer, b, buf_size); - nm_utils_strbuf_seek_end (&b, &buf_size); - nm_utils_strbuf_append_str (&b, &buf_size, " }"); - } - if (obj->_lnk_wireguard.peers_len) - nm_utils_strbuf_append_str (&b, &buf_size, " }"); - - return buf; - case NMP_OBJECT_TO_STRING_PUBLIC: - NMP_OBJECT_GET_CLASS (obj)->cmd_plobj_to_string (&obj->object, buf, buf_size); - - return buf; - default: - g_return_val_if_reached ("ERROR"); - } -} - -#define _vt_cmd_plobj_to_string_id(type, plat_type, ...) \ -static const char * \ -_vt_cmd_plobj_to_string_id_##type (const NMPlatformObject *_obj, char *buf, gsize buf_len) \ -{ \ - plat_type *const obj = (plat_type *) _obj; \ - _nm_unused char buf1[NM_UTILS_INET_ADDRSTRLEN]; \ - _nm_unused char buf2[NM_UTILS_INET_ADDRSTRLEN]; \ - \ - g_snprintf (buf, buf_len, \ - __VA_ARGS__); \ - return buf; \ -} -_vt_cmd_plobj_to_string_id (link, NMPlatformLink, "%d", obj->ifindex); -_vt_cmd_plobj_to_string_id (ip4_address, NMPlatformIP4Address, "%d: %s/%d%s%s", obj->ifindex, _nm_utils_inet4_ntop ( obj->address, buf1), obj->plen, - obj->peer_address != obj->address ? "," : "", - obj->peer_address != obj->address ? _nm_utils_inet4_ntop (nm_utils_ip4_address_clear_host_address (obj->peer_address, obj->plen), buf2) : ""); -_vt_cmd_plobj_to_string_id (ip6_address, NMPlatformIP6Address, "%d: %s", obj->ifindex, _nm_utils_inet6_ntop (&obj->address, buf1)); -_vt_cmd_plobj_to_string_id (qdisc, NMPlatformQdisc, "%d: %d", obj->ifindex, obj->parent); -_vt_cmd_plobj_to_string_id (tfilter, NMPlatformTfilter, "%d: %d", obj->ifindex, obj->parent); +_vt_cmd_obj_to_string_lnk_wireguard(const NMPObject * obj, + NMPObjectToStringMode to_string_mode, + char * buf, + gsize buf_size) +{ + const NMPClass *klass; + char buf2[sizeof(_nm_utils_to_string_buffer)]; + char * b; + guint i; + + klass = NMP_OBJECT_GET_CLASS(obj); + + switch (to_string_mode) { + case NMP_OBJECT_TO_STRING_ID: + g_snprintf(buf, buf_size, "%p", obj); + return buf; + case NMP_OBJECT_TO_STRING_ALL: + b = buf; + + nm_utils_strbuf_append( + &b, + &buf_size, + "[%s,%p,%u,%calive,%cvisible; %s" + "%s", + klass->obj_type_name, + obj, + obj->parent._ref_count, + nmp_object_is_alive(obj) ? '+' : '-', + nmp_object_is_visible(obj) ? '+' : '-', + nmp_object_to_string(obj, NMP_OBJECT_TO_STRING_PUBLIC, buf2, sizeof(buf2)), + obj->_lnk_wireguard.peers_len > 0 ? " peers {" : ""); + + for (i = 0; i < obj->_lnk_wireguard.peers_len; i++) { + const NMPWireGuardPeer *peer = &obj->_lnk_wireguard.peers[i]; + + nm_utils_strbuf_append_str(&b, &buf_size, " { "); + nm_platform_wireguard_peer_to_string(peer, b, buf_size); + nm_utils_strbuf_seek_end(&b, &buf_size); + nm_utils_strbuf_append_str(&b, &buf_size, " }"); + } + if (obj->_lnk_wireguard.peers_len) + nm_utils_strbuf_append_str(&b, &buf_size, " }"); + + return buf; + case NMP_OBJECT_TO_STRING_PUBLIC: + NMP_OBJECT_GET_CLASS(obj)->cmd_plobj_to_string(&obj->object, buf, buf_size); + + return buf; + default: + g_return_val_if_reached("ERROR"); + } +} + +#define _vt_cmd_plobj_to_string_id(type, plat_type, ...) \ + static const char *_vt_cmd_plobj_to_string_id_##type(const NMPlatformObject *_obj, \ + char * buf, \ + gsize buf_len) \ + { \ + plat_type *const obj = (plat_type *) _obj; \ + _nm_unused char buf1[NM_UTILS_INET_ADDRSTRLEN]; \ + _nm_unused char buf2[NM_UTILS_INET_ADDRSTRLEN]; \ + \ + g_snprintf(buf, buf_len, __VA_ARGS__); \ + return buf; \ + } \ + struct _dummy_struct_for_tailing_semicolon + +_vt_cmd_plobj_to_string_id(link, NMPlatformLink, "%d", obj->ifindex); + +_vt_cmd_plobj_to_string_id(ip4_address, + NMPlatformIP4Address, + "%d: %s/%d%s%s", + obj->ifindex, + _nm_utils_inet4_ntop(obj->address, buf1), + obj->plen, + obj->peer_address != obj->address ? "," : "", + obj->peer_address != obj->address ? _nm_utils_inet4_ntop( + nm_utils_ip4_address_clear_host_address(obj->peer_address, + obj->plen), + buf2) + : ""); + +_vt_cmd_plobj_to_string_id(ip6_address, + NMPlatformIP6Address, + "%d: %s", + obj->ifindex, + _nm_utils_inet6_ntop(&obj->address, buf1)); + +_vt_cmd_plobj_to_string_id(qdisc, NMPlatformQdisc, "%d: %d", obj->ifindex, obj->parent); + +_vt_cmd_plobj_to_string_id(tfilter, NMPlatformTfilter, "%d: %d", obj->ifindex, obj->parent); void -nmp_object_hash_update (const NMPObject *obj, NMHashState *h) +nmp_object_hash_update(const NMPObject *obj, NMHashState *h) { - const NMPClass *klass; + const NMPClass *klass; - g_return_if_fail (NMP_OBJECT_IS_VALID (obj)); + g_return_if_fail(NMP_OBJECT_IS_VALID(obj)); - klass = NMP_OBJECT_GET_CLASS (obj); + klass = NMP_OBJECT_GET_CLASS(obj); - nm_hash_update_val (h, klass->obj_type); - if (klass->cmd_obj_hash_update) - klass->cmd_obj_hash_update (obj, h); - else if (klass->cmd_plobj_hash_update) - klass->cmd_plobj_hash_update (&obj->object, h); - else - nm_hash_update_val (h, obj); + nm_hash_update_val(h, klass->obj_type); + if (klass->cmd_obj_hash_update) + klass->cmd_obj_hash_update(obj, h); + else if (klass->cmd_plobj_hash_update) + klass->cmd_plobj_hash_update(&obj->object, h); + else + nm_hash_update_val(h, obj); } static void -_vt_cmd_obj_hash_update_link (const NMPObject *obj, NMHashState *h) +_vt_cmd_obj_hash_update_link(const NMPObject *obj, NMHashState *h) { - nm_assert (NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_LINK); + nm_assert(NMP_OBJECT_GET_TYPE(obj) == NMP_OBJECT_TYPE_LINK); - nm_platform_link_hash_update (&obj->link, h); - nm_hash_update_vals (h, - obj->_link.netlink.is_in_netlink, - obj->_link.wireguard_family_id, - obj->_link.udev.device); - if (obj->_link.netlink.lnk) - nmp_object_hash_update (obj->_link.netlink.lnk, h); + nm_platform_link_hash_update(&obj->link, h); + nm_hash_update_vals(h, + obj->_link.netlink.is_in_netlink, + obj->_link.wireguard_family_id, + obj->_link.udev.device); + if (obj->_link.netlink.lnk) + nmp_object_hash_update(obj->_link.netlink.lnk, h); } static void -_vt_cmd_obj_hash_update_lnk_vlan (const NMPObject *obj, NMHashState *h) +_vt_cmd_obj_hash_update_lnk_vlan(const NMPObject *obj, NMHashState *h) { - nm_assert (NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_LNK_VLAN); + nm_assert(NMP_OBJECT_GET_TYPE(obj) == NMP_OBJECT_TYPE_LNK_VLAN); - nm_platform_lnk_vlan_hash_update (&obj->lnk_vlan, h); - _vlan_xgress_qos_mappings_hash_update (obj->_lnk_vlan.n_ingress_qos_map, - obj->_lnk_vlan.ingress_qos_map, - h); - _vlan_xgress_qos_mappings_hash_update (obj->_lnk_vlan.n_egress_qos_map, - obj->_lnk_vlan.egress_qos_map, - h); + nm_platform_lnk_vlan_hash_update(&obj->lnk_vlan, h); + _vlan_xgress_qos_mappings_hash_update(obj->_lnk_vlan.n_ingress_qos_map, + obj->_lnk_vlan.ingress_qos_map, + h); + _vlan_xgress_qos_mappings_hash_update(obj->_lnk_vlan.n_egress_qos_map, + obj->_lnk_vlan.egress_qos_map, + h); } static void -_vt_cmd_obj_hash_update_lnk_wireguard (const NMPObject *obj, NMHashState *h) +_vt_cmd_obj_hash_update_lnk_wireguard(const NMPObject *obj, NMHashState *h) { - guint i; + guint i; - nm_assert (NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_LNK_WIREGUARD); + nm_assert(NMP_OBJECT_GET_TYPE(obj) == NMP_OBJECT_TYPE_LNK_WIREGUARD); - nm_platform_lnk_wireguard_hash_update (&obj->lnk_wireguard, h); + nm_platform_lnk_wireguard_hash_update(&obj->lnk_wireguard, h); - nm_hash_update_val (h, obj->_lnk_wireguard.peers_len); - for (i = 0; i < obj->_lnk_wireguard.peers_len; i++) - _wireguard_peer_hash_update (&obj->_lnk_wireguard.peers[i], h); + nm_hash_update_val(h, obj->_lnk_wireguard.peers_len); + for (i = 0; i < obj->_lnk_wireguard.peers_len; i++) + _wireguard_peer_hash_update(&obj->_lnk_wireguard.peers[i], h); } int -nmp_object_cmp (const NMPObject *obj1, const NMPObject *obj2) +nmp_object_cmp(const NMPObject *obj1, const NMPObject *obj2) { - const NMPClass *klass1, *klass2; + const NMPClass *klass1, *klass2; - NM_CMP_SELF (obj1, obj2); + NM_CMP_SELF(obj1, obj2); - g_return_val_if_fail (NMP_OBJECT_IS_VALID (obj1), -1); - g_return_val_if_fail (NMP_OBJECT_IS_VALID (obj2), 1); + g_return_val_if_fail(NMP_OBJECT_IS_VALID(obj1), -1); + g_return_val_if_fail(NMP_OBJECT_IS_VALID(obj2), 1); - klass1 = NMP_OBJECT_GET_CLASS (obj1); - klass2 = NMP_OBJECT_GET_CLASS (obj2); + klass1 = NMP_OBJECT_GET_CLASS(obj1); + klass2 = NMP_OBJECT_GET_CLASS(obj2); - if (klass1 != klass2) { - nm_assert (klass1->obj_type != klass2->obj_type); - return klass1->obj_type < klass2->obj_type ? -1 : 1; - } + if (klass1 != klass2) { + nm_assert(klass1->obj_type != klass2->obj_type); + return klass1->obj_type < klass2->obj_type ? -1 : 1; + } - if (klass1->cmd_obj_cmp) - return klass1->cmd_obj_cmp (obj1, obj2); - return klass1->cmd_plobj_cmp (&obj1->object, &obj2->object); + if (klass1->cmd_obj_cmp) + return klass1->cmd_obj_cmp(obj1, obj2); + return klass1->cmd_plobj_cmp(&obj1->object, &obj2->object); } static int -_vt_cmd_obj_cmp_link (const NMPObject *obj1, const NMPObject *obj2) +_vt_cmd_obj_cmp_link(const NMPObject *obj1, const NMPObject *obj2) { - NM_CMP_RETURN (nm_platform_link_cmp (&obj1->link, &obj2->link)); - NM_CMP_DIRECT (obj1->_link.netlink.is_in_netlink, obj2->_link.netlink.is_in_netlink); - NM_CMP_RETURN (nmp_object_cmp (obj1->_link.netlink.lnk, obj2->_link.netlink.lnk)); - NM_CMP_DIRECT (obj1->_link.wireguard_family_id, obj2->_link.wireguard_family_id); + NM_CMP_RETURN(nm_platform_link_cmp(&obj1->link, &obj2->link)); + NM_CMP_DIRECT(obj1->_link.netlink.is_in_netlink, obj2->_link.netlink.is_in_netlink); + NM_CMP_RETURN(nmp_object_cmp(obj1->_link.netlink.lnk, obj2->_link.netlink.lnk)); + NM_CMP_DIRECT(obj1->_link.wireguard_family_id, obj2->_link.wireguard_family_id); - if (obj1->_link.udev.device != obj2->_link.udev.device) { - if (!obj1->_link.udev.device) - return -1; - if (!obj2->_link.udev.device) - return 1; + if (obj1->_link.udev.device != obj2->_link.udev.device) { + if (!obj1->_link.udev.device) + return -1; + if (!obj2->_link.udev.device) + return 1; - /* Only compare based on pointer values. That is ugly because it's not a - * stable sort order. - * - * Have this check as very last. */ - return (obj1->_link.udev.device < obj2->_link.udev.device) ? -1 : 1; - } + /* Only compare based on pointer values. That is ugly because it's not a + * stable sort order. + * + * Have this check as very last. */ + return (obj1->_link.udev.device < obj2->_link.udev.device) ? -1 : 1; + } - return 0; + return 0; } static int -_vt_cmd_obj_cmp_lnk_vlan (const NMPObject *obj1, const NMPObject *obj2) +_vt_cmd_obj_cmp_lnk_vlan(const NMPObject *obj1, const NMPObject *obj2) { - int c; + int c; - c = nm_platform_lnk_vlan_cmp (&obj1->lnk_vlan, &obj2->lnk_vlan); - if (c) - return c; + c = nm_platform_lnk_vlan_cmp(&obj1->lnk_vlan, &obj2->lnk_vlan); + if (c) + return c; - if (obj1->_lnk_vlan.n_ingress_qos_map != obj2->_lnk_vlan.n_ingress_qos_map) - return obj1->_lnk_vlan.n_ingress_qos_map < obj2->_lnk_vlan.n_ingress_qos_map ? -1 : 1; - if (obj1->_lnk_vlan.n_egress_qos_map != obj2->_lnk_vlan.n_egress_qos_map) - return obj1->_lnk_vlan.n_egress_qos_map < obj2->_lnk_vlan.n_egress_qos_map ? -1 : 1; + if (obj1->_lnk_vlan.n_ingress_qos_map != obj2->_lnk_vlan.n_ingress_qos_map) + return obj1->_lnk_vlan.n_ingress_qos_map < obj2->_lnk_vlan.n_ingress_qos_map ? -1 : 1; + if (obj1->_lnk_vlan.n_egress_qos_map != obj2->_lnk_vlan.n_egress_qos_map) + return obj1->_lnk_vlan.n_egress_qos_map < obj2->_lnk_vlan.n_egress_qos_map ? -1 : 1; - c = _vlan_xgress_qos_mappings_cmp (obj1->_lnk_vlan.n_ingress_qos_map, obj1->_lnk_vlan.ingress_qos_map, obj2->_lnk_vlan.ingress_qos_map); - if (c) - return c; - c = _vlan_xgress_qos_mappings_cmp (obj1->_lnk_vlan.n_egress_qos_map, obj1->_lnk_vlan.egress_qos_map, obj2->_lnk_vlan.egress_qos_map); + c = _vlan_xgress_qos_mappings_cmp(obj1->_lnk_vlan.n_ingress_qos_map, + obj1->_lnk_vlan.ingress_qos_map, + obj2->_lnk_vlan.ingress_qos_map); + if (c) + return c; + c = _vlan_xgress_qos_mappings_cmp(obj1->_lnk_vlan.n_egress_qos_map, + obj1->_lnk_vlan.egress_qos_map, + obj2->_lnk_vlan.egress_qos_map); - return c; + return c; } static int -_vt_cmd_obj_cmp_lnk_wireguard (const NMPObject *obj1, const NMPObject *obj2) +_vt_cmd_obj_cmp_lnk_wireguard(const NMPObject *obj1, const NMPObject *obj2) { - guint i; + guint i; - NM_CMP_RETURN (nm_platform_lnk_wireguard_cmp (&obj1->lnk_wireguard, &obj2->lnk_wireguard)); + NM_CMP_RETURN(nm_platform_lnk_wireguard_cmp(&obj1->lnk_wireguard, &obj2->lnk_wireguard)); - NM_CMP_FIELD (obj1, obj2, _lnk_wireguard.peers_len); + NM_CMP_FIELD(obj1, obj2, _lnk_wireguard.peers_len); - for (i = 0; i < obj1->_lnk_wireguard.peers_len; i++) - NM_CMP_RETURN (_wireguard_peer_cmp (&obj1->_lnk_wireguard.peers[i], &obj2->_lnk_wireguard.peers[i])); + for (i = 0; i < obj1->_lnk_wireguard.peers_len; i++) + NM_CMP_RETURN( + _wireguard_peer_cmp(&obj1->_lnk_wireguard.peers[i], &obj2->_lnk_wireguard.peers[i])); - return 0; + return 0; } /* @src is a const object, which is not entirely correct for link types, where @@ -1238,530 +1279,580 @@ _vt_cmd_obj_cmp_lnk_wireguard (const NMPObject *obj1, const NMPObject *obj2) * Hence, nmp_object_copy() can violate the const promise of @src. * */ void -nmp_object_copy (NMPObject *dst, const NMPObject *src, gboolean id_only) +nmp_object_copy(NMPObject *dst, const NMPObject *src, gboolean id_only) { - g_return_if_fail (NMP_OBJECT_IS_VALID (dst)); - g_return_if_fail (NMP_OBJECT_IS_VALID (src)); - g_return_if_fail (!NMP_OBJECT_IS_STACKINIT (dst)); + g_return_if_fail(NMP_OBJECT_IS_VALID(dst)); + g_return_if_fail(NMP_OBJECT_IS_VALID(src)); + g_return_if_fail(!NMP_OBJECT_IS_STACKINIT(dst)); - if (src != dst) { - const NMPClass *klass = NMP_OBJECT_GET_CLASS (dst); + if (src != dst) { + const NMPClass *klass = NMP_OBJECT_GET_CLASS(dst); - g_return_if_fail (klass == NMP_OBJECT_GET_CLASS (src)); + g_return_if_fail(klass == NMP_OBJECT_GET_CLASS(src)); - if (id_only) { - if (klass->cmd_plobj_id_copy) - klass->cmd_plobj_id_copy (&dst->object, &src->object); - } else if (klass->cmd_obj_copy) - klass->cmd_obj_copy (dst, src); - else - memcpy (&dst->object, &src->object, klass->sizeof_data); - } + if (id_only) { + if (klass->cmd_plobj_id_copy) + klass->cmd_plobj_id_copy(&dst->object, &src->object); + } else if (klass->cmd_obj_copy) + klass->cmd_obj_copy(dst, src); + else + memcpy(&dst->object, &src->object, klass->sizeof_data); + } } static void -_vt_cmd_obj_copy_link (NMPObject *dst, const NMPObject *src) -{ - if (dst->_link.udev.device != src->_link.udev.device) { - if (src->_link.udev.device) - udev_device_ref (src->_link.udev.device); - if (dst->_link.udev.device) - udev_device_unref (dst->_link.udev.device); - dst->_link.udev.device = src->_link.udev.device; - } - if (dst->_link.netlink.lnk != src->_link.netlink.lnk) { - if (src->_link.netlink.lnk) - nmp_object_ref (src->_link.netlink.lnk); - if (dst->_link.netlink.lnk) - nmp_object_unref (dst->_link.netlink.lnk); - dst->_link.netlink.lnk = src->_link.netlink.lnk; - } - if (dst->_link.ext_data != src->_link.ext_data) { - if (dst->_link.ext_data) - g_clear_object (&dst->_link.ext_data); - if (src->_link.ext_data) - dst->_link.ext_data = g_object_ref (src->_link.ext_data); - } - dst->_link = src->_link; +_vt_cmd_obj_copy_link(NMPObject *dst, const NMPObject *src) +{ + if (dst->_link.udev.device != src->_link.udev.device) { + if (src->_link.udev.device) + udev_device_ref(src->_link.udev.device); + if (dst->_link.udev.device) + udev_device_unref(dst->_link.udev.device); + dst->_link.udev.device = src->_link.udev.device; + } + if (dst->_link.netlink.lnk != src->_link.netlink.lnk) { + if (src->_link.netlink.lnk) + nmp_object_ref(src->_link.netlink.lnk); + if (dst->_link.netlink.lnk) + nmp_object_unref(dst->_link.netlink.lnk); + dst->_link.netlink.lnk = src->_link.netlink.lnk; + } + if (dst->_link.ext_data != src->_link.ext_data) { + if (dst->_link.ext_data) + g_clear_object(&dst->_link.ext_data); + if (src->_link.ext_data) + dst->_link.ext_data = g_object_ref(src->_link.ext_data); + } + dst->_link = src->_link; } static void -_vt_cmd_obj_copy_lnk_vlan (NMPObject *dst, const NMPObject *src) +_vt_cmd_obj_copy_lnk_vlan(NMPObject *dst, const NMPObject *src) { - dst->lnk_vlan = src->lnk_vlan; - _vlan_xgress_qos_mappings_cpy (&dst->_lnk_vlan.n_ingress_qos_map, - NM_UNCONST_PPTR (NMVlanQosMapping, &dst->_lnk_vlan.ingress_qos_map), - src->_lnk_vlan.n_ingress_qos_map, - src->_lnk_vlan.ingress_qos_map); - _vlan_xgress_qos_mappings_cpy (&dst->_lnk_vlan.n_egress_qos_map, - NM_UNCONST_PPTR (NMVlanQosMapping, &dst->_lnk_vlan.egress_qos_map), - src->_lnk_vlan.n_egress_qos_map, - src->_lnk_vlan.egress_qos_map); + dst->lnk_vlan = src->lnk_vlan; + _vlan_xgress_qos_mappings_cpy( + &dst->_lnk_vlan.n_ingress_qos_map, + NM_UNCONST_PPTR(NMVlanQosMapping, &dst->_lnk_vlan.ingress_qos_map), + src->_lnk_vlan.n_ingress_qos_map, + src->_lnk_vlan.ingress_qos_map); + _vlan_xgress_qos_mappings_cpy(&dst->_lnk_vlan.n_egress_qos_map, + NM_UNCONST_PPTR(NMVlanQosMapping, &dst->_lnk_vlan.egress_qos_map), + src->_lnk_vlan.n_egress_qos_map, + src->_lnk_vlan.egress_qos_map); } static void -_vt_cmd_obj_copy_lnk_wireguard (NMPObject *dst, const NMPObject *src) -{ - guint i; - - nm_assert (dst != src); - - _wireguard_clear (&dst->_lnk_wireguard); - - dst->_lnk_wireguard = src->_lnk_wireguard; - - dst->_lnk_wireguard.peers = nm_memdup (dst->_lnk_wireguard.peers, - sizeof (NMPWireGuardPeer) * dst->_lnk_wireguard.peers_len); - dst->_lnk_wireguard._allowed_ips_buf = nm_memdup (dst->_lnk_wireguard._allowed_ips_buf, - sizeof (NMPWireGuardAllowedIP) * dst->_lnk_wireguard._allowed_ips_buf_len); - - /* all the peers' pointers point into the buffer. They need to be readjusted. */ - for (i = 0; i < dst->_lnk_wireguard.peers_len; i++) { - NMPWireGuardPeer *peer = (NMPWireGuardPeer *) &dst->_lnk_wireguard.peers[i]; - - if (peer->allowed_ips_len == 0) { - nm_assert (!peer->allowed_ips); - continue; - } - nm_assert (dst->_lnk_wireguard._allowed_ips_buf_len > 0); - nm_assert (src->_lnk_wireguard._allowed_ips_buf); - nm_assert (peer->allowed_ips >= src->_lnk_wireguard._allowed_ips_buf); - nm_assert (&peer->allowed_ips[peer->allowed_ips_len] <= &src->_lnk_wireguard._allowed_ips_buf[src->_lnk_wireguard._allowed_ips_buf_len]); - - peer->allowed_ips = &dst->_lnk_wireguard._allowed_ips_buf[peer->allowed_ips - src->_lnk_wireguard._allowed_ips_buf]; - } - - nm_assert (nmp_object_equal (src, dst)); -} - -#define _vt_cmd_plobj_id_copy(type, plat_type, cmd) \ -static void \ -_vt_cmd_plobj_id_copy_##type (NMPlatformObject *_dst, const NMPlatformObject *_src) \ -{ \ - plat_type *const dst = (plat_type *) _dst; \ - const plat_type *const src = (const plat_type *) _src; \ - { cmd } \ -} -_vt_cmd_plobj_id_copy (link, NMPlatformLink, { - dst->ifindex = src->ifindex; +_vt_cmd_obj_copy_lnk_wireguard(NMPObject *dst, const NMPObject *src) +{ + guint i; + + nm_assert(dst != src); + + _wireguard_clear(&dst->_lnk_wireguard); + + dst->_lnk_wireguard = src->_lnk_wireguard; + + dst->_lnk_wireguard.peers = nm_memdup(dst->_lnk_wireguard.peers, + sizeof(NMPWireGuardPeer) * dst->_lnk_wireguard.peers_len); + dst->_lnk_wireguard._allowed_ips_buf = + nm_memdup(dst->_lnk_wireguard._allowed_ips_buf, + sizeof(NMPWireGuardAllowedIP) * dst->_lnk_wireguard._allowed_ips_buf_len); + + /* all the peers' pointers point into the buffer. They need to be readjusted. */ + for (i = 0; i < dst->_lnk_wireguard.peers_len; i++) { + NMPWireGuardPeer *peer = (NMPWireGuardPeer *) &dst->_lnk_wireguard.peers[i]; + + if (peer->allowed_ips_len == 0) { + nm_assert(!peer->allowed_ips); + continue; + } + nm_assert(dst->_lnk_wireguard._allowed_ips_buf_len > 0); + nm_assert(src->_lnk_wireguard._allowed_ips_buf); + nm_assert(peer->allowed_ips >= src->_lnk_wireguard._allowed_ips_buf); + nm_assert( + &peer->allowed_ips[peer->allowed_ips_len] + <= &src->_lnk_wireguard._allowed_ips_buf[src->_lnk_wireguard._allowed_ips_buf_len]); + + peer->allowed_ips = + &dst->_lnk_wireguard + ._allowed_ips_buf[peer->allowed_ips - src->_lnk_wireguard._allowed_ips_buf]; + } + + nm_assert(nmp_object_equal(src, dst)); +} + +#define _vt_cmd_plobj_id_copy(type, plat_type, cmd) \ + static void _vt_cmd_plobj_id_copy_##type(NMPlatformObject *_dst, const NMPlatformObject *_src) \ + { \ + plat_type *const dst = (plat_type *) _dst; \ + const plat_type *const src = (const plat_type *) _src; \ + { \ + cmd \ + } \ + } \ + struct _dummy_struct_for_tailing_semicolon + +_vt_cmd_plobj_id_copy(link, NMPlatformLink, { dst->ifindex = src->ifindex; }); + +_vt_cmd_plobj_id_copy(ip4_address, NMPlatformIP4Address, { + dst->ifindex = src->ifindex; + dst->plen = src->plen; + dst->address = src->address; + dst->peer_address = src->peer_address; }); -_vt_cmd_plobj_id_copy (ip4_address, NMPlatformIP4Address, { - dst->ifindex = src->ifindex; - dst->plen = src->plen; - dst->address = src->address; - dst->peer_address = src->peer_address; -}); -_vt_cmd_plobj_id_copy (ip6_address, NMPlatformIP6Address, { - dst->ifindex = src->ifindex; - dst->address = src->address; + +_vt_cmd_plobj_id_copy(ip6_address, NMPlatformIP6Address, { + dst->ifindex = src->ifindex; + dst->address = src->address; }); -_vt_cmd_plobj_id_copy (ip4_route, NMPlatformIP4Route, { - *dst = *src; - nm_assert (nm_platform_ip4_route_cmp (dst, src, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) == 0); + +_vt_cmd_plobj_id_copy(ip4_route, NMPlatformIP4Route, { + *dst = *src; + nm_assert(nm_platform_ip4_route_cmp(dst, src, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) == 0); }); -_vt_cmd_plobj_id_copy (ip6_route, NMPlatformIP6Route, { - *dst = *src; - nm_assert (nm_platform_ip6_route_cmp (dst, src, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) == 0); + +_vt_cmd_plobj_id_copy(ip6_route, NMPlatformIP6Route, { + *dst = *src; + nm_assert(nm_platform_ip6_route_cmp(dst, src, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) == 0); }); -_vt_cmd_plobj_id_copy (routing_rule, NMPlatformRoutingRule, { - *dst = *src; - nm_assert (nm_platform_routing_rule_cmp (dst, src, NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID) == 0); + +_vt_cmd_plobj_id_copy(routing_rule, NMPlatformRoutingRule, { + *dst = *src; + nm_assert(nm_platform_routing_rule_cmp(dst, src, NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID) == 0); }); /* Uses internally nmp_object_copy(), hence it also violates the const * promise for @obj. * */ NMPObject * -nmp_object_clone (const NMPObject *obj, gboolean id_only) +nmp_object_clone(const NMPObject *obj, gboolean id_only) { - NMPObject *dst; + NMPObject *dst; - if (!obj) - return NULL; + if (!obj) + return NULL; - g_return_val_if_fail (NMP_OBJECT_IS_VALID (obj), NULL); + g_return_val_if_fail(NMP_OBJECT_IS_VALID(obj), NULL); - dst = _nmp_object_new_from_class (NMP_OBJECT_GET_CLASS (obj)); - nmp_object_copy (dst, obj, id_only); - return dst; + dst = _nmp_object_new_from_class(NMP_OBJECT_GET_CLASS(obj)); + nmp_object_copy(dst, obj, id_only); + return dst; } int -nmp_object_id_cmp (const NMPObject *obj1, const NMPObject *obj2) -{ - const NMPClass *klass, *klass2; - - NM_CMP_SELF (obj1, obj2); - - g_return_val_if_fail (NMP_OBJECT_IS_VALID (obj1), FALSE); - g_return_val_if_fail (NMP_OBJECT_IS_VALID (obj2), FALSE); - - klass = NMP_OBJECT_GET_CLASS (obj1); - nm_assert (!klass->cmd_plobj_id_hash_update == !klass->cmd_plobj_id_cmp); - - klass2 = NMP_OBJECT_GET_CLASS (obj2); - nm_assert (klass); - if (klass != klass2) { - nm_assert (klass2); - NM_CMP_DIRECT (klass->obj_type, klass2->obj_type); - /* resort to pointer comparison */ - NM_CMP_DIRECT_PTR (klass, klass2); - return 0; - } - - if (!klass->cmd_plobj_id_cmp) { - /* the klass doesn't implement ID cmp(). That means, different objects - * never compare equal, but the cmp() according to their pointer value. */ - NM_CMP_DIRECT_PTR (obj1, obj2); - return 0; - } - - return klass->cmd_plobj_id_cmp (&obj1->object, &obj2->object); -} - -#define _vt_cmd_plobj_id_cmp(type, plat_type, cmd) \ -static int \ -_vt_cmd_plobj_id_cmp_##type (const NMPlatformObject *_obj1, const NMPlatformObject *_obj2) \ -{ \ - const plat_type *const obj1 = (const plat_type *) _obj1; \ - const plat_type *const obj2 = (const plat_type *) _obj2; \ - \ - NM_CMP_SELF (obj1, obj2); \ - { cmd; } \ - return 0; \ -} -_vt_cmd_plobj_id_cmp (link, NMPlatformLink, - NM_CMP_FIELD (obj1, obj2, ifindex); -) -_vt_cmd_plobj_id_cmp (ip4_address, NMPlatformIP4Address, - NM_CMP_FIELD (obj1, obj2, ifindex); - NM_CMP_FIELD (obj1, obj2, plen); - NM_CMP_FIELD (obj1, obj2, address); - /* for IPv4 addresses, you can add the same local address with differing peer-adddress - * (IFA_ADDRESS), provided that their net-part differs. */ - NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX (obj1->peer_address, obj2->peer_address, obj1->plen); -) -_vt_cmd_plobj_id_cmp (ip6_address, NMPlatformIP6Address, - NM_CMP_FIELD (obj1, obj2, ifindex); - /* for IPv6 addresses, the prefix length is not part of the primary identifier. */ - NM_CMP_FIELD_IN6ADDR (obj1, obj2, address); -) -_vt_cmd_plobj_id_cmp (qdisc, NMPlatformQdisc, - NM_CMP_FIELD (obj1, obj2, ifindex); - NM_CMP_FIELD (obj1, obj2, parent); -) -_vt_cmd_plobj_id_cmp (tfilter, NMPlatformTfilter, - NM_CMP_FIELD (obj1, obj2, ifindex); - NM_CMP_FIELD (obj1, obj2, handle); -) +nmp_object_id_cmp(const NMPObject *obj1, const NMPObject *obj2) +{ + const NMPClass *klass, *klass2; + + NM_CMP_SELF(obj1, obj2); + + g_return_val_if_fail(NMP_OBJECT_IS_VALID(obj1), FALSE); + g_return_val_if_fail(NMP_OBJECT_IS_VALID(obj2), FALSE); + + klass = NMP_OBJECT_GET_CLASS(obj1); + nm_assert(!klass->cmd_plobj_id_hash_update == !klass->cmd_plobj_id_cmp); + + klass2 = NMP_OBJECT_GET_CLASS(obj2); + nm_assert(klass); + if (klass != klass2) { + nm_assert(klass2); + NM_CMP_DIRECT(klass->obj_type, klass2->obj_type); + /* resort to pointer comparison */ + NM_CMP_DIRECT_PTR(klass, klass2); + return 0; + } + + if (!klass->cmd_plobj_id_cmp) { + /* the klass doesn't implement ID cmp(). That means, different objects + * never compare equal, but the cmp() according to their pointer value. */ + NM_CMP_DIRECT_PTR(obj1, obj2); + return 0; + } + + return klass->cmd_plobj_id_cmp(&obj1->object, &obj2->object); +} + +#define _vt_cmd_plobj_id_cmp(type, plat_type, cmd) \ + static int _vt_cmd_plobj_id_cmp_##type(const NMPlatformObject *_obj1, \ + const NMPlatformObject *_obj2) \ + { \ + const plat_type *const obj1 = (const plat_type *) _obj1; \ + const plat_type *const obj2 = (const plat_type *) _obj2; \ + \ + NM_CMP_SELF(obj1, obj2); \ + { \ + cmd; \ + } \ + return 0; \ + } \ + struct _dummy_struct_for_tailing_semicolon + +_vt_cmd_plobj_id_cmp(link, NMPlatformLink, { NM_CMP_FIELD(obj1, obj2, ifindex); }); + +_vt_cmd_plobj_id_cmp(ip4_address, NMPlatformIP4Address, { + NM_CMP_FIELD(obj1, obj2, ifindex); + NM_CMP_FIELD(obj1, obj2, plen); + NM_CMP_FIELD(obj1, obj2, address); + /* for IPv4 addresses, you can add the same local address with differing peer-address + * (IFA_ADDRESS), provided that their net-part differs. */ + NM_CMP_DIRECT_IN4ADDR_SAME_PREFIX(obj1->peer_address, obj2->peer_address, obj1->plen); +}); + +_vt_cmd_plobj_id_cmp(ip6_address, NMPlatformIP6Address, { + NM_CMP_FIELD(obj1, obj2, ifindex); + /* for IPv6 addresses, the prefix length is not part of the primary identifier. */ + NM_CMP_FIELD_IN6ADDR(obj1, obj2, address); +}); + +_vt_cmd_plobj_id_cmp(qdisc, NMPlatformQdisc, { + NM_CMP_FIELD(obj1, obj2, ifindex); + NM_CMP_FIELD(obj1, obj2, parent); +}); + +_vt_cmd_plobj_id_cmp(tfilter, NMPlatformTfilter, { + NM_CMP_FIELD(obj1, obj2, ifindex); + NM_CMP_FIELD(obj1, obj2, handle); +}); static int -_vt_cmd_plobj_id_cmp_ip4_route (const NMPlatformObject *obj1, const NMPlatformObject *obj2) +_vt_cmd_plobj_id_cmp_ip4_route(const NMPlatformObject *obj1, const NMPlatformObject *obj2) { - return nm_platform_ip4_route_cmp ((NMPlatformIP4Route *) obj1, (NMPlatformIP4Route *) obj2, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID); + return nm_platform_ip4_route_cmp((NMPlatformIP4Route *) obj1, + (NMPlatformIP4Route *) obj2, + NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID); } static int -_vt_cmd_plobj_id_cmp_ip6_route (const NMPlatformObject *obj1, const NMPlatformObject *obj2) +_vt_cmd_plobj_id_cmp_ip6_route(const NMPlatformObject *obj1, const NMPlatformObject *obj2) { - return nm_platform_ip6_route_cmp ((NMPlatformIP6Route *) obj1, (NMPlatformIP6Route *) obj2, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID); + return nm_platform_ip6_route_cmp((NMPlatformIP6Route *) obj1, + (NMPlatformIP6Route *) obj2, + NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID); } static int -_vt_cmd_plobj_id_cmp_routing_rule (const NMPlatformObject *obj1, const NMPlatformObject *obj2) +_vt_cmd_plobj_id_cmp_routing_rule(const NMPlatformObject *obj1, const NMPlatformObject *obj2) { - return nm_platform_routing_rule_cmp ((NMPlatformRoutingRule *) obj1, (NMPlatformRoutingRule *) obj2, NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID); + return nm_platform_routing_rule_cmp((NMPlatformRoutingRule *) obj1, + (NMPlatformRoutingRule *) obj2, + NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID); } void -nmp_object_id_hash_update (const NMPObject *obj, NMHashState *h) +nmp_object_id_hash_update(const NMPObject *obj, NMHashState *h) { - const NMPClass *klass; + const NMPClass *klass; - g_return_if_fail (NMP_OBJECT_IS_VALID (obj)); + g_return_if_fail(NMP_OBJECT_IS_VALID(obj)); - klass = NMP_OBJECT_GET_CLASS (obj); + klass = NMP_OBJECT_GET_CLASS(obj); - nm_assert (!klass->cmd_plobj_id_hash_update == !klass->cmd_plobj_id_cmp); + nm_assert(!klass->cmd_plobj_id_hash_update == !klass->cmd_plobj_id_cmp); - if (!klass->cmd_plobj_id_hash_update) { - /* The klass doesn't implement ID compare. It means, to use pointer - * equality. */ - nm_hash_update_val (h, obj); - return; - } + if (!klass->cmd_plobj_id_hash_update) { + /* The klass doesn't implement ID compare. It means, to use pointer + * equality. */ + nm_hash_update_val(h, obj); + return; + } - nm_hash_update_val (h, klass->obj_type); - klass->cmd_plobj_id_hash_update (&obj->object, h); + nm_hash_update_val(h, klass->obj_type); + klass->cmd_plobj_id_hash_update(&obj->object, h); } guint -nmp_object_id_hash (const NMPObject *obj) -{ - NMHashState h; - - if (!obj) - return nm_hash_static (914932607u); - - nm_hash_init (&h, 914932607u); - nmp_object_id_hash_update (obj, &h); - return nm_hash_complete (&h); -} - -#define _vt_cmd_plobj_id_hash_update(type, plat_type, cmd) \ -static void \ -_vt_cmd_plobj_id_hash_update_##type (const NMPlatformObject *_obj, NMHashState *h) \ -{ \ - const plat_type *const obj = (const plat_type *) _obj; \ - { cmd; } \ -} -_vt_cmd_plobj_id_hash_update (link, NMPlatformLink, { - nm_hash_update_val (h, obj->ifindex); -}) -_vt_cmd_plobj_id_hash_update (ip4_address, NMPlatformIP4Address, { - nm_hash_update_vals (h, - obj->ifindex, - obj->plen, - obj->address, - /* for IPv4 we must also consider the net-part of the peer-address (IFA_ADDRESS) */ - nm_utils_ip4_address_clear_host_address (obj->peer_address, obj->plen)); -}) -_vt_cmd_plobj_id_hash_update (ip6_address, NMPlatformIP6Address, { - nm_hash_update_vals (h, - obj->ifindex, - /* for IPv6 addresses, the prefix length is not part of the primary identifier. */ - obj->address); -}) -_vt_cmd_plobj_id_hash_update (ip4_route, NMPlatformIP4Route, { - nm_platform_ip4_route_hash_update (obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID, h); -}) -_vt_cmd_plobj_id_hash_update (ip6_route, NMPlatformIP6Route, { - nm_platform_ip6_route_hash_update (obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID, h); -}) -_vt_cmd_plobj_id_hash_update (routing_rule, NMPlatformRoutingRule, { - nm_platform_routing_rule_hash_update (obj, NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID, h); -}) -_vt_cmd_plobj_id_hash_update (qdisc, NMPlatformQdisc, { - nm_hash_update_vals (h, - obj->ifindex, - obj->parent); -}) -_vt_cmd_plobj_id_hash_update (tfilter, NMPlatformTfilter, { - nm_hash_update_vals (h, - obj->ifindex, - obj->handle); -}) +nmp_object_id_hash(const NMPObject *obj) +{ + NMHashState h; + + if (!obj) + return nm_hash_static(914932607u); + + nm_hash_init(&h, 914932607u); + nmp_object_id_hash_update(obj, &h); + return nm_hash_complete(&h); +} + +#define _vt_cmd_plobj_id_hash_update(type, plat_type, cmd) \ + static void _vt_cmd_plobj_id_hash_update_##type(const NMPlatformObject *_obj, NMHashState *h) \ + { \ + const plat_type *const obj = (const plat_type *) _obj; \ + { \ + cmd; \ + } \ + } \ + struct _dummy_struct_for_tailing_semicolon + +_vt_cmd_plobj_id_hash_update(link, NMPlatformLink, { nm_hash_update_val(h, obj->ifindex); }); + +_vt_cmd_plobj_id_hash_update(ip4_address, NMPlatformIP4Address, { + nm_hash_update_vals( + h, + obj->ifindex, + obj->plen, + obj->address, + /* for IPv4 we must also consider the net-part of the peer-address (IFA_ADDRESS) */ + nm_utils_ip4_address_clear_host_address(obj->peer_address, obj->plen)); +}); + +_vt_cmd_plobj_id_hash_update(ip6_address, NMPlatformIP6Address, { + nm_hash_update_vals( + h, + obj->ifindex, + /* for IPv6 addresses, the prefix length is not part of the primary identifier. */ + obj->address); +}); + +_vt_cmd_plobj_id_hash_update(ip4_route, NMPlatformIP4Route, { + nm_platform_ip4_route_hash_update(obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID, h); +}); + +_vt_cmd_plobj_id_hash_update(ip6_route, NMPlatformIP6Route, { + nm_platform_ip6_route_hash_update(obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID, h); +}); + +_vt_cmd_plobj_id_hash_update(routing_rule, NMPlatformRoutingRule, { + nm_platform_routing_rule_hash_update(obj, NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID, h); +}); + +_vt_cmd_plobj_id_hash_update(qdisc, NMPlatformQdisc, { + nm_hash_update_vals(h, obj->ifindex, obj->parent); +}); + +_vt_cmd_plobj_id_hash_update(tfilter, NMPlatformTfilter, { + nm_hash_update_vals(h, obj->ifindex, obj->handle); +}); static void -_vt_cmd_plobj_hash_update_ip4_route (const NMPlatformObject *obj, NMHashState *h) +_vt_cmd_plobj_hash_update_ip4_route(const NMPlatformObject *obj, NMHashState *h) { - return nm_platform_ip4_route_hash_update ((const NMPlatformIP4Route *) obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL, h); + return nm_platform_ip4_route_hash_update((const NMPlatformIP4Route *) obj, + NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL, + h); } static void -_vt_cmd_plobj_hash_update_ip6_route (const NMPlatformObject *obj, NMHashState *h) +_vt_cmd_plobj_hash_update_ip6_route(const NMPlatformObject *obj, NMHashState *h) { - return nm_platform_ip6_route_hash_update ((const NMPlatformIP6Route *) obj, NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL, h); + return nm_platform_ip6_route_hash_update((const NMPlatformIP6Route *) obj, + NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL, + h); } static void -_vt_cmd_plobj_hash_update_routing_rule (const NMPlatformObject *obj, NMHashState *h) +_vt_cmd_plobj_hash_update_routing_rule(const NMPlatformObject *obj, NMHashState *h) +{ + return nm_platform_routing_rule_hash_update((const NMPlatformRoutingRule *) obj, + NM_PLATFORM_ROUTING_RULE_CMP_TYPE_FULL, + h); +} + +guint +nmp_object_indirect_id_hash(gconstpointer a) { - return nm_platform_routing_rule_hash_update ((const NMPlatformRoutingRule *) obj, NM_PLATFORM_ROUTING_RULE_CMP_TYPE_FULL, h); + const NMPObject *const *p_obj = a; + + return nmp_object_id_hash(*p_obj); +} + +gboolean +nmp_object_indirect_id_equal(gconstpointer a, gconstpointer b) +{ + const NMPObject *const *p_obj_a = a; + const NMPObject *const *p_obj_b = b; + + return nmp_object_id_equal(*p_obj_a, *p_obj_b); } +/*****************************************************************************/ + gboolean -nmp_object_is_alive (const NMPObject *obj) +nmp_object_is_alive(const NMPObject *obj) { - const NMPClass *klass; + const NMPClass *klass; - /* for convenience, allow NULL. */ - if (!obj) - return FALSE; + /* for convenience, allow NULL. */ + if (!obj) + return FALSE; - klass = NMP_OBJECT_GET_CLASS (obj); - return !klass->cmd_obj_is_alive - || klass->cmd_obj_is_alive (obj); + klass = NMP_OBJECT_GET_CLASS(obj); + return !klass->cmd_obj_is_alive || klass->cmd_obj_is_alive(obj); } static gboolean -_vt_cmd_obj_is_alive_link (const NMPObject *obj) +_vt_cmd_obj_is_alive_link(const NMPObject *obj) { - return NMP_OBJECT_CAST_LINK (obj)->ifindex > 0 - && (obj->_link.netlink.is_in_netlink || obj->_link.udev.device); + return NMP_OBJECT_CAST_LINK(obj)->ifindex > 0 + && (obj->_link.netlink.is_in_netlink || obj->_link.udev.device); } static gboolean -_vt_cmd_obj_is_alive_ipx_address (const NMPObject *obj) +_vt_cmd_obj_is_alive_ipx_address(const NMPObject *obj) { - return NMP_OBJECT_CAST_IP_ADDRESS (obj)->ifindex > 0; + return NMP_OBJECT_CAST_IP_ADDRESS(obj)->ifindex > 0; } static gboolean -_vt_cmd_obj_is_alive_ipx_route (const NMPObject *obj) -{ - /* We want to ignore routes that are RTM_F_CLONED but we still - * let nmp_object_from_nl() create such route objects, instead of - * returning NULL right away. - * - * The idea is, that if we have the same route (according to its id) - * in the cache with !RTM_F_CLONED, an update that changes the route - * to be RTM_F_CLONED must remove the instance. - * - * If nmp_object_from_nl() would just return NULL, we couldn't look - * into the cache to see if it contains a route that now disappears - * (because it changed to be cloned). - * - * Instead we create a dead object, and nmp_cache_update_netlink() - * will remove the old version of the update. - **/ - return NMP_OBJECT_CAST_IP_ROUTE (obj)->ifindex > 0 - && !NM_FLAGS_HAS (obj->ip_route.r_rtm_flags, RTM_F_CLONED); +_vt_cmd_obj_is_alive_ipx_route(const NMPObject *obj) +{ + /* We want to ignore routes that are RTM_F_CLONED but we still + * let nmp_object_from_nl() create such route objects, instead of + * returning NULL right away. + * + * The idea is, that if we have the same route (according to its id) + * in the cache with !RTM_F_CLONED, an update that changes the route + * to be RTM_F_CLONED must remove the instance. + * + * If nmp_object_from_nl() would just return NULL, we couldn't look + * into the cache to see if it contains a route that now disappears + * (because it changed to be cloned). + * + * Instead we create a dead object, and nmp_cache_update_netlink() + * will remove the old version of the update. + **/ + return NMP_OBJECT_CAST_IP_ROUTE(obj)->ifindex > 0 + && !NM_FLAGS_HAS(obj->ip_route.r_rtm_flags, RTM_F_CLONED); } static gboolean -_vt_cmd_obj_is_alive_routing_rule (const NMPObject *obj) +_vt_cmd_obj_is_alive_routing_rule(const NMPObject *obj) { - return NM_IN_SET (obj->routing_rule.addr_family, AF_INET, AF_INET6); + return NM_IN_SET(obj->routing_rule.addr_family, AF_INET, AF_INET6); } static gboolean -_vt_cmd_obj_is_alive_qdisc (const NMPObject *obj) +_vt_cmd_obj_is_alive_qdisc(const NMPObject *obj) { - return NMP_OBJECT_CAST_QDISC (obj)->ifindex > 0; + return NMP_OBJECT_CAST_QDISC(obj)->ifindex > 0; } static gboolean -_vt_cmd_obj_is_alive_tfilter (const NMPObject *obj) +_vt_cmd_obj_is_alive_tfilter(const NMPObject *obj) { - return NMP_OBJECT_CAST_TFILTER (obj)->ifindex > 0; + return NMP_OBJECT_CAST_TFILTER(obj)->ifindex > 0; } gboolean -nmp_object_is_visible (const NMPObject *obj) +nmp_object_is_visible(const NMPObject *obj) { - const NMPClass *klass; + const NMPClass *klass; - /* for convenience, allow NULL. */ - if (!obj) - return FALSE; + /* for convenience, allow NULL. */ + if (!obj) + return FALSE; - klass = NMP_OBJECT_GET_CLASS (obj); + klass = NMP_OBJECT_GET_CLASS(obj); - /* a dead object is never visible. */ - if ( klass->cmd_obj_is_alive - && !klass->cmd_obj_is_alive (obj)) - return FALSE; + /* a dead object is never visible. */ + if (klass->cmd_obj_is_alive && !klass->cmd_obj_is_alive(obj)) + return FALSE; - return !klass->cmd_obj_is_visible - || klass->cmd_obj_is_visible (obj); + return !klass->cmd_obj_is_visible || klass->cmd_obj_is_visible(obj); } static gboolean -_vt_cmd_obj_is_visible_link (const NMPObject *obj) +_vt_cmd_obj_is_visible_link(const NMPObject *obj) { - return obj->_link.netlink.is_in_netlink - && obj->link.name[0]; + return obj->_link.netlink.is_in_netlink && obj->link.name[0]; } /*****************************************************************************/ static const guint8 _supported_cache_ids_object[] = { - NMP_CACHE_ID_TYPE_OBJECT_TYPE, - NMP_CACHE_ID_TYPE_OBJECT_BY_IFINDEX, - 0, + NMP_CACHE_ID_TYPE_OBJECT_TYPE, + NMP_CACHE_ID_TYPE_OBJECT_BY_IFINDEX, + 0, }; static const guint8 _supported_cache_ids_link[] = { - NMP_CACHE_ID_TYPE_OBJECT_TYPE, - NMP_CACHE_ID_TYPE_LINK_BY_IFNAME, - 0, + NMP_CACHE_ID_TYPE_OBJECT_TYPE, + NMP_CACHE_ID_TYPE_LINK_BY_IFNAME, + 0, }; static const guint8 _supported_cache_ids_ipx_address[] = { - NMP_CACHE_ID_TYPE_OBJECT_TYPE, - NMP_CACHE_ID_TYPE_OBJECT_BY_IFINDEX, - 0, + NMP_CACHE_ID_TYPE_OBJECT_TYPE, + NMP_CACHE_ID_TYPE_OBJECT_BY_IFINDEX, + 0, }; static const guint8 _supported_cache_ids_ipx_route[] = { - NMP_CACHE_ID_TYPE_OBJECT_TYPE, - NMP_CACHE_ID_TYPE_OBJECT_BY_IFINDEX, - NMP_CACHE_ID_TYPE_DEFAULT_ROUTES, - NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID, - 0, + NMP_CACHE_ID_TYPE_OBJECT_TYPE, + NMP_CACHE_ID_TYPE_OBJECT_BY_IFINDEX, + NMP_CACHE_ID_TYPE_DEFAULT_ROUTES, + NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID, + 0, }; static const guint8 _supported_cache_ids_routing_rules[] = { - NMP_CACHE_ID_TYPE_OBJECT_TYPE, - NMP_CACHE_ID_TYPE_OBJECT_BY_ADDR_FAMILY, - 0, + NMP_CACHE_ID_TYPE_OBJECT_TYPE, + NMP_CACHE_ID_TYPE_OBJECT_BY_ADDR_FAMILY, + 0, }; /*****************************************************************************/ static void -_vt_dedup_obj_destroy (NMDedupMultiObj *obj) +_vt_dedup_obj_destroy(NMDedupMultiObj *obj) { - NMPObject *o = (NMPObject *) obj; - const NMPClass *klass; + NMPObject * o = (NMPObject *) obj; + const NMPClass *klass; - nm_assert (o->parent._ref_count == 0); - nm_assert (!o->parent._multi_idx); + nm_assert(o->parent._ref_count == 0); + nm_assert(!o->parent._multi_idx); - klass = o->_class; - if (klass->cmd_obj_dispose) - klass->cmd_obj_dispose (o); - g_slice_free1 (klass->sizeof_data + G_STRUCT_OFFSET (NMPObject, object), o); + klass = o->_class; + if (klass->cmd_obj_dispose) + klass->cmd_obj_dispose(o); + g_slice_free1(klass->sizeof_data + G_STRUCT_OFFSET(NMPObject, object), o); } static const NMDedupMultiObj * -_vt_dedup_obj_clone (const NMDedupMultiObj *obj) +_vt_dedup_obj_clone(const NMDedupMultiObj *obj) { - return (const NMDedupMultiObj *) nmp_object_clone ((const NMPObject *) obj, FALSE); + return (const NMDedupMultiObj *) nmp_object_clone((const NMPObject *) obj, FALSE); } -#define DEDUP_MULTI_OBJ_CLASS_INIT() \ - { \ - .obj_clone = _vt_dedup_obj_clone, \ - .obj_destroy = _vt_dedup_obj_destroy, \ - .obj_full_hash_update = (void (*)(const NMDedupMultiObj *obj, NMHashState *h)) nmp_object_hash_update, \ - .obj_full_equal = (gboolean (*)(const NMDedupMultiObj *obj_a, const NMDedupMultiObj *obj_b)) nmp_object_equal, \ - } +#define DEDUP_MULTI_OBJ_CLASS_INIT() \ + { \ + .obj_clone = _vt_dedup_obj_clone, .obj_destroy = _vt_dedup_obj_destroy, \ + .obj_full_hash_update = \ + (void (*)(const NMDedupMultiObj *obj, NMHashState *h)) nmp_object_hash_update, \ + .obj_full_equal = (gboolean(*)(const NMDedupMultiObj *obj_a, \ + const NMDedupMultiObj *obj_b)) nmp_object_equal, \ + } /*****************************************************************************/ static NMDedupMultiIdxType * -_idx_type_get (const NMPCache *cache, NMPCacheIdType cache_id_type) +_idx_type_get(const NMPCache *cache, NMPCacheIdType cache_id_type) { - nm_assert (cache); - nm_assert (cache_id_type > NMP_CACHE_ID_TYPE_NONE); - nm_assert (cache_id_type <= NMP_CACHE_ID_TYPE_MAX); - nm_assert ((int) cache_id_type - 1 >= 0); - nm_assert ((int) cache_id_type - 1 < G_N_ELEMENTS (cache->idx_types)); + nm_assert(cache); + nm_assert(cache_id_type > NMP_CACHE_ID_TYPE_NONE); + nm_assert(cache_id_type <= NMP_CACHE_ID_TYPE_MAX); + nm_assert((int) cache_id_type - 1 >= 0); + nm_assert((int) cache_id_type - 1 < G_N_ELEMENTS(cache->idx_types)); - return (NMDedupMultiIdxType *) &cache->idx_types[cache_id_type - 1]; + return (NMDedupMultiIdxType *) &cache->idx_types[cache_id_type - 1]; } gboolean -nmp_cache_use_udev_get (const NMPCache *cache) +nmp_cache_use_udev_get(const NMPCache *cache) { - g_return_val_if_fail (cache, TRUE); + g_return_val_if_fail(cache, TRUE); - return cache->use_udev; + return cache->use_udev; } /*****************************************************************************/ gboolean -nmp_cache_link_connected_for_slave (int ifindex_master, const NMPObject *slave) +nmp_cache_link_connected_for_slave(int ifindex_master, const NMPObject *slave) { - nm_assert (NMP_OBJECT_GET_TYPE (slave) == NMP_OBJECT_TYPE_LINK); + nm_assert(NMP_OBJECT_GET_TYPE(slave) == NMP_OBJECT_TYPE_LINK); - return ifindex_master > 0 - && slave->link.master == ifindex_master - && slave->link.connected - && nmp_object_is_visible (slave); + return ifindex_master > 0 && slave->link.master == ifindex_master && slave->link.connected + && nmp_object_is_visible(slave); } /** @@ -1786,49 +1877,49 @@ nmp_cache_link_connected_for_slave (int ifindex_master, const NMPObject *slave) * Returns: %TRUE, if @master->link.connected should be flipped/toggled. **/ gboolean -nmp_cache_link_connected_needs_toggle (const NMPCache *cache, const NMPObject *master, const NMPObject *potential_slave, const NMPObject *ignore_slave) -{ - gboolean is_lower_up = FALSE; - - if ( !master - || NMP_OBJECT_GET_TYPE (master) != NMP_OBJECT_TYPE_LINK - || master->link.ifindex <= 0 - || !nmp_object_is_visible (master) - || !NM_IN_SET (master->link.type, NM_LINK_TYPE_BRIDGE, NM_LINK_TYPE_BOND)) - return FALSE; - - /* if native IFF_LOWER_UP is down, link.connected must also be down - * regardless of the slaves. */ - if (!NM_FLAGS_HAS (master->link.n_ifi_flags, IFF_LOWER_UP)) - return !!master->link.connected; - - if (potential_slave && NMP_OBJECT_GET_TYPE (potential_slave) != NMP_OBJECT_TYPE_LINK) - potential_slave = NULL; - - if ( potential_slave - && nmp_cache_link_connected_for_slave (master->link.ifindex, potential_slave)) - is_lower_up = TRUE; - else { - NMPLookup lookup; - NMDedupMultiIter iter; - const NMPlatformLink *link = NULL; - - nmp_cache_iter_for_each_link (&iter, - nmp_cache_lookup (cache, - nmp_lookup_init_obj_type (&lookup, - NMP_OBJECT_TYPE_LINK)), - &link) { - const NMPObject *obj = NMP_OBJECT_UP_CAST ((NMPlatformObject *) link); - - if ( (!potential_slave || potential_slave->link.ifindex != link->ifindex) - && ignore_slave != obj - && nmp_cache_link_connected_for_slave (master->link.ifindex, obj)) { - is_lower_up = TRUE; - break; - } - } - } - return !!master->link.connected != is_lower_up; +nmp_cache_link_connected_needs_toggle(const NMPCache * cache, + const NMPObject *master, + const NMPObject *potential_slave, + const NMPObject *ignore_slave) +{ + gboolean is_lower_up = FALSE; + + if (!master || NMP_OBJECT_GET_TYPE(master) != NMP_OBJECT_TYPE_LINK || master->link.ifindex <= 0 + || !nmp_object_is_visible(master) + || !NM_IN_SET(master->link.type, NM_LINK_TYPE_BRIDGE, NM_LINK_TYPE_BOND)) + return FALSE; + + /* if native IFF_LOWER_UP is down, link.connected must also be down + * regardless of the slaves. */ + if (!NM_FLAGS_HAS(master->link.n_ifi_flags, IFF_LOWER_UP)) + return !!master->link.connected; + + if (potential_slave && NMP_OBJECT_GET_TYPE(potential_slave) != NMP_OBJECT_TYPE_LINK) + potential_slave = NULL; + + if (potential_slave + && nmp_cache_link_connected_for_slave(master->link.ifindex, potential_slave)) + is_lower_up = TRUE; + else { + NMPLookup lookup; + NMDedupMultiIter iter; + const NMPlatformLink *link = NULL; + + nmp_cache_iter_for_each_link ( + &iter, + nmp_cache_lookup(cache, nmp_lookup_init_obj_type(&lookup, NMP_OBJECT_TYPE_LINK)), + &link) { + const NMPObject *obj = NMP_OBJECT_UP_CAST((NMPlatformObject *) link); + + if ((!potential_slave || potential_slave->link.ifindex != link->ifindex) + && ignore_slave != obj + && nmp_cache_link_connected_for_slave(master->link.ifindex, obj)) { + is_lower_up = TRUE; + break; + } + } + } + return !!master->link.connected != is_lower_up; } /** @@ -1851,703 +1942,683 @@ nmp_cache_link_connected_needs_toggle (const NMPCache *cache, const NMPObject *m * The connected flag of that master should be toggled. */ const NMPObject * -nmp_cache_link_connected_needs_toggle_by_ifindex (const NMPCache *cache, int master_ifindex, const NMPObject *potential_slave, const NMPObject *ignore_slave) +nmp_cache_link_connected_needs_toggle_by_ifindex(const NMPCache * cache, + int master_ifindex, + const NMPObject *potential_slave, + const NMPObject *ignore_slave) { - const NMPObject *master; + const NMPObject *master; - if (master_ifindex > 0) { - master = nmp_cache_lookup_link (cache, master_ifindex); - if (nmp_cache_link_connected_needs_toggle (cache, master, potential_slave, ignore_slave)) - return master; - } - return NULL; + if (master_ifindex > 0) { + master = nmp_cache_lookup_link(cache, master_ifindex); + if (nmp_cache_link_connected_needs_toggle(cache, master, potential_slave, ignore_slave)) + return master; + } + return NULL; } /*****************************************************************************/ static const NMDedupMultiEntry * -_lookup_entry_with_idx_type (const NMPCache *cache, - NMPCacheIdType cache_id_type, - const NMPObject *obj) +_lookup_entry_with_idx_type(const NMPCache * cache, + NMPCacheIdType cache_id_type, + const NMPObject *obj) { - const NMDedupMultiEntry *entry; + const NMDedupMultiEntry *entry; - nm_assert (cache); - nm_assert (NMP_OBJECT_IS_VALID (obj)); + nm_assert(cache); + nm_assert(NMP_OBJECT_IS_VALID(obj)); - entry = nm_dedup_multi_index_lookup_obj (cache->multi_idx, - _idx_type_get (cache, cache_id_type), - obj); - nm_assert (!entry - || ( NMP_OBJECT_IS_VALID (entry->obj) - && NMP_OBJECT_GET_CLASS (entry->obj) == NMP_OBJECT_GET_CLASS (obj))); - return entry; + entry = + nm_dedup_multi_index_lookup_obj(cache->multi_idx, _idx_type_get(cache, cache_id_type), obj); + nm_assert(!entry + || (NMP_OBJECT_IS_VALID(entry->obj) + && NMP_OBJECT_GET_CLASS(entry->obj) == NMP_OBJECT_GET_CLASS(obj))); + return entry; } static const NMDedupMultiEntry * -_lookup_entry (const NMPCache *cache, const NMPObject *obj) +_lookup_entry(const NMPCache *cache, const NMPObject *obj) { - return _lookup_entry_with_idx_type (cache, NMP_CACHE_ID_TYPE_OBJECT_TYPE, obj); + return _lookup_entry_with_idx_type(cache, NMP_CACHE_ID_TYPE_OBJECT_TYPE, obj); } const NMDedupMultiEntry * -nmp_cache_lookup_entry_with_idx_type (const NMPCache *cache, - NMPCacheIdType cache_id_type, - const NMPObject *obj) +nmp_cache_lookup_entry_with_idx_type(const NMPCache * cache, + NMPCacheIdType cache_id_type, + const NMPObject *obj) { - g_return_val_if_fail (cache, NULL); - g_return_val_if_fail (obj, NULL); - g_return_val_if_fail (cache_id_type > NMP_CACHE_ID_TYPE_NONE && cache_id_type <= NMP_CACHE_ID_TYPE_MAX, NULL); + g_return_val_if_fail(cache, NULL); + g_return_val_if_fail(obj, NULL); + g_return_val_if_fail(cache_id_type > NMP_CACHE_ID_TYPE_NONE + && cache_id_type <= NMP_CACHE_ID_TYPE_MAX, + NULL); - return _lookup_entry_with_idx_type (cache, cache_id_type, obj); + return _lookup_entry_with_idx_type(cache, cache_id_type, obj); } const NMDedupMultiEntry * -nmp_cache_lookup_entry (const NMPCache *cache, const NMPObject *obj) +nmp_cache_lookup_entry(const NMPCache *cache, const NMPObject *obj) { - g_return_val_if_fail (cache, NULL); - g_return_val_if_fail (obj, NULL); + g_return_val_if_fail(cache, NULL); + g_return_val_if_fail(obj, NULL); - return _lookup_entry (cache, obj); + return _lookup_entry(cache, obj); } const NMDedupMultiEntry * -nmp_cache_lookup_entry_link (const NMPCache *cache, int ifindex) +nmp_cache_lookup_entry_link(const NMPCache *cache, int ifindex) { - NMPObject obj_needle; + NMPObject obj_needle; - g_return_val_if_fail (cache, NULL); - g_return_val_if_fail (ifindex > 0, NULL); + g_return_val_if_fail(cache, NULL); + g_return_val_if_fail(ifindex > 0, NULL); - nmp_object_stackinit_id_link (&obj_needle, ifindex); - return _lookup_entry (cache, &obj_needle); + nmp_object_stackinit_id_link(&obj_needle, ifindex); + return _lookup_entry(cache, &obj_needle); } const NMPObject * -nmp_cache_lookup_obj (const NMPCache *cache, const NMPObject *obj) +nmp_cache_lookup_obj(const NMPCache *cache, const NMPObject *obj) { - return nm_dedup_multi_entry_get_obj (nmp_cache_lookup_entry (cache, obj)); + return nm_dedup_multi_entry_get_obj(nmp_cache_lookup_entry(cache, obj)); } const NMPObject * -nmp_cache_lookup_link (const NMPCache *cache, int ifindex) +nmp_cache_lookup_link(const NMPCache *cache, int ifindex) { - return nm_dedup_multi_entry_get_obj (nmp_cache_lookup_entry_link (cache, ifindex)); + return nm_dedup_multi_entry_get_obj(nmp_cache_lookup_entry_link(cache, ifindex)); } /*****************************************************************************/ const NMDedupMultiHeadEntry * -nmp_cache_lookup_all (const NMPCache *cache, - NMPCacheIdType cache_id_type, - const NMPObject *select_obj) +nmp_cache_lookup_all(const NMPCache * cache, + NMPCacheIdType cache_id_type, + const NMPObject *select_obj) { - nm_assert (cache); - nm_assert (NMP_OBJECT_IS_VALID (select_obj)); + nm_assert(cache); + nm_assert(NMP_OBJECT_IS_VALID(select_obj)); - return nm_dedup_multi_index_lookup_head (cache->multi_idx, - _idx_type_get (cache, cache_id_type), - select_obj); + return nm_dedup_multi_index_lookup_head(cache->multi_idx, + _idx_type_get(cache, cache_id_type), + select_obj); } static const NMPLookup * -_L (const NMPLookup *lookup) +_L(const NMPLookup *lookup) { #if NM_MORE_ASSERTS - DedupMultiIdxType idx_type; + DedupMultiIdxType idx_type; - nm_assert (lookup); - _dedup_multi_idx_type_init (&idx_type, lookup->cache_id_type); - nm_assert (idx_type.parent.klass->idx_obj_partitionable ((NMDedupMultiIdxType *) &idx_type, (NMDedupMultiObj *) &lookup->selector_obj)); + nm_assert(lookup); + _dedup_multi_idx_type_init(&idx_type, lookup->cache_id_type); + nm_assert( + idx_type.parent.klass->idx_obj_partitionable((NMDedupMultiIdxType *) &idx_type, + (NMDedupMultiObj *) &lookup->selector_obj)); #endif - return lookup; + return lookup; } const NMPLookup * -nmp_lookup_init_obj_type (NMPLookup *lookup, - NMPObjectType obj_type) -{ - nm_assert (lookup); - - switch (obj_type) { - case NMP_OBJECT_TYPE_LINK: - case NMP_OBJECT_TYPE_IP4_ADDRESS: - case NMP_OBJECT_TYPE_IP6_ADDRESS: - case NMP_OBJECT_TYPE_IP4_ROUTE: - case NMP_OBJECT_TYPE_IP6_ROUTE: - case NMP_OBJECT_TYPE_ROUTING_RULE: - case NMP_OBJECT_TYPE_QDISC: - case NMP_OBJECT_TYPE_TFILTER: - _nmp_object_stackinit_from_type (&lookup->selector_obj, obj_type); - lookup->cache_id_type = NMP_CACHE_ID_TYPE_OBJECT_TYPE; - return _L (lookup); - default: - nm_assert_not_reached (); - return NULL; - } +nmp_lookup_init_obj_type(NMPLookup *lookup, NMPObjectType obj_type) +{ + nm_assert(lookup); + + switch (obj_type) { + case NMP_OBJECT_TYPE_LINK: + case NMP_OBJECT_TYPE_IP4_ADDRESS: + case NMP_OBJECT_TYPE_IP6_ADDRESS: + case NMP_OBJECT_TYPE_IP4_ROUTE: + case NMP_OBJECT_TYPE_IP6_ROUTE: + case NMP_OBJECT_TYPE_ROUTING_RULE: + case NMP_OBJECT_TYPE_QDISC: + case NMP_OBJECT_TYPE_TFILTER: + _nmp_object_stackinit_from_type(&lookup->selector_obj, obj_type); + lookup->cache_id_type = NMP_CACHE_ID_TYPE_OBJECT_TYPE; + return _L(lookup); + default: + nm_assert_not_reached(); + return NULL; + } } const NMPLookup * -nmp_lookup_init_link_by_ifname (NMPLookup *lookup, - const char *ifname) +nmp_lookup_init_link_by_ifname(NMPLookup *lookup, const char *ifname) { - NMPObject *o; + NMPObject *o; - nm_assert (lookup); - nm_assert (ifname); - nm_assert (strlen (ifname) < IFNAMSIZ); + nm_assert(lookup); + nm_assert(ifname); + nm_assert(strlen(ifname) < IFNAMSIZ); - o = _nmp_object_stackinit_from_type (&lookup->selector_obj, NMP_OBJECT_TYPE_LINK); - if (g_strlcpy (o->link.name, ifname, sizeof (o->link.name)) >= sizeof (o->link.name)) - g_return_val_if_reached (NULL); - lookup->cache_id_type = NMP_CACHE_ID_TYPE_LINK_BY_IFNAME; - return _L (lookup); + o = _nmp_object_stackinit_from_type(&lookup->selector_obj, NMP_OBJECT_TYPE_LINK); + if (g_strlcpy(o->link.name, ifname, sizeof(o->link.name)) >= sizeof(o->link.name)) + g_return_val_if_reached(NULL); + lookup->cache_id_type = NMP_CACHE_ID_TYPE_LINK_BY_IFNAME; + return _L(lookup); } const NMPLookup * -nmp_lookup_init_object (NMPLookup *lookup, - NMPObjectType obj_type, - int ifindex) +nmp_lookup_init_object(NMPLookup *lookup, NMPObjectType obj_type, int ifindex) { - NMPObject *o; + NMPObject *o; - nm_assert (lookup); - nm_assert (NM_IN_SET (obj_type, NMP_OBJECT_TYPE_IP4_ADDRESS, - NMP_OBJECT_TYPE_IP6_ADDRESS, - NMP_OBJECT_TYPE_IP4_ROUTE, - NMP_OBJECT_TYPE_IP6_ROUTE, - NMP_OBJECT_TYPE_QDISC, - NMP_OBJECT_TYPE_TFILTER)); + nm_assert(lookup); + nm_assert(NM_IN_SET(obj_type, + NMP_OBJECT_TYPE_IP4_ADDRESS, + NMP_OBJECT_TYPE_IP6_ADDRESS, + NMP_OBJECT_TYPE_IP4_ROUTE, + NMP_OBJECT_TYPE_IP6_ROUTE, + NMP_OBJECT_TYPE_QDISC, + NMP_OBJECT_TYPE_TFILTER)); - if (ifindex <= 0) { - return nmp_lookup_init_obj_type (lookup, - obj_type); - } + if (ifindex <= 0) { + return nmp_lookup_init_obj_type(lookup, obj_type); + } - o = _nmp_object_stackinit_from_type (&lookup->selector_obj, obj_type); - o->obj_with_ifindex.ifindex = ifindex; - lookup->cache_id_type = NMP_CACHE_ID_TYPE_OBJECT_BY_IFINDEX; - return _L (lookup); + o = _nmp_object_stackinit_from_type(&lookup->selector_obj, obj_type); + o->obj_with_ifindex.ifindex = ifindex; + lookup->cache_id_type = NMP_CACHE_ID_TYPE_OBJECT_BY_IFINDEX; + return _L(lookup); } const NMPLookup * -nmp_lookup_init_route_default (NMPLookup *lookup, - NMPObjectType obj_type) +nmp_lookup_init_route_default(NMPLookup *lookup, NMPObjectType obj_type) { - NMPObject *o; + NMPObject *o; - nm_assert (lookup); - nm_assert (NM_IN_SET (obj_type, NMP_OBJECT_TYPE_IP4_ROUTE, - NMP_OBJECT_TYPE_IP6_ROUTE)); + nm_assert(lookup); + nm_assert(NM_IN_SET(obj_type, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE)); - o = _nmp_object_stackinit_from_type (&lookup->selector_obj, obj_type); - o->ip_route.ifindex = 1; - lookup->cache_id_type = NMP_CACHE_ID_TYPE_DEFAULT_ROUTES; - return _L (lookup); + o = _nmp_object_stackinit_from_type(&lookup->selector_obj, obj_type); + o->ip_route.ifindex = 1; + lookup->cache_id_type = NMP_CACHE_ID_TYPE_DEFAULT_ROUTES; + return _L(lookup); } const NMPLookup * -nmp_lookup_init_route_by_weak_id (NMPLookup *lookup, - const NMPObject *obj) -{ - const NMPlatformIP4Route *r4; - const NMPlatformIP6Route *r6; - - nm_assert (lookup); - - switch (NMP_OBJECT_GET_TYPE (obj)) { - case NMP_OBJECT_TYPE_IP4_ROUTE: - r4 = NMP_OBJECT_CAST_IP4_ROUTE (obj); - return nmp_lookup_init_ip4_route_by_weak_id (lookup, - r4->network, - r4->plen, - r4->metric, - r4->tos); - case NMP_OBJECT_TYPE_IP6_ROUTE: - r6 = NMP_OBJECT_CAST_IP6_ROUTE (obj); - return nmp_lookup_init_ip6_route_by_weak_id (lookup, - &r6->network, - r6->plen, - r6->metric, - &r6->src, - r6->src_plen); - default: - nm_assert_not_reached (); - return NULL; - } +nmp_lookup_init_route_by_weak_id(NMPLookup *lookup, const NMPObject *obj) +{ + const NMPlatformIP4Route *r4; + const NMPlatformIP6Route *r6; + + nm_assert(lookup); + + switch (NMP_OBJECT_GET_TYPE(obj)) { + case NMP_OBJECT_TYPE_IP4_ROUTE: + r4 = NMP_OBJECT_CAST_IP4_ROUTE(obj); + return nmp_lookup_init_ip4_route_by_weak_id(lookup, + r4->network, + r4->plen, + r4->metric, + r4->tos); + case NMP_OBJECT_TYPE_IP6_ROUTE: + r6 = NMP_OBJECT_CAST_IP6_ROUTE(obj); + return nmp_lookup_init_ip6_route_by_weak_id(lookup, + &r6->network, + r6->plen, + r6->metric, + &r6->src, + r6->src_plen); + default: + nm_assert_not_reached(); + return NULL; + } } const NMPLookup * -nmp_lookup_init_ip4_route_by_weak_id (NMPLookup *lookup, - in_addr_t network, - guint plen, - guint32 metric, - guint8 tos) +nmp_lookup_init_ip4_route_by_weak_id(NMPLookup *lookup, + in_addr_t network, + guint plen, + guint32 metric, + guint8 tos) { - NMPObject *o; + NMPObject *o; - nm_assert (lookup); + nm_assert(lookup); - o = _nmp_object_stackinit_from_type (&lookup->selector_obj, NMP_OBJECT_TYPE_IP4_ROUTE); - o->ip4_route.ifindex = 1; - o->ip4_route.plen = plen; - o->ip4_route.metric = metric; - if (network) - o->ip4_route.network = network; - o->ip4_route.tos = tos; - lookup->cache_id_type = NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID; - return _L (lookup); + o = _nmp_object_stackinit_from_type(&lookup->selector_obj, NMP_OBJECT_TYPE_IP4_ROUTE); + o->ip4_route.ifindex = 1; + o->ip4_route.plen = plen; + o->ip4_route.metric = metric; + if (network) + o->ip4_route.network = network; + o->ip4_route.tos = tos; + lookup->cache_id_type = NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID; + return _L(lookup); } const NMPLookup * -nmp_lookup_init_ip6_route_by_weak_id (NMPLookup *lookup, - const struct in6_addr *network, - guint plen, - guint32 metric, - const struct in6_addr *src, - guint8 src_plen) -{ - NMPObject *o; - - nm_assert (lookup); - - o = _nmp_object_stackinit_from_type (&lookup->selector_obj, NMP_OBJECT_TYPE_IP6_ROUTE); - o->ip6_route.ifindex = 1; - o->ip6_route.plen = plen; - o->ip6_route.metric = metric; - if (network) - o->ip6_route.network = *network; - if (src) - o->ip6_route.src = *src; - o->ip6_route.src_plen = src_plen; - lookup->cache_id_type = NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID; - return _L (lookup); +nmp_lookup_init_ip6_route_by_weak_id(NMPLookup * lookup, + const struct in6_addr *network, + guint plen, + guint32 metric, + const struct in6_addr *src, + guint8 src_plen) +{ + NMPObject *o; + + nm_assert(lookup); + + o = _nmp_object_stackinit_from_type(&lookup->selector_obj, NMP_OBJECT_TYPE_IP6_ROUTE); + o->ip6_route.ifindex = 1; + o->ip6_route.plen = plen; + o->ip6_route.metric = metric; + if (network) + o->ip6_route.network = *network; + if (src) + o->ip6_route.src = *src; + o->ip6_route.src_plen = src_plen; + lookup->cache_id_type = NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID; + return _L(lookup); } const NMPLookup * -nmp_lookup_init_object_by_addr_family (NMPLookup *lookup, - NMPObjectType obj_type, - int addr_family) +nmp_lookup_init_object_by_addr_family(NMPLookup *lookup, NMPObjectType obj_type, int addr_family) { - NMPObject *o; + NMPObject *o; - nm_assert (lookup); - nm_assert (NM_IN_SET (obj_type, NMP_OBJECT_TYPE_ROUTING_RULE)); + nm_assert(lookup); + nm_assert(NM_IN_SET(obj_type, NMP_OBJECT_TYPE_ROUTING_RULE)); - if (addr_family == AF_UNSPEC) - return nmp_lookup_init_obj_type (lookup, obj_type); + if (addr_family == AF_UNSPEC) + return nmp_lookup_init_obj_type(lookup, obj_type); - nm_assert_addr_family (addr_family); - o = _nmp_object_stackinit_from_type (&lookup->selector_obj, obj_type); - NMP_OBJECT_CAST_ROUTING_RULE (o)->addr_family = addr_family; - lookup->cache_id_type = NMP_CACHE_ID_TYPE_OBJECT_BY_ADDR_FAMILY; - return _L (lookup); + nm_assert_addr_family(addr_family); + o = _nmp_object_stackinit_from_type(&lookup->selector_obj, obj_type); + NMP_OBJECT_CAST_ROUTING_RULE(o)->addr_family = addr_family; + lookup->cache_id_type = NMP_CACHE_ID_TYPE_OBJECT_BY_ADDR_FAMILY; + return _L(lookup); } /*****************************************************************************/ GArray * -nmp_cache_lookup_to_array (const NMDedupMultiHeadEntry *head_entry, - NMPObjectType obj_type, - gboolean visible_only) -{ - const NMPClass *klass = nmp_class_from_type (obj_type); - NMDedupMultiIter iter; - const NMPObject *o; - GArray *array; - - g_return_val_if_fail (klass, NULL); - - array = g_array_sized_new (FALSE, FALSE, - klass->sizeof_public, - head_entry ? head_entry->len : 0); - nmp_cache_iter_for_each (&iter, - head_entry, - &o) { - nm_assert (NMP_OBJECT_GET_CLASS (o) == klass); - if ( visible_only - && !nmp_object_is_visible (o)) - continue; - g_array_append_vals (array, &o->object, 1); - } - return array; +nmp_cache_lookup_to_array(const NMDedupMultiHeadEntry *head_entry, + NMPObjectType obj_type, + gboolean visible_only) +{ + const NMPClass * klass = nmp_class_from_type(obj_type); + NMDedupMultiIter iter; + const NMPObject *o; + GArray * array; + + g_return_val_if_fail(klass, NULL); + + array = g_array_sized_new(FALSE, FALSE, klass->sizeof_public, head_entry ? head_entry->len : 0); + nmp_cache_iter_for_each (&iter, head_entry, &o) { + nm_assert(NMP_OBJECT_GET_CLASS(o) == klass); + if (visible_only && !nmp_object_is_visible(o)) + continue; + g_array_append_vals(array, &o->object, 1); + } + return array; } /*****************************************************************************/ const NMPObject * -nmp_cache_lookup_link_full (const NMPCache *cache, - int ifindex, - const char *ifname, - gboolean visible_only, - NMLinkType link_type, - NMPObjectMatchFn match_fn, - gpointer user_data) -{ - NMPObject obj_needle; - const NMPObject *obj; - NMDedupMultiIter iter; - const NMDedupMultiHeadEntry *head_entry; - const NMPlatformLink *link = NULL; - NMPLookup lookup; - - if (ifindex > 0) { - obj = nmp_cache_lookup_obj (cache, nmp_object_stackinit_id_link (&obj_needle, ifindex)); - - if ( !obj - || (visible_only && !nmp_object_is_visible (obj)) - || (link_type != NM_LINK_TYPE_NONE && obj->link.type != link_type) - || (ifname && strcmp (obj->link.name, ifname)) - || (match_fn && !match_fn (obj, user_data))) - return NULL; - return obj; - } else if (!ifname && !match_fn) - return NULL; - else { - const NMPObject *obj_best = NULL; - - if (ifname) { - if (strlen (ifname) >= IFNAMSIZ) - return NULL; - nmp_lookup_init_link_by_ifname (&lookup, ifname); - } else - nmp_lookup_init_obj_type (&lookup, NMP_OBJECT_TYPE_LINK); - - head_entry = nmp_cache_lookup (cache, &lookup); - nmp_cache_iter_for_each_link (&iter, head_entry, &link) { - obj = NMP_OBJECT_UP_CAST (link); - - if (link_type != NM_LINK_TYPE_NONE && obj->link.type != link_type) - continue; - if (visible_only && !nmp_object_is_visible (obj)) - continue; - if (match_fn && !match_fn (obj, user_data)) - continue; - - /* if there are multiple candidates, prefer the visible ones. */ - if ( visible_only - || nmp_object_is_visible (obj)) - return obj; - if (!obj_best) - obj_best = obj; - } - return obj_best; - } +nmp_cache_lookup_link_full(const NMPCache * cache, + int ifindex, + const char * ifname, + gboolean visible_only, + NMLinkType link_type, + NMPObjectMatchFn match_fn, + gpointer user_data) +{ + NMPObject obj_needle; + const NMPObject * obj; + NMDedupMultiIter iter; + const NMDedupMultiHeadEntry *head_entry; + const NMPlatformLink * link = NULL; + NMPLookup lookup; + + if (ifindex > 0) { + obj = nmp_cache_lookup_obj(cache, nmp_object_stackinit_id_link(&obj_needle, ifindex)); + + if (!obj || (visible_only && !nmp_object_is_visible(obj)) + || (link_type != NM_LINK_TYPE_NONE && obj->link.type != link_type) + || (ifname && strcmp(obj->link.name, ifname)) + || (match_fn && !match_fn(obj, user_data))) + return NULL; + return obj; + } else if (!ifname && !match_fn) + return NULL; + else { + const NMPObject *obj_best = NULL; + + if (ifname) { + if (strlen(ifname) >= IFNAMSIZ) + return NULL; + nmp_lookup_init_link_by_ifname(&lookup, ifname); + } else + nmp_lookup_init_obj_type(&lookup, NMP_OBJECT_TYPE_LINK); + + head_entry = nmp_cache_lookup(cache, &lookup); + nmp_cache_iter_for_each_link (&iter, head_entry, &link) { + obj = NMP_OBJECT_UP_CAST(link); + + if (link_type != NM_LINK_TYPE_NONE && obj->link.type != link_type) + continue; + if (visible_only && !nmp_object_is_visible(obj)) + continue; + if (match_fn && !match_fn(obj, user_data)) + continue; + + /* if there are multiple candidates, prefer the visible ones. */ + if (visible_only || nmp_object_is_visible(obj)) + return obj; + if (!obj_best) + obj_best = obj; + } + return obj_best; + } } /*****************************************************************************/ static NMDedupMultiIdxMode -_obj_get_add_mode (const NMPObject *obj) -{ - /* new objects are usually appended to the list. Except for - * addresses, which are prepended during `ip address add`. - * - * Actually, for routes it is more complicated, because depending on - * `ip route append`, `ip route replace`, `ip route prepend`, the object - * will be added at the tail, at the front, or even replace an element - * in the list. However, that is handled separately by nmp_cache_update_netlink_route() - * and of no concern here. */ - if (NM_IN_SET (NMP_OBJECT_GET_TYPE (obj), - NMP_OBJECT_TYPE_IP4_ADDRESS, - NMP_OBJECT_TYPE_IP6_ADDRESS)) - return NM_DEDUP_MULTI_IDX_MODE_PREPEND; - return NM_DEDUP_MULTI_IDX_MODE_APPEND; +_obj_get_add_mode(const NMPObject *obj) +{ + /* new objects are usually appended to the list. Except for + * addresses, which are prepended during `ip address add`. + * + * Actually, for routes it is more complicated, because depending on + * `ip route append`, `ip route replace`, `ip route prepend`, the object + * will be added at the tail, at the front, or even replace an element + * in the list. However, that is handled separately by nmp_cache_update_netlink_route() + * and of no concern here. */ + if (NM_IN_SET(NMP_OBJECT_GET_TYPE(obj), + NMP_OBJECT_TYPE_IP4_ADDRESS, + NMP_OBJECT_TYPE_IP6_ADDRESS)) + return NM_DEDUP_MULTI_IDX_MODE_PREPEND; + return NM_DEDUP_MULTI_IDX_MODE_APPEND; } static void -_idxcache_update_order_for_dump (NMPCache *cache, - const NMDedupMultiEntry *entry) +_idxcache_update_order_for_dump(NMPCache *cache, const NMDedupMultiEntry *entry) { - const NMPClass *klass; - const guint8 *i_idx_type; - const NMDedupMultiEntry *entry2; + const NMPClass * klass; + const guint8 * i_idx_type; + const NMDedupMultiEntry *entry2; - nm_dedup_multi_entry_reorder (entry, NULL, TRUE); + nm_dedup_multi_entry_reorder(entry, NULL, TRUE); - klass = NMP_OBJECT_GET_CLASS (entry->obj); - for (i_idx_type = klass->supported_cache_ids; *i_idx_type; i_idx_type++) { - NMPCacheIdType id_type = *i_idx_type; + klass = NMP_OBJECT_GET_CLASS(entry->obj); + for (i_idx_type = klass->supported_cache_ids; *i_idx_type; i_idx_type++) { + NMPCacheIdType id_type = *i_idx_type; - if (id_type == NMP_CACHE_ID_TYPE_OBJECT_TYPE) - continue; + if (id_type == NMP_CACHE_ID_TYPE_OBJECT_TYPE) + continue; - entry2 = nm_dedup_multi_index_lookup_obj (cache->multi_idx, - _idx_type_get (cache, id_type), - entry->obj); - if (!entry2) - continue; + entry2 = nm_dedup_multi_index_lookup_obj(cache->multi_idx, + _idx_type_get(cache, id_type), + entry->obj); + if (!entry2) + continue; - nm_assert (entry2 != entry); - nm_assert (entry2->obj == entry->obj); + nm_assert(entry2 != entry); + nm_assert(entry2->obj == entry->obj); - nm_dedup_multi_entry_reorder (entry2, NULL, TRUE); - } + nm_dedup_multi_entry_reorder(entry2, NULL, TRUE); + } } static void -_idxcache_update_other_cache_ids (NMPCache *cache, - NMPCacheIdType cache_id_type, - const NMPObject *obj_old, - const NMPObject *obj_new, - gboolean is_dump) -{ - const NMDedupMultiEntry *entry_new; - const NMDedupMultiEntry *entry_old; - const NMDedupMultiEntry *entry_order; - NMDedupMultiIdxType *idx_type; - - nm_assert (obj_new || obj_old); - nm_assert (!obj_new || NMP_OBJECT_GET_TYPE (obj_new) != NMP_OBJECT_TYPE_UNKNOWN); - nm_assert (!obj_old || NMP_OBJECT_GET_TYPE (obj_old) != NMP_OBJECT_TYPE_UNKNOWN); - nm_assert (!obj_old || !obj_new || NMP_OBJECT_GET_CLASS (obj_new) == NMP_OBJECT_GET_CLASS (obj_old)); - nm_assert (!obj_old || !obj_new || !nmp_object_equal (obj_new, obj_old)); - nm_assert (!obj_new || obj_new == nm_dedup_multi_index_obj_find (cache->multi_idx, obj_new)); - nm_assert (!obj_old || obj_old == nm_dedup_multi_index_obj_find (cache->multi_idx, obj_old)); - - idx_type = _idx_type_get (cache, cache_id_type); - - if (obj_old) { - entry_old = nm_dedup_multi_index_lookup_obj (cache->multi_idx, - idx_type, - obj_old); - if (!obj_new) { - if (entry_old) - nm_dedup_multi_index_remove_entry (cache->multi_idx, entry_old); - return; - } - } else - entry_old = NULL; - - if (obj_new) { - if ( obj_old - && nm_dedup_multi_idx_type_id_equal (idx_type, obj_old, obj_new) - && nm_dedup_multi_idx_type_partition_equal (idx_type, obj_old, obj_new)) { - /* optimize. We just looked up the @obj_old entry and @obj_new compares equal - * according to idx_obj_id_equal(). entry_new is the same as entry_old. */ - entry_new = entry_old; - } else { - entry_new = nm_dedup_multi_index_lookup_obj (cache->multi_idx, - idx_type, - obj_new); - } - - if (entry_new) - entry_order = entry_new; - else if ( entry_old - && nm_dedup_multi_idx_type_partition_equal (idx_type, entry_old->obj, obj_new)) - entry_order = entry_old; - else - entry_order = NULL; - nm_dedup_multi_index_add_full (cache->multi_idx, - idx_type, - obj_new, - is_dump - ? NM_DEDUP_MULTI_IDX_MODE_APPEND_FORCE - : _obj_get_add_mode (obj_new), - is_dump - ? NULL - : entry_order, - entry_new ?: NM_DEDUP_MULTI_ENTRY_MISSING, - entry_new ? entry_new->head : (entry_order ? entry_order->head : NULL), - &entry_new, - NULL); +_idxcache_update_other_cache_ids(NMPCache * cache, + NMPCacheIdType cache_id_type, + const NMPObject *obj_old, + const NMPObject *obj_new, + gboolean is_dump) +{ + const NMDedupMultiEntry *entry_new; + const NMDedupMultiEntry *entry_old; + const NMDedupMultiEntry *entry_order; + NMDedupMultiIdxType * idx_type; + + nm_assert(obj_new || obj_old); + nm_assert(!obj_new || NMP_OBJECT_GET_TYPE(obj_new) != NMP_OBJECT_TYPE_UNKNOWN); + nm_assert(!obj_old || NMP_OBJECT_GET_TYPE(obj_old) != NMP_OBJECT_TYPE_UNKNOWN); + nm_assert(!obj_old || !obj_new + || NMP_OBJECT_GET_CLASS(obj_new) == NMP_OBJECT_GET_CLASS(obj_old)); + nm_assert(!obj_old || !obj_new || !nmp_object_equal(obj_new, obj_old)); + nm_assert(!obj_new || obj_new == nm_dedup_multi_index_obj_find(cache->multi_idx, obj_new)); + nm_assert(!obj_old || obj_old == nm_dedup_multi_index_obj_find(cache->multi_idx, obj_old)); + + idx_type = _idx_type_get(cache, cache_id_type); + + if (obj_old) { + entry_old = nm_dedup_multi_index_lookup_obj(cache->multi_idx, idx_type, obj_old); + if (!obj_new) { + if (entry_old) + nm_dedup_multi_index_remove_entry(cache->multi_idx, entry_old); + return; + } + } else + entry_old = NULL; + + if (obj_new) { + if (obj_old && nm_dedup_multi_idx_type_id_equal(idx_type, obj_old, obj_new) + && nm_dedup_multi_idx_type_partition_equal(idx_type, obj_old, obj_new)) { + /* optimize. We just looked up the @obj_old entry and @obj_new compares equal + * according to idx_obj_id_equal(). entry_new is the same as entry_old. */ + entry_new = entry_old; + } else { + entry_new = nm_dedup_multi_index_lookup_obj(cache->multi_idx, idx_type, obj_new); + } + + if (entry_new) + entry_order = entry_new; + else if (entry_old + && nm_dedup_multi_idx_type_partition_equal(idx_type, entry_old->obj, obj_new)) + entry_order = entry_old; + else + entry_order = NULL; + nm_dedup_multi_index_add_full( + cache->multi_idx, + idx_type, + obj_new, + is_dump ? NM_DEDUP_MULTI_IDX_MODE_APPEND_FORCE : _obj_get_add_mode(obj_new), + is_dump ? NULL : entry_order, + entry_new ?: NM_DEDUP_MULTI_ENTRY_MISSING, + entry_new ? entry_new->head : (entry_order ? entry_order->head : NULL), + &entry_new, + NULL); #if NM_MORE_ASSERTS - if (entry_new) { - nm_assert (idx_type->klass->idx_obj_partitionable); - nm_assert (idx_type->klass->idx_obj_partition_equal); - nm_assert (idx_type->klass->idx_obj_partitionable (idx_type, entry_new->obj)); - nm_assert (idx_type->klass->idx_obj_partition_equal (idx_type, (gpointer) obj_new, entry_new->obj)); - } + if (entry_new) { + nm_assert(idx_type->klass->idx_obj_partitionable); + nm_assert(idx_type->klass->idx_obj_partition_equal); + nm_assert(idx_type->klass->idx_obj_partitionable(idx_type, entry_new->obj)); + nm_assert(idx_type->klass->idx_obj_partition_equal(idx_type, + (gpointer) obj_new, + entry_new->obj)); + } #endif - } else - entry_new = NULL; + } else + entry_new = NULL; - if ( entry_old - && entry_old != entry_new) - nm_dedup_multi_index_remove_entry (cache->multi_idx, entry_old); + if (entry_old && entry_old != entry_new) + nm_dedup_multi_index_remove_entry(cache->multi_idx, entry_old); } static void -_idxcache_update (NMPCache *cache, - const NMDedupMultiEntry *entry_old, - NMPObject *obj_new, - gboolean is_dump, - const NMDedupMultiEntry **out_entry_new) -{ - const NMPClass *klass; - const guint8 *i_idx_type; - NMDedupMultiIdxType *idx_type_o = _idx_type_get (cache, NMP_CACHE_ID_TYPE_OBJECT_TYPE); - const NMDedupMultiEntry *entry_new = NULL; - nm_auto_nmpobj const NMPObject *obj_old = NULL; - - /* we update an object in the cache. - * - * Note that @entry_old MUST be what is currently tracked in multi_idx, and it must - * have the same ID as @obj_new. */ - - nm_assert (cache); - nm_assert (entry_old || obj_new); - nm_assert (!obj_new || nmp_object_is_alive (obj_new)); - nm_assert (!entry_old || entry_old == nm_dedup_multi_index_lookup_obj (cache->multi_idx, idx_type_o, entry_old->obj)); - nm_assert (!obj_new || entry_old == nm_dedup_multi_index_lookup_obj (cache->multi_idx, idx_type_o, obj_new)); - nm_assert (!entry_old || entry_old->head->idx_type == idx_type_o); - nm_assert ( !entry_old - || !obj_new - || nm_dedup_multi_idx_type_partition_equal (idx_type_o, entry_old->obj, obj_new)); - nm_assert ( !entry_old - || !obj_new - || nm_dedup_multi_idx_type_id_equal (idx_type_o, entry_old->obj, obj_new)); - nm_assert ( !entry_old - || !obj_new - || ( obj_new->parent.klass == ((const NMPObject *) entry_old->obj)->parent.klass - && !obj_new->parent.klass->obj_full_equal ((NMDedupMultiObj *) obj_new, entry_old->obj))); - - /* keep a reference to the pre-existing entry */ - if (entry_old) - obj_old = nmp_object_ref (entry_old->obj); - - /* first update the main index NMP_CACHE_ID_TYPE_OBJECT_TYPE. - * We already know the pre-existing @entry old, so all that - * nm_dedup_multi_index_add_full() effectively does, is update the - * obj reference. - * - * We also get the new boxed object, which we need below. */ - if (obj_new) { - nm_auto_nmpobj NMPObject *obj_old2 = NULL; - - nm_dedup_multi_index_add_full (cache->multi_idx, - idx_type_o, - obj_new, - is_dump - ? NM_DEDUP_MULTI_IDX_MODE_APPEND_FORCE - : _obj_get_add_mode (obj_new), - NULL, - entry_old ?: NM_DEDUP_MULTI_ENTRY_MISSING, - NULL, - &entry_new, - (const NMDedupMultiObj **) &obj_old2); - nm_assert (entry_new); - nm_assert (obj_old == obj_old2); - nm_assert (!entry_old || entry_old == entry_new); - } else - nm_dedup_multi_index_remove_entry (cache->multi_idx, entry_old); - - /* now update all other indexes. We know the previously boxed entry, and the - * newly boxed one. */ - klass = NMP_OBJECT_GET_CLASS (entry_new ? entry_new->obj : obj_old); - for (i_idx_type = klass->supported_cache_ids; *i_idx_type; i_idx_type++) { - NMPCacheIdType id_type = *i_idx_type; - - if (id_type == NMP_CACHE_ID_TYPE_OBJECT_TYPE) - continue; - _idxcache_update_other_cache_ids (cache, id_type, - obj_old, - entry_new ? entry_new->obj : NULL, - is_dump); - } - - NM_SET_OUT (out_entry_new, entry_new); +_idxcache_update(NMPCache * cache, + const NMDedupMultiEntry * entry_old, + NMPObject * obj_new, + gboolean is_dump, + const NMDedupMultiEntry **out_entry_new) +{ + const NMPClass * klass; + const guint8 * i_idx_type; + NMDedupMultiIdxType * idx_type_o = _idx_type_get(cache, NMP_CACHE_ID_TYPE_OBJECT_TYPE); + const NMDedupMultiEntry *entry_new = NULL; + nm_auto_nmpobj const NMPObject *obj_old = NULL; + + /* we update an object in the cache. + * + * Note that @entry_old MUST be what is currently tracked in multi_idx, and it must + * have the same ID as @obj_new. */ + + nm_assert(cache); + nm_assert(entry_old || obj_new); + nm_assert(!obj_new || nmp_object_is_alive(obj_new)); + nm_assert( + !entry_old + || entry_old + == nm_dedup_multi_index_lookup_obj(cache->multi_idx, idx_type_o, entry_old->obj)); + nm_assert(!obj_new + || entry_old + == nm_dedup_multi_index_lookup_obj(cache->multi_idx, idx_type_o, obj_new)); + nm_assert(!entry_old || entry_old->head->idx_type == idx_type_o); + nm_assert(!entry_old || !obj_new + || nm_dedup_multi_idx_type_partition_equal(idx_type_o, entry_old->obj, obj_new)); + nm_assert(!entry_old || !obj_new + || nm_dedup_multi_idx_type_id_equal(idx_type_o, entry_old->obj, obj_new)); + nm_assert(!entry_old || !obj_new + || (obj_new->parent.klass == ((const NMPObject *) entry_old->obj)->parent.klass + && !obj_new->parent.klass->obj_full_equal((NMDedupMultiObj *) obj_new, + entry_old->obj))); + + /* keep a reference to the pre-existing entry */ + if (entry_old) + obj_old = nmp_object_ref(entry_old->obj); + + /* first update the main index NMP_CACHE_ID_TYPE_OBJECT_TYPE. + * We already know the pre-existing @entry old, so all that + * nm_dedup_multi_index_add_full() effectively does, is update the + * obj reference. + * + * We also get the new boxed object, which we need below. */ + if (obj_new) { + nm_auto_nmpobj NMPObject *obj_old2 = NULL; + + nm_dedup_multi_index_add_full(cache->multi_idx, + idx_type_o, + obj_new, + is_dump ? NM_DEDUP_MULTI_IDX_MODE_APPEND_FORCE + : _obj_get_add_mode(obj_new), + NULL, + entry_old ?: NM_DEDUP_MULTI_ENTRY_MISSING, + NULL, + &entry_new, + (const NMDedupMultiObj **) &obj_old2); + nm_assert(entry_new); + nm_assert(obj_old == obj_old2); + nm_assert(!entry_old || entry_old == entry_new); + } else + nm_dedup_multi_index_remove_entry(cache->multi_idx, entry_old); + + /* now update all other indexes. We know the previously boxed entry, and the + * newly boxed one. */ + klass = NMP_OBJECT_GET_CLASS(entry_new ? entry_new->obj : obj_old); + for (i_idx_type = klass->supported_cache_ids; *i_idx_type; i_idx_type++) { + NMPCacheIdType id_type = *i_idx_type; + + if (id_type == NMP_CACHE_ID_TYPE_OBJECT_TYPE) + continue; + _idxcache_update_other_cache_ids(cache, + id_type, + obj_old, + entry_new ? entry_new->obj : NULL, + is_dump); + } + + NM_SET_OUT(out_entry_new, entry_new); } NMPCacheOpsType -nmp_cache_remove (NMPCache *cache, - const NMPObject *obj_needle, - gboolean equals_by_ptr, - gboolean only_dirty, - const NMPObject **out_obj_old) +nmp_cache_remove(NMPCache * cache, + const NMPObject * obj_needle, + gboolean equals_by_ptr, + gboolean only_dirty, + const NMPObject **out_obj_old) { - const NMDedupMultiEntry *entry_old; - const NMPObject *obj_old; + const NMDedupMultiEntry *entry_old; + const NMPObject * obj_old; - entry_old = _lookup_entry (cache, obj_needle); + entry_old = _lookup_entry(cache, obj_needle); - if (!entry_old) { - NM_SET_OUT (out_obj_old, NULL); - return NMP_CACHE_OPS_UNCHANGED; - } + if (!entry_old) { + NM_SET_OUT(out_obj_old, NULL); + return NMP_CACHE_OPS_UNCHANGED; + } - obj_old = entry_old->obj; + obj_old = entry_old->obj; - NM_SET_OUT (out_obj_old, nmp_object_ref (obj_old)); + NM_SET_OUT(out_obj_old, nmp_object_ref(obj_old)); - if ( equals_by_ptr - && obj_old != obj_needle) { - /* We found an identical object, but we only delete it if it's the same pointer as - * @obj_needle. */ - return NMP_CACHE_OPS_UNCHANGED; - } - if ( only_dirty - && !entry_old->dirty) { - /* the entry is not dirty. Skip. */ - return NMP_CACHE_OPS_UNCHANGED; - } - _idxcache_update (cache, entry_old, NULL, FALSE, NULL); - return NMP_CACHE_OPS_REMOVED; + if (equals_by_ptr && obj_old != obj_needle) { + /* We found an identical object, but we only delete it if it's the same pointer as + * @obj_needle. */ + return NMP_CACHE_OPS_UNCHANGED; + } + if (only_dirty && !entry_old->dirty) { + /* the entry is not dirty. Skip. */ + return NMP_CACHE_OPS_UNCHANGED; + } + _idxcache_update(cache, entry_old, NULL, FALSE, NULL); + return NMP_CACHE_OPS_REMOVED; } NMPCacheOpsType -nmp_cache_remove_netlink (NMPCache *cache, - const NMPObject *obj_needle, - const NMPObject **out_obj_old, - const NMPObject **out_obj_new) -{ - const NMDedupMultiEntry *entry_old; - const NMDedupMultiEntry *entry_new = NULL; - const NMPObject *obj_old; - nm_auto_nmpobj NMPObject *obj_new = NULL; - - entry_old = _lookup_entry (cache, obj_needle); - - if (!entry_old) { - NM_SET_OUT (out_obj_old, NULL); - NM_SET_OUT (out_obj_new, NULL); - return NMP_CACHE_OPS_UNCHANGED; - } - - obj_old = entry_old->obj; - - if (NMP_OBJECT_GET_TYPE (obj_needle) == NMP_OBJECT_TYPE_LINK) { - /* For nmp_cache_remove_netlink() we have an incomplete @obj_needle instance to be - * removed from netlink. Link objects are alive without being in netlink when they - * have a udev-device. All we want to do in this case is clear the netlink.is_in_netlink - * flag. */ - - NM_SET_OUT (out_obj_old, nmp_object_ref (obj_old)); - - if (!obj_old->_link.netlink.is_in_netlink) { - nm_assert (obj_old->_link.udev.device); - NM_SET_OUT (out_obj_new, nmp_object_ref (obj_old)); - return NMP_CACHE_OPS_UNCHANGED; - } - - if (!obj_old->_link.udev.device) { - /* the update would make @obj_old invalid. Remove it. */ - _idxcache_update (cache, entry_old, NULL, FALSE, NULL); - NM_SET_OUT (out_obj_new, NULL); - return NMP_CACHE_OPS_REMOVED; - } - - obj_new = nmp_object_clone (obj_old, FALSE); - obj_new->_link.netlink.is_in_netlink = FALSE; - - _nmp_object_fixup_link_master_connected (&obj_new, NULL, cache); - _nmp_object_fixup_link_udev_fields (&obj_new, NULL, cache->use_udev); - - _idxcache_update (cache, - entry_old, - obj_new, - FALSE, - &entry_new); - NM_SET_OUT (out_obj_new, nmp_object_ref (entry_new->obj)); - return NMP_CACHE_OPS_UPDATED; - } - - NM_SET_OUT (out_obj_old, nmp_object_ref (obj_old)); - NM_SET_OUT (out_obj_new, NULL); - _idxcache_update (cache, entry_old, NULL, FALSE, NULL); - return NMP_CACHE_OPS_REMOVED; +nmp_cache_remove_netlink(NMPCache * cache, + const NMPObject * obj_needle, + const NMPObject **out_obj_old, + const NMPObject **out_obj_new) +{ + const NMDedupMultiEntry *entry_old; + const NMDedupMultiEntry *entry_new = NULL; + const NMPObject * obj_old; + nm_auto_nmpobj NMPObject *obj_new = NULL; + + entry_old = _lookup_entry(cache, obj_needle); + + if (!entry_old) { + NM_SET_OUT(out_obj_old, NULL); + NM_SET_OUT(out_obj_new, NULL); + return NMP_CACHE_OPS_UNCHANGED; + } + + obj_old = entry_old->obj; + + if (NMP_OBJECT_GET_TYPE(obj_needle) == NMP_OBJECT_TYPE_LINK) { + /* For nmp_cache_remove_netlink() we have an incomplete @obj_needle instance to be + * removed from netlink. Link objects are alive without being in netlink when they + * have a udev-device. All we want to do in this case is clear the netlink.is_in_netlink + * flag. */ + + NM_SET_OUT(out_obj_old, nmp_object_ref(obj_old)); + + if (!obj_old->_link.netlink.is_in_netlink) { + nm_assert(obj_old->_link.udev.device); + NM_SET_OUT(out_obj_new, nmp_object_ref(obj_old)); + return NMP_CACHE_OPS_UNCHANGED; + } + + if (!obj_old->_link.udev.device) { + /* the update would make @obj_old invalid. Remove it. */ + _idxcache_update(cache, entry_old, NULL, FALSE, NULL); + NM_SET_OUT(out_obj_new, NULL); + return NMP_CACHE_OPS_REMOVED; + } + + obj_new = nmp_object_clone(obj_old, FALSE); + obj_new->_link.netlink.is_in_netlink = FALSE; + + _nmp_object_fixup_link_master_connected(&obj_new, NULL, cache); + _nmp_object_fixup_link_udev_fields(&obj_new, NULL, cache->use_udev); + + _idxcache_update(cache, entry_old, obj_new, FALSE, &entry_new); + NM_SET_OUT(out_obj_new, nmp_object_ref(entry_new->obj)); + return NMP_CACHE_OPS_UPDATED; + } + + NM_SET_OUT(out_obj_old, nmp_object_ref(obj_old)); + NM_SET_OUT(out_obj_new, NULL); + _idxcache_update(cache, entry_old, NULL, FALSE, NULL); + return NMP_CACHE_OPS_REMOVED; } /** @@ -2578,801 +2649,809 @@ nmp_cache_remove_netlink (NMPCache *cache, * and @out_obj_new will be set accordingly. **/ NMPCacheOpsType -nmp_cache_update_netlink (NMPCache *cache, - NMPObject *obj_hand_over, - gboolean is_dump, - const NMPObject **out_obj_old, - const NMPObject **out_obj_new) -{ - const NMDedupMultiEntry *entry_old; - const NMDedupMultiEntry *entry_new; - const NMPObject *obj_old; - gboolean is_alive; - - nm_assert (cache); - nm_assert (NMP_OBJECT_IS_VALID (obj_hand_over)); - nm_assert (!NMP_OBJECT_IS_STACKINIT (obj_hand_over)); - /* A link object from netlink must have the udev related fields unset. - * We could implement to handle that, but there is no need to support such - * a use-case */ - nm_assert (NMP_OBJECT_GET_TYPE (obj_hand_over) != NMP_OBJECT_TYPE_LINK || - ( !obj_hand_over->_link.udev.device - && !obj_hand_over->link.driver)); - nm_assert (nm_dedup_multi_index_obj_find (cache->multi_idx, obj_hand_over) != obj_hand_over); - - entry_old = _lookup_entry (cache, obj_hand_over); - - if (!entry_old) { - - NM_SET_OUT (out_obj_old, NULL); - - if (!nmp_object_is_alive (obj_hand_over)) { - NM_SET_OUT (out_obj_new, NULL); - return NMP_CACHE_OPS_UNCHANGED; - } - - if (NMP_OBJECT_GET_TYPE (obj_hand_over) == NMP_OBJECT_TYPE_LINK) { - _nmp_object_fixup_link_master_connected (&obj_hand_over, NULL, cache); - _nmp_object_fixup_link_udev_fields (&obj_hand_over, NULL, cache->use_udev); - } - - _idxcache_update (cache, - entry_old, - obj_hand_over, - is_dump, - &entry_new); - NM_SET_OUT (out_obj_new, nmp_object_ref (entry_new->obj)); - return NMP_CACHE_OPS_ADDED; - } - - obj_old = entry_old->obj; - - if (NMP_OBJECT_GET_TYPE (obj_hand_over) == NMP_OBJECT_TYPE_LINK) { - if (!obj_hand_over->_link.netlink.is_in_netlink) { - if (!obj_old->_link.netlink.is_in_netlink) { - nm_assert (obj_old->_link.udev.device); - NM_SET_OUT (out_obj_old, nmp_object_ref (obj_old)); - NM_SET_OUT (out_obj_new, nmp_object_ref (obj_old)); - return NMP_CACHE_OPS_UNCHANGED; - } - if (obj_old->_link.udev.device) { - /* @obj_hand_over is not in netlink. - * - * This is similar to nmp_cache_remove_netlink(), but there we preserve the - * preexisting netlink properties. The use case of that is when kernel_get_object() - * cannot load an object (based on the id of a needle). - * - * Here we keep the data provided from @obj_hand_over. The usecase is when receiving - * a valid @obj_hand_over instance from netlink with RTM_DELROUTE. - */ - is_alive = TRUE; - } else - is_alive = FALSE; - } else - is_alive = TRUE; - - if (is_alive) { - _nmp_object_fixup_link_master_connected (&obj_hand_over, NULL, cache); - - /* Merge the netlink parts with what we have from udev. */ - udev_device_unref (obj_hand_over->_link.udev.device); - obj_hand_over->_link.udev.device = obj_old->_link.udev.device ? udev_device_ref (obj_old->_link.udev.device) : NULL; - _nmp_object_fixup_link_udev_fields (&obj_hand_over, NULL, cache->use_udev); - - if (obj_hand_over->_link.netlink.lnk) { - nm_auto_nmpobj const NMPObject *lnk_old = obj_hand_over->_link.netlink.lnk; - - /* let's dedup/intern the lnk object. */ - obj_hand_over->_link.netlink.lnk = nm_dedup_multi_index_obj_intern (cache->multi_idx, lnk_old); - } - } - } else - is_alive = nmp_object_is_alive (obj_hand_over); - - NM_SET_OUT (out_obj_old, nmp_object_ref (obj_old)); - - if (!is_alive) { - /* the update would make @obj_old invalid. Remove it. */ - _idxcache_update (cache, entry_old, NULL, FALSE, NULL); - NM_SET_OUT (out_obj_new, NULL); - return NMP_CACHE_OPS_REMOVED; - } - - if (nmp_object_equal (obj_old, obj_hand_over)) { - if (is_dump) - _idxcache_update_order_for_dump (cache, entry_old); - nm_dedup_multi_entry_set_dirty (entry_old, FALSE); - NM_SET_OUT (out_obj_new, nmp_object_ref (obj_old)); - return NMP_CACHE_OPS_UNCHANGED; - } - - _idxcache_update (cache, - entry_old, - obj_hand_over, - is_dump, - &entry_new); - NM_SET_OUT (out_obj_new, nmp_object_ref (entry_new->obj)); - return NMP_CACHE_OPS_UPDATED; +nmp_cache_update_netlink(NMPCache * cache, + NMPObject * obj_hand_over, + gboolean is_dump, + const NMPObject **out_obj_old, + const NMPObject **out_obj_new) +{ + const NMDedupMultiEntry *entry_old; + const NMDedupMultiEntry *entry_new; + const NMPObject * obj_old; + gboolean is_alive; + + nm_assert(cache); + nm_assert(NMP_OBJECT_IS_VALID(obj_hand_over)); + nm_assert(!NMP_OBJECT_IS_STACKINIT(obj_hand_over)); + /* A link object from netlink must have the udev related fields unset. + * We could implement to handle that, but there is no need to support such + * a use-case */ + nm_assert(NMP_OBJECT_GET_TYPE(obj_hand_over) != NMP_OBJECT_TYPE_LINK + || (!obj_hand_over->_link.udev.device && !obj_hand_over->link.driver)); + nm_assert(nm_dedup_multi_index_obj_find(cache->multi_idx, obj_hand_over) != obj_hand_over); + + entry_old = _lookup_entry(cache, obj_hand_over); + + if (!entry_old) { + NM_SET_OUT(out_obj_old, NULL); + + if (!nmp_object_is_alive(obj_hand_over)) { + NM_SET_OUT(out_obj_new, NULL); + return NMP_CACHE_OPS_UNCHANGED; + } + + if (NMP_OBJECT_GET_TYPE(obj_hand_over) == NMP_OBJECT_TYPE_LINK) { + _nmp_object_fixup_link_master_connected(&obj_hand_over, NULL, cache); + _nmp_object_fixup_link_udev_fields(&obj_hand_over, NULL, cache->use_udev); + } + + _idxcache_update(cache, entry_old, obj_hand_over, is_dump, &entry_new); + NM_SET_OUT(out_obj_new, nmp_object_ref(entry_new->obj)); + return NMP_CACHE_OPS_ADDED; + } + + obj_old = entry_old->obj; + + if (NMP_OBJECT_GET_TYPE(obj_hand_over) == NMP_OBJECT_TYPE_LINK) { + if (!obj_hand_over->_link.netlink.is_in_netlink) { + if (!obj_old->_link.netlink.is_in_netlink) { + nm_assert(obj_old->_link.udev.device); + NM_SET_OUT(out_obj_old, nmp_object_ref(obj_old)); + NM_SET_OUT(out_obj_new, nmp_object_ref(obj_old)); + return NMP_CACHE_OPS_UNCHANGED; + } + if (obj_old->_link.udev.device) { + /* @obj_hand_over is not in netlink. + * + * This is similar to nmp_cache_remove_netlink(), but there we preserve the + * preexisting netlink properties. The use case of that is when kernel_get_object() + * cannot load an object (based on the id of a needle). + * + * Here we keep the data provided from @obj_hand_over. The usecase is when receiving + * a valid @obj_hand_over instance from netlink with RTM_DELROUTE. + */ + is_alive = TRUE; + } else + is_alive = FALSE; + } else + is_alive = TRUE; + + if (is_alive) { + _nmp_object_fixup_link_master_connected(&obj_hand_over, NULL, cache); + + /* Merge the netlink parts with what we have from udev. */ + udev_device_unref(obj_hand_over->_link.udev.device); + obj_hand_over->_link.udev.device = + obj_old->_link.udev.device ? udev_device_ref(obj_old->_link.udev.device) : NULL; + _nmp_object_fixup_link_udev_fields(&obj_hand_over, NULL, cache->use_udev); + + if (obj_hand_over->_link.netlink.lnk) { + nm_auto_nmpobj const NMPObject *lnk_old = obj_hand_over->_link.netlink.lnk; + + /* let's dedup/intern the lnk object. */ + obj_hand_over->_link.netlink.lnk = + nm_dedup_multi_index_obj_intern(cache->multi_idx, lnk_old); + } + } + } else + is_alive = nmp_object_is_alive(obj_hand_over); + + NM_SET_OUT(out_obj_old, nmp_object_ref(obj_old)); + + if (!is_alive) { + /* the update would make @obj_old invalid. Remove it. */ + _idxcache_update(cache, entry_old, NULL, FALSE, NULL); + NM_SET_OUT(out_obj_new, NULL); + return NMP_CACHE_OPS_REMOVED; + } + + if (nmp_object_equal(obj_old, obj_hand_over)) { + if (is_dump) + _idxcache_update_order_for_dump(cache, entry_old); + nm_dedup_multi_entry_set_dirty(entry_old, FALSE); + NM_SET_OUT(out_obj_new, nmp_object_ref(obj_old)); + return NMP_CACHE_OPS_UNCHANGED; + } + + _idxcache_update(cache, entry_old, obj_hand_over, is_dump, &entry_new); + NM_SET_OUT(out_obj_new, nmp_object_ref(entry_new->obj)); + return NMP_CACHE_OPS_UPDATED; } NMPCacheOpsType -nmp_cache_update_netlink_route (NMPCache *cache, - NMPObject *obj_hand_over, - gboolean is_dump, - guint16 nlmsgflags, - const NMPObject **out_obj_old, - const NMPObject **out_obj_new, - const NMPObject **out_obj_replace, - gboolean *out_resync_required) -{ - NMDedupMultiIter iter; - const NMDedupMultiEntry *entry_old; - const NMDedupMultiEntry *entry_new; - const NMDedupMultiEntry *entry_cur; - const NMDedupMultiEntry *entry_replace; - const NMDedupMultiHeadEntry *head_entry; - gboolean is_alive; - NMPCacheOpsType ops_type = NMP_CACHE_OPS_UNCHANGED; - gboolean resync_required; - - nm_assert (cache); - nm_assert (NMP_OBJECT_IS_VALID (obj_hand_over)); - nm_assert (!NMP_OBJECT_IS_STACKINIT (obj_hand_over)); - /* A link object from netlink must have the udev related fields unset. - * We could implement to handle that, but there is no need to support such - * a use-case */ - nm_assert (NM_IN_SET (NMP_OBJECT_GET_TYPE (obj_hand_over), NMP_OBJECT_TYPE_IP4_ROUTE, - NMP_OBJECT_TYPE_IP6_ROUTE)); - nm_assert (nm_dedup_multi_index_obj_find (cache->multi_idx, obj_hand_over) != obj_hand_over); - - entry_old = _lookup_entry (cache, obj_hand_over); - entry_new = NULL; - - NM_SET_OUT (out_obj_old, nmp_object_ref (nm_dedup_multi_entry_get_obj (entry_old))); - - if (!entry_old) { - - if (!nmp_object_is_alive (obj_hand_over)) - goto update_done; - - _idxcache_update (cache, - NULL, - obj_hand_over, - is_dump, - &entry_new); - ops_type = NMP_CACHE_OPS_ADDED; - goto update_done; - } - - is_alive = nmp_object_is_alive (obj_hand_over); - - if (!is_alive) { - /* the update would make @entry_old invalid. Remove it. */ - _idxcache_update (cache, entry_old, NULL, FALSE, NULL); - ops_type = NMP_CACHE_OPS_REMOVED; - goto update_done; - } - - if (nmp_object_equal (entry_old->obj, obj_hand_over)) { - if (is_dump) - _idxcache_update_order_for_dump (cache, entry_old); - nm_dedup_multi_entry_set_dirty (entry_old, FALSE); - goto update_done; - } - - _idxcache_update (cache, - entry_old, - obj_hand_over, - is_dump, - &entry_new); - ops_type = NMP_CACHE_OPS_UPDATED; +nmp_cache_update_netlink_route(NMPCache * cache, + NMPObject * obj_hand_over, + gboolean is_dump, + guint16 nlmsgflags, + const NMPObject **out_obj_old, + const NMPObject **out_obj_new, + const NMPObject **out_obj_replace, + gboolean * out_resync_required) +{ + NMDedupMultiIter iter; + const NMDedupMultiEntry * entry_old; + const NMDedupMultiEntry * entry_new; + const NMDedupMultiEntry * entry_cur; + const NMDedupMultiEntry * entry_replace; + const NMDedupMultiHeadEntry *head_entry; + gboolean is_alive; + NMPCacheOpsType ops_type = NMP_CACHE_OPS_UNCHANGED; + gboolean resync_required; + + nm_assert(cache); + nm_assert(NMP_OBJECT_IS_VALID(obj_hand_over)); + nm_assert(!NMP_OBJECT_IS_STACKINIT(obj_hand_over)); + /* A link object from netlink must have the udev related fields unset. + * We could implement to handle that, but there is no need to support such + * a use-case */ + nm_assert(NM_IN_SET(NMP_OBJECT_GET_TYPE(obj_hand_over), + NMP_OBJECT_TYPE_IP4_ROUTE, + NMP_OBJECT_TYPE_IP6_ROUTE)); + nm_assert(nm_dedup_multi_index_obj_find(cache->multi_idx, obj_hand_over) != obj_hand_over); + + entry_old = _lookup_entry(cache, obj_hand_over); + entry_new = NULL; + + NM_SET_OUT(out_obj_old, nmp_object_ref(nm_dedup_multi_entry_get_obj(entry_old))); + + if (!entry_old) { + if (!nmp_object_is_alive(obj_hand_over)) + goto update_done; + + _idxcache_update(cache, NULL, obj_hand_over, is_dump, &entry_new); + ops_type = NMP_CACHE_OPS_ADDED; + goto update_done; + } + + is_alive = nmp_object_is_alive(obj_hand_over); + + if (!is_alive) { + /* the update would make @entry_old invalid. Remove it. */ + _idxcache_update(cache, entry_old, NULL, FALSE, NULL); + ops_type = NMP_CACHE_OPS_REMOVED; + goto update_done; + } + + if (nmp_object_equal(entry_old->obj, obj_hand_over)) { + if (is_dump) + _idxcache_update_order_for_dump(cache, entry_old); + nm_dedup_multi_entry_set_dirty(entry_old, FALSE); + goto update_done; + } + + _idxcache_update(cache, entry_old, obj_hand_over, is_dump, &entry_new); + ops_type = NMP_CACHE_OPS_UPDATED; update_done: - NM_SET_OUT (out_obj_new, nmp_object_ref (nm_dedup_multi_entry_get_obj (entry_new))); - - /* a RTM_GETROUTE event may signal that another object was replaced. - * Find out whether that is the case and return it as @obj_replaced. - * - * Also, fixup the order of @entry_new within NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID - * index. For most parts, we don't care about the order of objects (including routes). - * But NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID we must keep in the correct order, to - * properly find @obj_replaced. */ - resync_required = FALSE; - entry_replace = NULL; - if (is_dump) - goto out; - - if (!entry_new) { - if ( NM_FLAGS_HAS (nlmsgflags, NLM_F_REPLACE) - && nmp_cache_lookup_all (cache, - NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID, - obj_hand_over)) { - /* hm. @obj_hand_over was not added, meaning it was not alive. - * However, we track some other objects with the same weak-id. - * It's unclear what that means. To be sure, resync. */ - resync_required = TRUE; - } - goto out; - } - - /* FIXME: for routes, we only maintain the order correctly for the BY_WEAK_ID - * index. For all other indexes their order becomes messed up. */ - entry_cur = _lookup_entry_with_idx_type (cache, - NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID, - entry_new->obj); - if (!entry_cur) { - nm_assert_not_reached (); - goto out; - } - nm_assert (entry_cur->obj == entry_new->obj); - - head_entry = entry_cur->head; - nm_assert (head_entry == nmp_cache_lookup_all (cache, - NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID, - entry_cur->obj)); - - if (head_entry->len == 1) { - /* there is only one object, and we expect it to be @obj_new. */ - nm_assert (nm_dedup_multi_head_entry_get_idx (head_entry, 0) == entry_cur); - goto out; - } - - switch (nlmsgflags & (NLM_F_REPLACE | NLM_F_EXCL | NLM_F_CREATE | NLM_F_APPEND)) { - case NLM_F_REPLACE: - /* ip route change */ - - /* get the first element (but skip @obj_new). */ - nm_dedup_multi_iter_init (&iter, head_entry); - if (!nm_dedup_multi_iter_next (&iter)) - nm_assert_not_reached (); - if (iter.current == entry_cur) { - if (!nm_dedup_multi_iter_next (&iter)) - nm_assert_not_reached (); - } - entry_replace = iter.current; - - nm_assert ( entry_replace - && entry_cur != entry_replace); - - nm_dedup_multi_entry_reorder (entry_cur, entry_replace, FALSE); - break; - case NLM_F_CREATE | NLM_F_APPEND: - /* ip route append */ - nm_dedup_multi_entry_reorder (entry_cur, NULL, TRUE); - break; - case NLM_F_CREATE: - /* ip route prepend */ - nm_dedup_multi_entry_reorder (entry_cur, NULL, FALSE); - break; - default: - /* this is an unexpected case, probably a bug that we need to handle better. */ - resync_required = TRUE; - break; - } + NM_SET_OUT(out_obj_new, nmp_object_ref(nm_dedup_multi_entry_get_obj(entry_new))); + + /* a RTM_GETROUTE event may signal that another object was replaced. + * Find out whether that is the case and return it as @obj_replaced. + * + * Also, fixup the order of @entry_new within NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID + * index. For most parts, we don't care about the order of objects (including routes). + * But NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID we must keep in the correct order, to + * properly find @obj_replaced. */ + resync_required = FALSE; + entry_replace = NULL; + if (is_dump) + goto out; + + if (!entry_new) { + if (NM_FLAGS_HAS(nlmsgflags, NLM_F_REPLACE) + && nmp_cache_lookup_all(cache, NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID, obj_hand_over)) { + /* hm. @obj_hand_over was not added, meaning it was not alive. + * However, we track some other objects with the same weak-id. + * It's unclear what that means. To be sure, resync. */ + resync_required = TRUE; + } + goto out; + } + + /* FIXME: for routes, we only maintain the order correctly for the BY_WEAK_ID + * index. For all other indexes their order becomes messed up. */ + entry_cur = + _lookup_entry_with_idx_type(cache, NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID, entry_new->obj); + if (!entry_cur) { + nm_assert_not_reached(); + goto out; + } + nm_assert(entry_cur->obj == entry_new->obj); + + head_entry = entry_cur->head; + nm_assert(head_entry + == nmp_cache_lookup_all(cache, NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID, entry_cur->obj)); + + if (head_entry->len == 1) { + /* there is only one object, and we expect it to be @obj_new. */ + nm_assert(nm_dedup_multi_head_entry_get_idx(head_entry, 0) == entry_cur); + goto out; + } + + switch (nlmsgflags & (NLM_F_REPLACE | NLM_F_EXCL | NLM_F_CREATE | NLM_F_APPEND)) { + case NLM_F_REPLACE: + /* ip route change */ + + /* get the first element (but skip @obj_new). */ + nm_dedup_multi_iter_init(&iter, head_entry); + if (!nm_dedup_multi_iter_next(&iter)) + nm_assert_not_reached(); + if (iter.current == entry_cur) { + if (!nm_dedup_multi_iter_next(&iter)) + nm_assert_not_reached(); + } + entry_replace = iter.current; + + nm_assert(entry_replace && entry_cur != entry_replace); + + nm_dedup_multi_entry_reorder(entry_cur, entry_replace, FALSE); + break; + case NLM_F_CREATE | NLM_F_APPEND: + /* ip route append */ + nm_dedup_multi_entry_reorder(entry_cur, NULL, TRUE); + break; + case NLM_F_CREATE: + /* ip route prepend */ + nm_dedup_multi_entry_reorder(entry_cur, NULL, FALSE); + break; + default: + /* this is an unexpected case, probably a bug that we need to handle better. */ + resync_required = TRUE; + break; + } out: - NM_SET_OUT (out_obj_replace, nmp_object_ref (nm_dedup_multi_entry_get_obj (entry_replace))); - NM_SET_OUT (out_resync_required, resync_required); - return ops_type; + NM_SET_OUT(out_obj_replace, nmp_object_ref(nm_dedup_multi_entry_get_obj(entry_replace))); + NM_SET_OUT(out_resync_required, resync_required); + return ops_type; } NMPCacheOpsType -nmp_cache_update_link_udev (NMPCache *cache, - int ifindex, - struct udev_device *udevice, - const NMPObject **out_obj_old, - const NMPObject **out_obj_new) -{ - const NMPObject *obj_old; - nm_auto_nmpobj NMPObject *obj_new = NULL; - const NMDedupMultiEntry *entry_old; - const NMDedupMultiEntry *entry_new; - - entry_old = nmp_cache_lookup_entry_link (cache, ifindex); - - if (!entry_old) { - if (!udevice) { - NM_SET_OUT (out_obj_old, NULL); - NM_SET_OUT (out_obj_new, NULL); - return NMP_CACHE_OPS_UNCHANGED; - } - - obj_new = nmp_object_new (NMP_OBJECT_TYPE_LINK, NULL); - obj_new->link.ifindex = ifindex; - obj_new->_link.udev.device = udev_device_ref (udevice); - - _nmp_object_fixup_link_udev_fields (&obj_new, NULL, cache->use_udev); - - _idxcache_update (cache, - NULL, - obj_new, - FALSE, - &entry_new); - NM_SET_OUT (out_obj_old, NULL); - NM_SET_OUT (out_obj_new, nmp_object_ref (entry_new->obj)); - return NMP_CACHE_OPS_ADDED; - } else { - obj_old = entry_old->obj; - NM_SET_OUT (out_obj_old, nmp_object_ref (obj_old)); - - if (obj_old->_link.udev.device == udevice) { - NM_SET_OUT (out_obj_new, nmp_object_ref (obj_old)); - return NMP_CACHE_OPS_UNCHANGED; - } - - if (!udevice && !obj_old->_link.netlink.is_in_netlink) { - /* the update would make @obj_old invalid. Remove it. */ - _idxcache_update (cache, entry_old, NULL, FALSE, NULL); - NM_SET_OUT (out_obj_new, NULL); - return NMP_CACHE_OPS_REMOVED; - } - - obj_new = nmp_object_clone (obj_old, FALSE); - - udev_device_unref (obj_new->_link.udev.device); - obj_new->_link.udev.device = udevice ? udev_device_ref (udevice) : NULL; - - _nmp_object_fixup_link_udev_fields (&obj_new, NULL, cache->use_udev); - - _idxcache_update (cache, - entry_old, - obj_new, - FALSE, - &entry_new); - NM_SET_OUT (out_obj_new, nmp_object_ref (entry_new->obj)); - return NMP_CACHE_OPS_UPDATED; - } +nmp_cache_update_link_udev(NMPCache * cache, + int ifindex, + struct udev_device *udevice, + const NMPObject ** out_obj_old, + const NMPObject ** out_obj_new) +{ + const NMPObject *obj_old; + nm_auto_nmpobj NMPObject *obj_new = NULL; + const NMDedupMultiEntry * entry_old; + const NMDedupMultiEntry * entry_new; + + entry_old = nmp_cache_lookup_entry_link(cache, ifindex); + + if (!entry_old) { + if (!udevice) { + NM_SET_OUT(out_obj_old, NULL); + NM_SET_OUT(out_obj_new, NULL); + return NMP_CACHE_OPS_UNCHANGED; + } + + obj_new = nmp_object_new(NMP_OBJECT_TYPE_LINK, NULL); + obj_new->link.ifindex = ifindex; + obj_new->_link.udev.device = udev_device_ref(udevice); + + _nmp_object_fixup_link_udev_fields(&obj_new, NULL, cache->use_udev); + + _idxcache_update(cache, NULL, obj_new, FALSE, &entry_new); + NM_SET_OUT(out_obj_old, NULL); + NM_SET_OUT(out_obj_new, nmp_object_ref(entry_new->obj)); + return NMP_CACHE_OPS_ADDED; + } else { + obj_old = entry_old->obj; + NM_SET_OUT(out_obj_old, nmp_object_ref(obj_old)); + + if (obj_old->_link.udev.device == udevice) { + NM_SET_OUT(out_obj_new, nmp_object_ref(obj_old)); + return NMP_CACHE_OPS_UNCHANGED; + } + + if (!udevice && !obj_old->_link.netlink.is_in_netlink) { + /* the update would make @obj_old invalid. Remove it. */ + _idxcache_update(cache, entry_old, NULL, FALSE, NULL); + NM_SET_OUT(out_obj_new, NULL); + return NMP_CACHE_OPS_REMOVED; + } + + obj_new = nmp_object_clone(obj_old, FALSE); + + udev_device_unref(obj_new->_link.udev.device); + obj_new->_link.udev.device = udevice ? udev_device_ref(udevice) : NULL; + + _nmp_object_fixup_link_udev_fields(&obj_new, NULL, cache->use_udev); + + _idxcache_update(cache, entry_old, obj_new, FALSE, &entry_new); + NM_SET_OUT(out_obj_new, nmp_object_ref(entry_new->obj)); + return NMP_CACHE_OPS_UPDATED; + } } NMPCacheOpsType -nmp_cache_update_link_master_connected (NMPCache *cache, - int ifindex, - const NMPObject **out_obj_old, - const NMPObject **out_obj_new) +nmp_cache_update_link_master_connected(NMPCache * cache, + int ifindex, + const NMPObject **out_obj_old, + const NMPObject **out_obj_new) { - const NMDedupMultiEntry *entry_old; - const NMDedupMultiEntry *entry_new = NULL; - const NMPObject *obj_old; - nm_auto_nmpobj NMPObject *obj_new = NULL; + const NMDedupMultiEntry *entry_old; + const NMDedupMultiEntry *entry_new = NULL; + const NMPObject * obj_old; + nm_auto_nmpobj NMPObject *obj_new = NULL; - entry_old = nmp_cache_lookup_entry_link (cache, ifindex); + entry_old = nmp_cache_lookup_entry_link(cache, ifindex); - if (!entry_old) { - NM_SET_OUT (out_obj_old, NULL); - NM_SET_OUT (out_obj_new, NULL); - return NMP_CACHE_OPS_UNCHANGED; - } + if (!entry_old) { + NM_SET_OUT(out_obj_old, NULL); + NM_SET_OUT(out_obj_new, NULL); + return NMP_CACHE_OPS_UNCHANGED; + } - obj_old = entry_old->obj; + obj_old = entry_old->obj; - if (!nmp_cache_link_connected_needs_toggle (cache, obj_old, NULL, NULL)) { - NM_SET_OUT (out_obj_old, nmp_object_ref (obj_old)); - NM_SET_OUT (out_obj_new, nmp_object_ref (obj_old)); - return NMP_CACHE_OPS_UNCHANGED; - } + if (!nmp_cache_link_connected_needs_toggle(cache, obj_old, NULL, NULL)) { + NM_SET_OUT(out_obj_old, nmp_object_ref(obj_old)); + NM_SET_OUT(out_obj_new, nmp_object_ref(obj_old)); + return NMP_CACHE_OPS_UNCHANGED; + } - obj_new = nmp_object_clone (obj_old, FALSE); - obj_new->link.connected = !obj_old->link.connected; + obj_new = nmp_object_clone(obj_old, FALSE); + obj_new->link.connected = !obj_old->link.connected; - NM_SET_OUT (out_obj_old, nmp_object_ref (obj_old)); - _idxcache_update (cache, - entry_old, - obj_new, - FALSE, - &entry_new); - NM_SET_OUT (out_obj_new, nmp_object_ref (entry_new->obj)); - return NMP_CACHE_OPS_UPDATED; + NM_SET_OUT(out_obj_old, nmp_object_ref(obj_old)); + _idxcache_update(cache, entry_old, obj_new, FALSE, &entry_new); + NM_SET_OUT(out_obj_new, nmp_object_ref(entry_new->obj)); + return NMP_CACHE_OPS_UPDATED; } /*****************************************************************************/ void -nmp_cache_dirty_set_all_main (NMPCache *cache, - const NMPLookup *lookup) +nmp_cache_dirty_set_all_main(NMPCache *cache, const NMPLookup *lookup) { - const NMDedupMultiHeadEntry *head_entry; - NMDedupMultiIter iter; + const NMDedupMultiHeadEntry *head_entry; + NMDedupMultiIter iter; - nm_assert (cache); - nm_assert (lookup); + nm_assert(cache); + nm_assert(lookup); - head_entry = nmp_cache_lookup (cache, lookup); + head_entry = nmp_cache_lookup(cache, lookup); - nm_dedup_multi_iter_init (&iter, head_entry); - while (nm_dedup_multi_iter_next (&iter)) { - const NMDedupMultiEntry *main_entry; + nm_dedup_multi_iter_init(&iter, head_entry); + while (nm_dedup_multi_iter_next(&iter)) { + const NMDedupMultiEntry *main_entry; - main_entry = nmp_cache_reresolve_main_entry (cache, iter.current, lookup); + main_entry = nmp_cache_reresolve_main_entry(cache, iter.current, lookup); - nm_dedup_multi_entry_set_dirty (main_entry, TRUE); - } + nm_dedup_multi_entry_set_dirty(main_entry, TRUE); + } } /*****************************************************************************/ NMPCache * -nmp_cache_new (NMDedupMultiIndex *multi_idx, gboolean use_udev) +nmp_cache_new(NMDedupMultiIndex *multi_idx, gboolean use_udev) { - NMPCache *cache = g_slice_new0 (NMPCache); - guint i; + NMPCache *cache = g_slice_new0(NMPCache); + guint i; - for (i = NMP_CACHE_ID_TYPE_NONE + 1; i <= NMP_CACHE_ID_TYPE_MAX; i++) - _dedup_multi_idx_type_init ((DedupMultiIdxType *) _idx_type_get (cache, i), i); + for (i = NMP_CACHE_ID_TYPE_NONE + 1; i <= NMP_CACHE_ID_TYPE_MAX; i++) + _dedup_multi_idx_type_init((DedupMultiIdxType *) _idx_type_get(cache, i), i); - cache->multi_idx = nm_dedup_multi_index_ref (multi_idx); + cache->multi_idx = nm_dedup_multi_index_ref(multi_idx); - cache->use_udev = !!use_udev; - return cache; + cache->use_udev = !!use_udev; + return cache; } void -nmp_cache_free (NMPCache *cache) +nmp_cache_free(NMPCache *cache) { - guint i; + guint i; - for (i = NMP_CACHE_ID_TYPE_NONE + 1; i <= NMP_CACHE_ID_TYPE_MAX; i++) - nm_dedup_multi_index_remove_idx (cache->multi_idx, _idx_type_get (cache, i)); + for (i = NMP_CACHE_ID_TYPE_NONE + 1; i <= NMP_CACHE_ID_TYPE_MAX; i++) + nm_dedup_multi_index_remove_idx(cache->multi_idx, _idx_type_get(cache, i)); - nm_dedup_multi_index_unref (cache->multi_idx); + nm_dedup_multi_index_unref(cache->multi_idx); - g_slice_free (NMPCache, cache); + g_slice_free(NMPCache, cache); } /*****************************************************************************/ void -ASSERT_nmp_cache_is_consistent (const NMPCache *cache) -{ -} +nmtst_assert_nmp_cache_is_consistent(const NMPCache *cache) +{} /*****************************************************************************/ +/* below, ensure that addr_family get's automatically initialize to AF_UNSPEC. */ +G_STATIC_ASSERT(AF_UNSPEC == 0); + +typedef const char *(*CmdPlobjToStringFunc)(const NMPlatformObject *obj, char *buf, gsize len); +typedef const char *(*CmdPlobjToStringIdFunc)(const NMPlatformObject *obj, char *buf, gsize len); +typedef void (*CmdPlobjHashUpdateFunc)(const NMPlatformObject *obj, NMHashState *h); +typedef int (*CmdPlobjCmpFunc)(const NMPlatformObject *obj1, const NMPlatformObject *obj2); + const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { - [NMP_OBJECT_TYPE_LINK - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_LINK, - .sizeof_data = sizeof (NMPObjectLink), - .sizeof_public = sizeof (NMPlatformLink), - .obj_type_name = "link", - .rtm_gettype = RTM_GETLINK, - .signal_type_id = NM_PLATFORM_SIGNAL_ID_LINK, - .signal_type = NM_PLATFORM_SIGNAL_LINK_CHANGED, - .supported_cache_ids = _supported_cache_ids_link, - .cmd_obj_hash_update = _vt_cmd_obj_hash_update_link, - .cmd_obj_cmp = _vt_cmd_obj_cmp_link, - .cmd_obj_copy = _vt_cmd_obj_copy_link, - .cmd_obj_dispose = _vt_cmd_obj_dispose_link, - .cmd_obj_is_alive = _vt_cmd_obj_is_alive_link, - .cmd_obj_is_visible = _vt_cmd_obj_is_visible_link, - .cmd_obj_to_string = _vt_cmd_obj_to_string_link, - .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_link, - .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_link, - .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_link, - .cmd_plobj_to_string_id = _vt_cmd_plobj_to_string_id_link, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_link_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_link_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_link_cmp, - }, - [NMP_OBJECT_TYPE_IP4_ADDRESS - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_IP4_ADDRESS, - .sizeof_data = sizeof (NMPObjectIP4Address), - .sizeof_public = sizeof (NMPlatformIP4Address), - .obj_type_name = "ip4-address", - .addr_family = AF_INET, - .rtm_gettype = RTM_GETADDR, - .signal_type_id = NM_PLATFORM_SIGNAL_ID_IP4_ADDRESS, - .signal_type = NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, - .supported_cache_ids = _supported_cache_ids_ipx_address, - .cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_address, - .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip4_address, - .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_ip4_address, - .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_ip4_address, - .cmd_plobj_to_string_id = _vt_cmd_plobj_to_string_id_ip4_address, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_ip4_address_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_ip4_address_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_ip4_address_cmp, - }, - [NMP_OBJECT_TYPE_IP6_ADDRESS - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_IP6_ADDRESS, - .sizeof_data = sizeof (NMPObjectIP6Address), - .sizeof_public = sizeof (NMPlatformIP6Address), - .obj_type_name = "ip6-address", - .addr_family = AF_INET6, - .rtm_gettype = RTM_GETADDR, - .signal_type_id = NM_PLATFORM_SIGNAL_ID_IP6_ADDRESS, - .signal_type = NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, - .supported_cache_ids = _supported_cache_ids_ipx_address, - .cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_address, - .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip6_address, - .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_ip6_address, - .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_ip6_address, - .cmd_plobj_to_string_id = _vt_cmd_plobj_to_string_id_ip6_address, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_ip6_address_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_ip6_address_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_ip6_address_cmp - }, - [NMP_OBJECT_TYPE_IP4_ROUTE - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_IP4_ROUTE, - .sizeof_data = sizeof (NMPObjectIP4Route), - .sizeof_public = sizeof (NMPlatformIP4Route), - .obj_type_name = "ip4-route", - .addr_family = AF_INET, - .rtm_gettype = RTM_GETROUTE, - .signal_type_id = NM_PLATFORM_SIGNAL_ID_IP4_ROUTE, - .signal_type = NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, - .supported_cache_ids = _supported_cache_ids_ipx_route, - .cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_route, - .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip4_route, - .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_ip4_route, - .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_ip4_route, - .cmd_plobj_to_string_id = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_ip4_route_to_string, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_ip4_route_to_string, - .cmd_plobj_hash_update = _vt_cmd_plobj_hash_update_ip4_route, - .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(), - .obj_type = NMP_OBJECT_TYPE_IP6_ROUTE, - .sizeof_data = sizeof (NMPObjectIP6Route), - .sizeof_public = sizeof (NMPlatformIP6Route), - .obj_type_name = "ip6-route", - .addr_family = AF_INET6, - .rtm_gettype = RTM_GETROUTE, - .signal_type_id = NM_PLATFORM_SIGNAL_ID_IP6_ROUTE, - .signal_type = NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, - .supported_cache_ids = _supported_cache_ids_ipx_route, - .cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_route, - .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip6_route, - .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_ip6_route, - .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_ip6_route, - .cmd_plobj_to_string_id = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_ip6_route_to_string, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_ip6_route_to_string, - .cmd_plobj_hash_update = _vt_cmd_plobj_hash_update_ip6_route, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_ip6_route_cmp_full, - }, - [NMP_OBJECT_TYPE_ROUTING_RULE - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_ROUTING_RULE, - .sizeof_data = sizeof (NMPObjectRoutingRule), - .sizeof_public = sizeof (NMPlatformRoutingRule), - .obj_type_name = "routing-rule", - .rtm_gettype = RTM_GETRULE, - .signal_type_id = NM_PLATFORM_SIGNAL_ID_ROUTING_RULE, - .signal_type = NM_PLATFORM_SIGNAL_ROUTING_RULE_CHANGED, - .supported_cache_ids = _supported_cache_ids_routing_rules, - .cmd_obj_is_alive = _vt_cmd_obj_is_alive_routing_rule, - .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_routing_rule, - .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_routing_rule, - .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_routing_rule, - .cmd_plobj_to_string_id = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_routing_rule_to_string, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_routing_rule_to_string, - .cmd_plobj_hash_update = _vt_cmd_plobj_hash_update_routing_rule, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_routing_rule_cmp_full, - }, - [NMP_OBJECT_TYPE_QDISC - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_QDISC, - .sizeof_data = sizeof (NMPObjectQdisc), - .sizeof_public = sizeof (NMPlatformQdisc), - .obj_type_name = "qdisc", - .rtm_gettype = RTM_GETQDISC, - .signal_type_id = NM_PLATFORM_SIGNAL_ID_QDISC, - .signal_type = NM_PLATFORM_SIGNAL_QDISC_CHANGED, - .supported_cache_ids = _supported_cache_ids_object, - .cmd_obj_is_alive = _vt_cmd_obj_is_alive_qdisc, - .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_qdisc, - .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_qdisc, - .cmd_plobj_to_string_id = _vt_cmd_plobj_to_string_id_qdisc, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_qdisc_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_qdisc_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_qdisc_cmp, - }, - [NMP_OBJECT_TYPE_TFILTER - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_TFILTER, - .sizeof_data = sizeof (NMPObjectTfilter), - .sizeof_public = sizeof (NMPlatformTfilter), - .obj_type_name = "tfilter", - .rtm_gettype = RTM_GETTFILTER, - .signal_type_id = NM_PLATFORM_SIGNAL_ID_TFILTER, - .signal_type = NM_PLATFORM_SIGNAL_TFILTER_CHANGED, - .supported_cache_ids = _supported_cache_ids_object, - .cmd_obj_is_alive = _vt_cmd_obj_is_alive_tfilter, - .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_tfilter, - .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_tfilter, - .cmd_plobj_to_string_id = _vt_cmd_plobj_to_string_id_tfilter, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_tfilter_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_tfilter_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_tfilter_cmp, - }, - [NMP_OBJECT_TYPE_LNK_GRE - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_LNK_GRE, - .sizeof_data = sizeof (NMPObjectLnkGre), - .sizeof_public = sizeof (NMPlatformLnkGre), - .obj_type_name = "gre", - .lnk_link_type = NM_LINK_TYPE_GRE, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_gre_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_gre_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_gre_cmp, - }, - [NMP_OBJECT_TYPE_LNK_GRETAP - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_LNK_GRETAP, - .sizeof_data = sizeof (NMPObjectLnkGre), - .sizeof_public = sizeof (NMPlatformLnkGre), - .obj_type_name = "gretap", - .lnk_link_type = NM_LINK_TYPE_GRETAP, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_gre_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_gre_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_gre_cmp, - }, - [NMP_OBJECT_TYPE_LNK_INFINIBAND - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_LNK_INFINIBAND, - .sizeof_data = sizeof (NMPObjectLnkInfiniband), - .sizeof_public = sizeof (NMPlatformLnkInfiniband), - .obj_type_name = "infiniband", - .lnk_link_type = NM_LINK_TYPE_INFINIBAND, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_infiniband_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_infiniband_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_infiniband_cmp, - }, - [NMP_OBJECT_TYPE_LNK_IP6TNL - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_LNK_IP6TNL, - .sizeof_data = sizeof (NMPObjectLnkIp6Tnl), - .sizeof_public = sizeof (NMPlatformLnkIp6Tnl), - .obj_type_name = "ip6tnl", - .lnk_link_type = NM_LINK_TYPE_IP6TNL, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_ip6tnl_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_ip6tnl_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_ip6tnl_cmp, - }, - [NMP_OBJECT_TYPE_LNK_IP6GRE - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_LNK_IP6GRE, - .sizeof_data = sizeof (NMPObjectLnkIp6Tnl), - .sizeof_public = sizeof (NMPlatformLnkIp6Tnl), - .obj_type_name = "ip6gre", - .lnk_link_type = NM_LINK_TYPE_IP6GRE, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_ip6tnl_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_ip6tnl_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_ip6tnl_cmp, - }, - [NMP_OBJECT_TYPE_LNK_IP6GRETAP - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_LNK_IP6GRETAP, - .sizeof_data = sizeof (NMPObjectLnkIp6Tnl), - .sizeof_public = sizeof (NMPlatformLnkIp6Tnl), - .obj_type_name = "ip6gretap", - .lnk_link_type = NM_LINK_TYPE_IP6GRETAP, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_ip6tnl_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_ip6tnl_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_ip6tnl_cmp, - }, - [NMP_OBJECT_TYPE_LNK_IPIP - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_LNK_IPIP, - .sizeof_data = sizeof (NMPObjectLnkIpIp), - .sizeof_public = sizeof (NMPlatformLnkIpIp), - .obj_type_name = "ipip", - .lnk_link_type = NM_LINK_TYPE_IPIP, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_ipip_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_ipip_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_ipip_cmp, - }, - [NMP_OBJECT_TYPE_LNK_MACSEC - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_LNK_MACSEC, - .sizeof_data = sizeof (NMPObjectLnkMacsec), - .sizeof_public = sizeof (NMPlatformLnkMacsec), - .obj_type_name = "macsec", - .lnk_link_type = NM_LINK_TYPE_MACSEC, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_macsec_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_macsec_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_macsec_cmp, - }, - [NMP_OBJECT_TYPE_LNK_MACVLAN - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_LNK_MACVLAN, - .sizeof_data = sizeof (NMPObjectLnkMacvlan), - .sizeof_public = sizeof (NMPlatformLnkMacvlan), - .obj_type_name = "macvlan", - .lnk_link_type = NM_LINK_TYPE_MACVLAN, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_macvlan_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_macvlan_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_macvlan_cmp, - }, - [NMP_OBJECT_TYPE_LNK_MACVTAP - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_LNK_MACVTAP, - .sizeof_data = sizeof (NMPObjectLnkMacvtap), - .sizeof_public = sizeof (NMPlatformLnkMacvlan), - .obj_type_name = "macvtap", - .lnk_link_type = NM_LINK_TYPE_MACVTAP, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_macvlan_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_macvlan_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_macvlan_cmp, - }, - [NMP_OBJECT_TYPE_LNK_SIT - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_LNK_SIT, - .sizeof_data = sizeof (NMPObjectLnkSit), - .sizeof_public = sizeof (NMPlatformLnkSit), - .obj_type_name = "sit", - .lnk_link_type = NM_LINK_TYPE_SIT, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_sit_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_sit_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_sit_cmp, - }, - [NMP_OBJECT_TYPE_LNK_TUN - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_LNK_TUN, - .sizeof_data = sizeof (NMPObjectLnkTun), - .sizeof_public = sizeof (NMPlatformLnkTun), - .obj_type_name = "tun", - .lnk_link_type = NM_LINK_TYPE_TUN, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_tun_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_tun_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_tun_cmp, - }, - [NMP_OBJECT_TYPE_LNK_VLAN - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_LNK_VLAN, - .sizeof_data = sizeof (NMPObjectLnkVlan), - .sizeof_public = sizeof (NMPlatformLnkVlan), - .obj_type_name = "vlan", - .lnk_link_type = NM_LINK_TYPE_VLAN, - .cmd_obj_hash_update = _vt_cmd_obj_hash_update_lnk_vlan, - .cmd_obj_cmp = _vt_cmd_obj_cmp_lnk_vlan, - .cmd_obj_copy = _vt_cmd_obj_copy_lnk_vlan, - .cmd_obj_dispose = _vt_cmd_obj_dispose_lnk_vlan, - .cmd_obj_to_string = _vt_cmd_obj_to_string_lnk_vlan, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_vlan_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_vlan_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_vlan_cmp, - }, - [NMP_OBJECT_TYPE_LNK_VRF - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_LNK_VRF, - .sizeof_data = sizeof (NMPObjectLnkVrf), - .sizeof_public = sizeof (NMPlatformLnkVrf), - .obj_type_name = "vrf", - .lnk_link_type = NM_LINK_TYPE_VRF, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_vrf_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_vrf_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_vrf_cmp, - }, - - [NMP_OBJECT_TYPE_LNK_VXLAN - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_LNK_VXLAN, - .sizeof_data = sizeof (NMPObjectLnkVxlan), - .sizeof_public = sizeof (NMPlatformLnkVxlan), - .obj_type_name = "vxlan", - .lnk_link_type = NM_LINK_TYPE_VXLAN, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_vxlan_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_vxlan_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_vxlan_cmp, - }, - [NMP_OBJECT_TYPE_LNK_WIREGUARD - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_LNK_WIREGUARD, - .sizeof_data = sizeof (NMPObjectLnkWireGuard), - .sizeof_public = sizeof (NMPlatformLnkWireGuard), - .obj_type_name = "wireguard", - .lnk_link_type = NM_LINK_TYPE_WIREGUARD, - .cmd_obj_hash_update = _vt_cmd_obj_hash_update_lnk_wireguard, - .cmd_obj_cmp = _vt_cmd_obj_cmp_lnk_wireguard, - .cmd_obj_copy = _vt_cmd_obj_copy_lnk_wireguard, - .cmd_obj_dispose = _vt_cmd_obj_dispose_lnk_wireguard, - .cmd_obj_to_string = _vt_cmd_obj_to_string_lnk_wireguard, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_wireguard_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_wireguard_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_wireguard_cmp, - }, + [NMP_OBJECT_TYPE_LINK - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LINK, + .sizeof_data = sizeof(NMPObjectLink), + .sizeof_public = sizeof(NMPlatformLink), + .obj_type_name = "link", + .rtm_gettype = RTM_GETLINK, + .signal_type_id = NM_PLATFORM_SIGNAL_ID_LINK, + .signal_type = NM_PLATFORM_SIGNAL_LINK_CHANGED, + .supported_cache_ids = _supported_cache_ids_link, + .cmd_obj_hash_update = _vt_cmd_obj_hash_update_link, + .cmd_obj_cmp = _vt_cmd_obj_cmp_link, + .cmd_obj_copy = _vt_cmd_obj_copy_link, + .cmd_obj_dispose = _vt_cmd_obj_dispose_link, + .cmd_obj_is_alive = _vt_cmd_obj_is_alive_link, + .cmd_obj_is_visible = _vt_cmd_obj_is_visible_link, + .cmd_obj_to_string = _vt_cmd_obj_to_string_link, + .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_link, + .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_link, + .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_link, + .cmd_plobj_to_string_id = _vt_cmd_plobj_to_string_id_link, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_link_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_link_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_link_cmp, + }, + [NMP_OBJECT_TYPE_IP4_ADDRESS - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_IP4_ADDRESS, + .sizeof_data = sizeof(NMPObjectIP4Address), + .sizeof_public = sizeof(NMPlatformIP4Address), + .obj_type_name = "ip4-address", + .addr_family = AF_INET, + .rtm_gettype = RTM_GETADDR, + .signal_type_id = NM_PLATFORM_SIGNAL_ID_IP4_ADDRESS, + .signal_type = NM_PLATFORM_SIGNAL_IP4_ADDRESS_CHANGED, + .supported_cache_ids = _supported_cache_ids_ipx_address, + .cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_address, + .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip4_address, + .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_ip4_address, + .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_ip4_address, + .cmd_plobj_to_string_id = _vt_cmd_plobj_to_string_id_ip4_address, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_ip4_address_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_ip4_address_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_ip4_address_cmp, + }, + [NMP_OBJECT_TYPE_IP6_ADDRESS + - 1] = {.parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_IP6_ADDRESS, + .sizeof_data = sizeof(NMPObjectIP6Address), + .sizeof_public = sizeof(NMPlatformIP6Address), + .obj_type_name = "ip6-address", + .addr_family = AF_INET6, + .rtm_gettype = RTM_GETADDR, + .signal_type_id = NM_PLATFORM_SIGNAL_ID_IP6_ADDRESS, + .signal_type = NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, + .supported_cache_ids = _supported_cache_ids_ipx_address, + .cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_address, + .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip6_address, + .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_ip6_address, + .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_ip6_address, + .cmd_plobj_to_string_id = _vt_cmd_plobj_to_string_id_ip6_address, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_ip6_address_to_string, + .cmd_plobj_hash_update = + (CmdPlobjHashUpdateFunc) nm_platform_ip6_address_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_ip6_address_cmp}, + [NMP_OBJECT_TYPE_IP4_ROUTE - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_IP4_ROUTE, + .sizeof_data = sizeof(NMPObjectIP4Route), + .sizeof_public = sizeof(NMPlatformIP4Route), + .obj_type_name = "ip4-route", + .addr_family = AF_INET, + .rtm_gettype = RTM_GETROUTE, + .signal_type_id = NM_PLATFORM_SIGNAL_ID_IP4_ROUTE, + .signal_type = NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, + .supported_cache_ids = _supported_cache_ids_ipx_route, + .cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_route, + .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip4_route, + .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_ip4_route, + .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_ip4_route, + .cmd_plobj_to_string_id = (CmdPlobjToStringIdFunc) nm_platform_ip4_route_to_string, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_ip4_route_to_string, + .cmd_plobj_hash_update = _vt_cmd_plobj_hash_update_ip4_route, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_ip4_route_cmp_full, + }, + [NMP_OBJECT_TYPE_IP6_ROUTE - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_IP6_ROUTE, + .sizeof_data = sizeof(NMPObjectIP6Route), + .sizeof_public = sizeof(NMPlatformIP6Route), + .obj_type_name = "ip6-route", + .addr_family = AF_INET6, + .rtm_gettype = RTM_GETROUTE, + .signal_type_id = NM_PLATFORM_SIGNAL_ID_IP6_ROUTE, + .signal_type = NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, + .supported_cache_ids = _supported_cache_ids_ipx_route, + .cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_route, + .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip6_route, + .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_ip6_route, + .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_ip6_route, + .cmd_plobj_to_string_id = (CmdPlobjToStringIdFunc) nm_platform_ip6_route_to_string, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_ip6_route_to_string, + .cmd_plobj_hash_update = _vt_cmd_plobj_hash_update_ip6_route, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_ip6_route_cmp_full, + }, + [NMP_OBJECT_TYPE_ROUTING_RULE - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_ROUTING_RULE, + .sizeof_data = sizeof(NMPObjectRoutingRule), + .sizeof_public = sizeof(NMPlatformRoutingRule), + .obj_type_name = "routing-rule", + .rtm_gettype = RTM_GETRULE, + .signal_type_id = NM_PLATFORM_SIGNAL_ID_ROUTING_RULE, + .signal_type = NM_PLATFORM_SIGNAL_ROUTING_RULE_CHANGED, + .supported_cache_ids = _supported_cache_ids_routing_rules, + .cmd_obj_is_alive = _vt_cmd_obj_is_alive_routing_rule, + .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_routing_rule, + .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_routing_rule, + .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_routing_rule, + .cmd_plobj_to_string_id = (CmdPlobjToStringIdFunc) nm_platform_routing_rule_to_string, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_routing_rule_to_string, + .cmd_plobj_hash_update = _vt_cmd_plobj_hash_update_routing_rule, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_routing_rule_cmp_full, + }, + [NMP_OBJECT_TYPE_QDISC - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_QDISC, + .sizeof_data = sizeof(NMPObjectQdisc), + .sizeof_public = sizeof(NMPlatformQdisc), + .obj_type_name = "qdisc", + .rtm_gettype = RTM_GETQDISC, + .signal_type_id = NM_PLATFORM_SIGNAL_ID_QDISC, + .signal_type = NM_PLATFORM_SIGNAL_QDISC_CHANGED, + .supported_cache_ids = _supported_cache_ids_object, + .cmd_obj_is_alive = _vt_cmd_obj_is_alive_qdisc, + .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_qdisc, + .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_qdisc, + .cmd_plobj_to_string_id = _vt_cmd_plobj_to_string_id_qdisc, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_qdisc_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_qdisc_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_qdisc_cmp, + }, + [NMP_OBJECT_TYPE_TFILTER - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_TFILTER, + .sizeof_data = sizeof(NMPObjectTfilter), + .sizeof_public = sizeof(NMPlatformTfilter), + .obj_type_name = "tfilter", + .rtm_gettype = RTM_GETTFILTER, + .signal_type_id = NM_PLATFORM_SIGNAL_ID_TFILTER, + .signal_type = NM_PLATFORM_SIGNAL_TFILTER_CHANGED, + .supported_cache_ids = _supported_cache_ids_object, + .cmd_obj_is_alive = _vt_cmd_obj_is_alive_tfilter, + .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_tfilter, + .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_tfilter, + .cmd_plobj_to_string_id = _vt_cmd_plobj_to_string_id_tfilter, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_tfilter_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_tfilter_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_tfilter_cmp, + }, + [NMP_OBJECT_TYPE_LNK_BRIDGE - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_BRIDGE, + .sizeof_data = sizeof(NMPObjectLnkBridge), + .sizeof_public = sizeof(NMPlatformLnkBridge), + .obj_type_name = "bridge", + .lnk_link_type = NM_LINK_TYPE_BRIDGE, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_bridge_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_bridge_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_bridge_cmp, + }, + [NMP_OBJECT_TYPE_LNK_GRE - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_GRE, + .sizeof_data = sizeof(NMPObjectLnkGre), + .sizeof_public = sizeof(NMPlatformLnkGre), + .obj_type_name = "gre", + .lnk_link_type = NM_LINK_TYPE_GRE, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_gre_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_gre_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_gre_cmp, + }, + [NMP_OBJECT_TYPE_LNK_GRETAP - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_GRETAP, + .sizeof_data = sizeof(NMPObjectLnkGre), + .sizeof_public = sizeof(NMPlatformLnkGre), + .obj_type_name = "gretap", + .lnk_link_type = NM_LINK_TYPE_GRETAP, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_gre_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_gre_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_gre_cmp, + }, + [NMP_OBJECT_TYPE_LNK_INFINIBAND - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_INFINIBAND, + .sizeof_data = sizeof(NMPObjectLnkInfiniband), + .sizeof_public = sizeof(NMPlatformLnkInfiniband), + .obj_type_name = "infiniband", + .lnk_link_type = NM_LINK_TYPE_INFINIBAND, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_infiniband_to_string, + .cmd_plobj_hash_update = + (CmdPlobjHashUpdateFunc) nm_platform_lnk_infiniband_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_infiniband_cmp, + }, + [NMP_OBJECT_TYPE_LNK_IP6TNL - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_IP6TNL, + .sizeof_data = sizeof(NMPObjectLnkIp6Tnl), + .sizeof_public = sizeof(NMPlatformLnkIp6Tnl), + .obj_type_name = "ip6tnl", + .lnk_link_type = NM_LINK_TYPE_IP6TNL, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_ip6tnl_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_ip6tnl_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_ip6tnl_cmp, + }, + [NMP_OBJECT_TYPE_LNK_IP6GRE - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_IP6GRE, + .sizeof_data = sizeof(NMPObjectLnkIp6Tnl), + .sizeof_public = sizeof(NMPlatformLnkIp6Tnl), + .obj_type_name = "ip6gre", + .lnk_link_type = NM_LINK_TYPE_IP6GRE, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_ip6tnl_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_ip6tnl_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_ip6tnl_cmp, + }, + [NMP_OBJECT_TYPE_LNK_IP6GRETAP - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_IP6GRETAP, + .sizeof_data = sizeof(NMPObjectLnkIp6Tnl), + .sizeof_public = sizeof(NMPlatformLnkIp6Tnl), + .obj_type_name = "ip6gretap", + .lnk_link_type = NM_LINK_TYPE_IP6GRETAP, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_ip6tnl_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_ip6tnl_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_ip6tnl_cmp, + }, + [NMP_OBJECT_TYPE_LNK_IPIP - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_IPIP, + .sizeof_data = sizeof(NMPObjectLnkIpIp), + .sizeof_public = sizeof(NMPlatformLnkIpIp), + .obj_type_name = "ipip", + .lnk_link_type = NM_LINK_TYPE_IPIP, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_ipip_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_ipip_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_ipip_cmp, + }, + [NMP_OBJECT_TYPE_LNK_MACSEC - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_MACSEC, + .sizeof_data = sizeof(NMPObjectLnkMacsec), + .sizeof_public = sizeof(NMPlatformLnkMacsec), + .obj_type_name = "macsec", + .lnk_link_type = NM_LINK_TYPE_MACSEC, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_macsec_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_macsec_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_macsec_cmp, + }, + [NMP_OBJECT_TYPE_LNK_MACVLAN - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_MACVLAN, + .sizeof_data = sizeof(NMPObjectLnkMacvlan), + .sizeof_public = sizeof(NMPlatformLnkMacvlan), + .obj_type_name = "macvlan", + .lnk_link_type = NM_LINK_TYPE_MACVLAN, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_macvlan_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_macvlan_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_macvlan_cmp, + }, + [NMP_OBJECT_TYPE_LNK_MACVTAP - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_MACVTAP, + .sizeof_data = sizeof(NMPObjectLnkMacvtap), + .sizeof_public = sizeof(NMPlatformLnkMacvlan), + .obj_type_name = "macvtap", + .lnk_link_type = NM_LINK_TYPE_MACVTAP, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_macvlan_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_macvlan_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_macvlan_cmp, + }, + [NMP_OBJECT_TYPE_LNK_SIT - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_SIT, + .sizeof_data = sizeof(NMPObjectLnkSit), + .sizeof_public = sizeof(NMPlatformLnkSit), + .obj_type_name = "sit", + .lnk_link_type = NM_LINK_TYPE_SIT, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_sit_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_sit_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_sit_cmp, + }, + [NMP_OBJECT_TYPE_LNK_TUN - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_TUN, + .sizeof_data = sizeof(NMPObjectLnkTun), + .sizeof_public = sizeof(NMPlatformLnkTun), + .obj_type_name = "tun", + .lnk_link_type = NM_LINK_TYPE_TUN, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_tun_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_tun_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_tun_cmp, + }, + [NMP_OBJECT_TYPE_LNK_VLAN - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_VLAN, + .sizeof_data = sizeof(NMPObjectLnkVlan), + .sizeof_public = sizeof(NMPlatformLnkVlan), + .obj_type_name = "vlan", + .lnk_link_type = NM_LINK_TYPE_VLAN, + .cmd_obj_hash_update = _vt_cmd_obj_hash_update_lnk_vlan, + .cmd_obj_cmp = _vt_cmd_obj_cmp_lnk_vlan, + .cmd_obj_copy = _vt_cmd_obj_copy_lnk_vlan, + .cmd_obj_dispose = _vt_cmd_obj_dispose_lnk_vlan, + .cmd_obj_to_string = _vt_cmd_obj_to_string_lnk_vlan, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_vlan_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_vlan_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_vlan_cmp, + }, + [NMP_OBJECT_TYPE_LNK_VRF - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_VRF, + .sizeof_data = sizeof(NMPObjectLnkVrf), + .sizeof_public = sizeof(NMPlatformLnkVrf), + .obj_type_name = "vrf", + .lnk_link_type = NM_LINK_TYPE_VRF, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_vrf_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_vrf_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_vrf_cmp, + }, + [NMP_OBJECT_TYPE_LNK_VXLAN - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_VXLAN, + .sizeof_data = sizeof(NMPObjectLnkVxlan), + .sizeof_public = sizeof(NMPlatformLnkVxlan), + .obj_type_name = "vxlan", + .lnk_link_type = NM_LINK_TYPE_VXLAN, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_vxlan_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_vxlan_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_vxlan_cmp, + }, + [NMP_OBJECT_TYPE_LNK_WIREGUARD - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_WIREGUARD, + .sizeof_data = sizeof(NMPObjectLnkWireGuard), + .sizeof_public = sizeof(NMPlatformLnkWireGuard), + .obj_type_name = "wireguard", + .lnk_link_type = NM_LINK_TYPE_WIREGUARD, + .cmd_obj_hash_update = _vt_cmd_obj_hash_update_lnk_wireguard, + .cmd_obj_cmp = _vt_cmd_obj_cmp_lnk_wireguard, + .cmd_obj_copy = _vt_cmd_obj_copy_lnk_wireguard, + .cmd_obj_dispose = _vt_cmd_obj_dispose_lnk_wireguard, + .cmd_obj_to_string = _vt_cmd_obj_to_string_lnk_wireguard, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_wireguard_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_wireguard_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_wireguard_cmp, + }, }; |