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.h | |
| parent | e7b44ef4c80907346ec7492a09c45277459924fc (diff) | |
New upstream version 1.27.90 upstream/1.27.90
Diffstat (limited to 'src/platform/nmp-object.h')
| -rw-r--r-- | src/platform/nmp-object.h | 1456 |
1 files changed, 793 insertions, 663 deletions
diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h index 44525ed0..58f54dbe 100644 --- a/src/platform/nmp-object.h +++ b/src/platform/nmp-object.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2015 - 2018 Red Hat, Inc. */ @@ -18,90 +18,86 @@ struct udev_device; /* "struct __kernel_timespec" uses "long long", but we use gint64. In practice, * these are the same types. */ -G_STATIC_ASSERT (sizeof (long long) == sizeof (gint64)); +G_STATIC_ASSERT(sizeof(long long) == sizeof(gint64)); typedef struct { - /* like "struct __kernel_timespec". */ - gint64 tv_sec; - gint64 tv_nsec; + /* like "struct __kernel_timespec". */ + gint64 tv_sec; + gint64 tv_nsec; } NMPTimespec64; /*****************************************************************************/ typedef union { - struct sockaddr sa; - struct sockaddr_in in; - struct sockaddr_in6 in6; + struct sockaddr sa; + struct sockaddr_in in; + struct sockaddr_in6 in6; } NMSockAddrUnion; #define NM_SOCK_ADDR_UNION_INIT_UNSPEC \ - { \ - .sa = { \ - .sa_family = AF_UNSPEC, \ - }, \ - } + { \ + .sa = { \ + .sa_family = AF_UNSPEC, \ + }, \ + } -int nm_sock_addr_union_cmp (const NMSockAddrUnion *a, - const NMSockAddrUnion *b); +int nm_sock_addr_union_cmp(const NMSockAddrUnion *a, const NMSockAddrUnion *b); -void nm_sock_addr_union_hash_update (const NMSockAddrUnion *a, - NMHashState *h); +void nm_sock_addr_union_hash_update(const NMSockAddrUnion *a, NMHashState *h); -void nm_sock_addr_union_cpy (NMSockAddrUnion *dst, - gconstpointer src /* unaligned (const NMSockAddrUnion *) */); +void nm_sock_addr_union_cpy(NMSockAddrUnion *dst, + gconstpointer src /* unaligned (const NMSockAddrUnion *) */); -void nm_sock_addr_union_cpy_untrusted (NMSockAddrUnion *dst, - gconstpointer src /* unaligned (const NMSockAddrUnion *) */, - gsize src_len); +void nm_sock_addr_union_cpy_untrusted(NMSockAddrUnion *dst, + gconstpointer src /* unaligned (const NMSockAddrUnion *) */, + gsize src_len); -const char *nm_sock_addr_union_to_string (const NMSockAddrUnion *sa, - char *buf, - gsize len); +const char *nm_sock_addr_union_to_string(const NMSockAddrUnion *sa, char *buf, gsize len); /*****************************************************************************/ typedef struct { - NMIPAddr addr; - guint8 family; - guint8 mask; + NMIPAddr addr; + guint8 family; + guint8 mask; } NMPWireGuardAllowedIP; typedef struct _NMPWireGuardPeer { - NMSockAddrUnion endpoint; + NMSockAddrUnion endpoint; - NMPTimespec64 last_handshake_time; + NMPTimespec64 last_handshake_time; - guint64 rx_bytes; - guint64 tx_bytes; + guint64 rx_bytes; + guint64 tx_bytes; - union { - const NMPWireGuardAllowedIP *allowed_ips; - guint _construct_idx_start; - }; - union { - guint allowed_ips_len; - guint _construct_idx_end; - }; + union { + const NMPWireGuardAllowedIP *allowed_ips; + guint _construct_idx_start; + }; + union { + guint allowed_ips_len; + guint _construct_idx_end; + }; - guint16 persistent_keepalive_interval; + guint16 persistent_keepalive_interval; - guint8 public_key[NMP_WIREGUARD_PUBLIC_KEY_LEN]; - guint8 preshared_key[NMP_WIREGUARD_SYMMETRIC_KEY_LEN]; + guint8 public_key[NMP_WIREGUARD_PUBLIC_KEY_LEN]; + guint8 preshared_key[NMP_WIREGUARD_SYMMETRIC_KEY_LEN]; } NMPWireGuardPeer; /*****************************************************************************/ typedef enum { /*< skip >*/ - NMP_OBJECT_TO_STRING_ID, - NMP_OBJECT_TO_STRING_PUBLIC, - NMP_OBJECT_TO_STRING_ALL, + NMP_OBJECT_TO_STRING_ID, + NMP_OBJECT_TO_STRING_PUBLIC, + NMP_OBJECT_TO_STRING_ALL, } NMPObjectToStringMode; typedef enum { /*< skip >*/ - NMP_CACHE_OPS_UNCHANGED = NM_PLATFORM_SIGNAL_NONE, - NMP_CACHE_OPS_ADDED = NM_PLATFORM_SIGNAL_ADDED, - NMP_CACHE_OPS_UPDATED = NM_PLATFORM_SIGNAL_CHANGED, - NMP_CACHE_OPS_REMOVED = NM_PLATFORM_SIGNAL_REMOVED, + NMP_CACHE_OPS_UNCHANGED = NM_PLATFORM_SIGNAL_NONE, + NMP_CACHE_OPS_ADDED = NM_PLATFORM_SIGNAL_ADDED, + NMP_CACHE_OPS_UPDATED = NM_PLATFORM_SIGNAL_CHANGED, + NMP_CACHE_OPS_REMOVED = NM_PLATFORM_SIGNAL_REMOVED, } NMPCacheOpsType; /* The NMPCacheIdType are the different index types. @@ -121,878 +117,1012 @@ typedef enum { /*< skip >*/ * matching v4/v6 and ifindex -- or maybe not at all if it isn't visible. * */ typedef enum { /*< skip >*/ - NMP_CACHE_ID_TYPE_NONE, - - /* all the objects of a certain type. - * - * This index is special. It is the only one that contains *all* object. - * Other indexes may consider some object as non "partitionable", hence - * they don't track all objects. - * - * Hence, this index type is used when looking at all objects (still - * partitioned by type). - * - * Also, note that links may be considered invisible. This index type - * expose all links, even invisible ones. For addresses/routes, this - * distinction doesn't exist, as all addresses/routes that are alive - * are visible as well. */ - NMP_CACHE_ID_TYPE_OBJECT_TYPE, - - /* index for the link objects by ifname. */ - NMP_CACHE_ID_TYPE_LINK_BY_IFNAME, - - /* indices for the visible default-routes, ignoring ifindex. - * This index only contains two partitions: all visible default-routes, - * separate for IPv4 and IPv6. */ - NMP_CACHE_ID_TYPE_DEFAULT_ROUTES, - - /* all the objects that have an ifindex (by object-type) for an ifindex. */ - NMP_CACHE_ID_TYPE_OBJECT_BY_IFINDEX, - - /* Consider all the destination fields of a route, that is, the ID without the ifindex - * and gateway (meaning: network/plen,metric). - * The reason for this is that `ip route change` can replace an existing route - * and modify its ifindex/gateway. Effectively, that means it deletes an existing - * route and adds a different one (as the ID of the route changes). However, it only - * sends one RTM_NEWADDR notification without notifying about the deletion. We detect - * that by having this index to contain overlapping routes which require special - * cache-resync. */ - NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID, - - /* a filter for objects that track an explicit address family. - * - * Note that currently on NMPObjectRoutingRule is indexed by this filter. */ - NMP_CACHE_ID_TYPE_OBJECT_BY_ADDR_FAMILY, - - __NMP_CACHE_ID_TYPE_MAX, - NMP_CACHE_ID_TYPE_MAX = __NMP_CACHE_ID_TYPE_MAX - 1, + NMP_CACHE_ID_TYPE_NONE, + + /* all the objects of a certain type. + * + * This index is special. It is the only one that contains *all* object. + * Other indexes may consider some object as non "partitionable", hence + * they don't track all objects. + * + * Hence, this index type is used when looking at all objects (still + * partitioned by type). + * + * Also, note that links may be considered invisible. This index type + * expose all links, even invisible ones. For addresses/routes, this + * distinction doesn't exist, as all addresses/routes that are alive + * are visible as well. */ + NMP_CACHE_ID_TYPE_OBJECT_TYPE, + + /* index for the link objects by ifname. */ + NMP_CACHE_ID_TYPE_LINK_BY_IFNAME, + + /* indices for the visible default-routes, ignoring ifindex. + * This index only contains two partitions: all visible default-routes, + * separate for IPv4 and IPv6. */ + NMP_CACHE_ID_TYPE_DEFAULT_ROUTES, + + /* all the objects that have an ifindex (by object-type) for an ifindex. */ + NMP_CACHE_ID_TYPE_OBJECT_BY_IFINDEX, + + /* Consider all the destination fields of a route, that is, the ID without the ifindex + * and gateway (meaning: network/plen,metric). + * The reason for this is that `ip route change` can replace an existing route + * and modify its ifindex/gateway. Effectively, that means it deletes an existing + * route and adds a different one (as the ID of the route changes). However, it only + * sends one RTM_NEWADDR notification without notifying about the deletion. We detect + * that by having this index to contain overlapping routes which require special + * cache-resync. */ + NMP_CACHE_ID_TYPE_ROUTES_BY_WEAK_ID, + + /* a filter for objects that track an explicit address family. + * + * Note that currently on NMPObjectRoutingRule is indexed by this filter. */ + NMP_CACHE_ID_TYPE_OBJECT_BY_ADDR_FAMILY, + + __NMP_CACHE_ID_TYPE_MAX, + NMP_CACHE_ID_TYPE_MAX = __NMP_CACHE_ID_TYPE_MAX - 1, } NMPCacheIdType; typedef struct { - NMDedupMultiObjClass parent; - const char *obj_type_name; - int sizeof_data; - int sizeof_public; - NMPObjectType obj_type; - int addr_family; - int rtm_gettype; - NMPlatformSignalIdType signal_type_id; - const char *signal_type; - - const guint8 *supported_cache_ids; - - /* Only for NMPObjectLnk* types. */ - NMLinkType lnk_link_type; - - void (*cmd_obj_hash_update) (const NMPObject *obj, NMHashState *h); - int (*cmd_obj_cmp) (const NMPObject *obj1, const NMPObject *obj2); - void (*cmd_obj_copy) (NMPObject *dst, const NMPObject *src); - void (*cmd_obj_dispose) (NMPObject *obj); - gboolean (*cmd_obj_is_alive) (const NMPObject *obj); - gboolean (*cmd_obj_is_visible) (const NMPObject *obj); - const char *(*cmd_obj_to_string) (const NMPObject *obj, NMPObjectToStringMode to_string_mode, char *buf, gsize buf_size); - - /* functions that operate on NMPlatformObject */ - void (*cmd_plobj_id_copy) (NMPlatformObject *dst, const NMPlatformObject *src); - int (*cmd_plobj_id_cmp) (const NMPlatformObject *obj1, const NMPlatformObject *obj2); - void (*cmd_plobj_id_hash_update) (const NMPlatformObject *obj, NMHashState *h); - const char *(*cmd_plobj_to_string_id) (const NMPlatformObject *obj, char *buf, gsize buf_size); - const char *(*cmd_plobj_to_string) (const NMPlatformObject *obj, char *buf, gsize len); - void (*cmd_plobj_hash_update) (const NMPlatformObject *obj, NMHashState *h); - int (*cmd_plobj_cmp) (const NMPlatformObject *obj1, const NMPlatformObject *obj2); + NMDedupMultiObjClass parent; + const char * obj_type_name; + const char * signal_type; + const guint8 * supported_cache_ids; + int sizeof_data; + int sizeof_public; + int addr_family; + int rtm_gettype; + NMPObjectType obj_type; + NMPlatformSignalIdType signal_type_id; + + /* Only for NMPObjectLnk* types. */ + NMLinkType lnk_link_type; + + void (*cmd_obj_hash_update)(const NMPObject *obj, NMHashState *h); + int (*cmd_obj_cmp)(const NMPObject *obj1, const NMPObject *obj2); + void (*cmd_obj_copy)(NMPObject *dst, const NMPObject *src); + void (*cmd_obj_dispose)(NMPObject *obj); + gboolean (*cmd_obj_is_alive)(const NMPObject *obj); + gboolean (*cmd_obj_is_visible)(const NMPObject *obj); + const char *(*cmd_obj_to_string)(const NMPObject * obj, + NMPObjectToStringMode to_string_mode, + char * buf, + gsize buf_size); + + /* functions that operate on NMPlatformObject */ + void (*cmd_plobj_id_copy)(NMPlatformObject *dst, const NMPlatformObject *src); + int (*cmd_plobj_id_cmp)(const NMPlatformObject *obj1, const NMPlatformObject *obj2); + void (*cmd_plobj_id_hash_update)(const NMPlatformObject *obj, NMHashState *h); + const char *(*cmd_plobj_to_string_id)(const NMPlatformObject *obj, char *buf, gsize buf_size); + const char *(*cmd_plobj_to_string)(const NMPlatformObject *obj, char *buf, gsize len); + void (*cmd_plobj_hash_update)(const NMPlatformObject *obj, NMHashState *h); + int (*cmd_plobj_cmp)(const NMPlatformObject *obj1, const NMPlatformObject *obj2); } NMPClass; extern const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX]; typedef struct { - NMPlatformLink _public; - - struct { - bool is_in_netlink; - - /* Additional data that depends on the link-type (IFLA_INFO_DATA) */ - const NMPObject *lnk; - } netlink; - - struct { - /* note that "struct udev_device" references the library context - * "struct udev", but doesn't own it. - * - * Hence, the udev.device shall not be used after the library - * context is is destroyed. - * - * In case of NMPObjectLink instances that you obtained from the - * platform cache, that means that you shall no keep references - * to those instances that outlife the NMPlatform instance. - * - * In practice, the requirement is less strict and you'll be even - * fine if the platform instance (and the "struct udev" instance) - * are already destroyed while you still hold onto a reference to - * the NMPObjectLink instance. Just don't make use of udev functions - * that cause access to the udev library context. - */ - struct udev_device *device; - } udev; - - /* Auxiliary data object for Wi-Fi and WPAN */ - GObject *ext_data; - - /* FIXME: not every NMPObjectLink should pay the price for tracking - * the wireguard family id. This should be tracked via ext_data, which - * would be exactly the right place. */ - int wireguard_family_id; + NMPlatformLink _public; + + struct { + bool is_in_netlink; + + /* Additional data that depends on the link-type (IFLA_INFO_DATA) */ + const NMPObject *lnk; + } netlink; + + struct { + /* note that "struct udev_device" references the library context + * "struct udev", but doesn't own it. + * + * Hence, the udev.device shall not be used after the library + * context is destroyed. + * + * In case of NMPObjectLink instances that you obtained from the + * platform cache, that means that you shall no keep references + * to those instances that outlife the NMPlatform instance. + * + * In practice, the requirement is less strict and you'll be even + * fine if the platform instance (and the "struct udev" instance) + * are already destroyed while you still hold onto a reference to + * the NMPObjectLink instance. Just don't make use of udev functions + * that cause access to the udev library context. + */ + struct udev_device *device; + } udev; + + /* Auxiliary data object for Wi-Fi and WPAN */ + GObject *ext_data; + + /* FIXME: not every NMPObjectLink should pay the price for tracking + * the wireguard family id. This should be tracked via ext_data, which + * would be exactly the right place. */ + int wireguard_family_id; } NMPObjectLink; typedef struct { - NMPlatformLnkGre _public; + NMPlatformLnkBridge _public; +} NMPObjectLnkBridge; + +typedef struct { + NMPlatformLnkGre _public; } NMPObjectLnkGre; typedef struct { - NMPlatformLnkInfiniband _public; + NMPlatformLnkInfiniband _public; } NMPObjectLnkInfiniband; typedef struct { - NMPlatformLnkIp6Tnl _public; + NMPlatformLnkIp6Tnl _public; } NMPObjectLnkIp6Tnl; typedef struct { - NMPlatformLnkIpIp _public; + NMPlatformLnkIpIp _public; } NMPObjectLnkIpIp; typedef struct { - NMPlatformLnkMacsec _public; + NMPlatformLnkMacsec _public; } NMPObjectLnkMacsec; typedef struct { - NMPlatformLnkMacvlan _public; + NMPlatformLnkMacvlan _public; } NMPObjectLnkMacvlan; typedef NMPObjectLnkMacvlan NMPObjectLnkMacvtap; typedef struct { - NMPlatformLnkSit _public; + NMPlatformLnkSit _public; } NMPObjectLnkSit; typedef struct { - NMPlatformLnkTun _public; + NMPlatformLnkTun _public; } NMPObjectLnkTun; typedef struct { - NMPlatformLnkVlan _public; + NMPlatformLnkVlan _public; - guint n_ingress_qos_map; - guint n_egress_qos_map; - const NMVlanQosMapping *ingress_qos_map; - const NMVlanQosMapping *egress_qos_map; + guint n_ingress_qos_map; + guint n_egress_qos_map; + const NMVlanQosMapping *ingress_qos_map; + const NMVlanQosMapping *egress_qos_map; } NMPObjectLnkVlan; typedef struct { - NMPlatformLnkVrf _public; + NMPlatformLnkVrf _public; } NMPObjectLnkVrf; typedef struct { - NMPlatformLnkVxlan _public; + NMPlatformLnkVxlan _public; } NMPObjectLnkVxlan; typedef struct { - NMPlatformLnkWireGuard _public; - const NMPWireGuardPeer *peers; - const NMPWireGuardAllowedIP *_allowed_ips_buf; - guint peers_len; - guint _allowed_ips_buf_len; + NMPlatformLnkWireGuard _public; + const NMPWireGuardPeer * peers; + const NMPWireGuardAllowedIP *_allowed_ips_buf; + guint peers_len; + guint _allowed_ips_buf_len; } NMPObjectLnkWireGuard; typedef struct { - NMPlatformIP4Address _public; + NMPlatformIP4Address _public; } NMPObjectIP4Address; typedef struct { - NMPlatformIP4Route _public; + NMPlatformIP4Route _public; } NMPObjectIP4Route; typedef struct { - NMPlatformIP6Address _public; + NMPlatformIP6Address _public; } NMPObjectIP6Address; typedef struct { - NMPlatformIP6Route _public; + NMPlatformIP6Route _public; } NMPObjectIP6Route; typedef struct { - NMPlatformRoutingRule _public; + NMPlatformRoutingRule _public; } NMPObjectRoutingRule; typedef struct { - NMPlatformQdisc _public; + NMPlatformQdisc _public; } NMPObjectQdisc; typedef struct { - NMPlatformTfilter _public; + NMPlatformTfilter _public; } NMPObjectTfilter; struct _NMPObject { - union { - NMDedupMultiObj parent; - const NMPClass *_class; - }; - union { - NMPlatformObject object; + union { + NMDedupMultiObj parent; + const NMPClass *_class; + }; + union { + NMPlatformObject object; - NMPlatformObjWithIfindex obj_with_ifindex; + NMPlatformObjWithIfindex obj_with_ifindex; - NMPlatformLink link; - NMPObjectLink _link; + NMPlatformLink link; + NMPObjectLink _link; - NMPlatformLnkGre lnk_gre; - NMPObjectLnkGre _lnk_gre; + NMPlatformLnkBridge lnk_bridge; + NMPObjectLnkBridge _lnk_bridge; - NMPlatformLnkInfiniband lnk_infiniband; - NMPObjectLnkInfiniband _lnk_infiniband; + NMPlatformLnkGre lnk_gre; + NMPObjectLnkGre _lnk_gre; - NMPlatformLnkIpIp lnk_ipip; - NMPObjectLnkIpIp _lnk_ipip; + NMPlatformLnkInfiniband lnk_infiniband; + NMPObjectLnkInfiniband _lnk_infiniband; - NMPlatformLnkIp6Tnl lnk_ip6tnl; - NMPObjectLnkIp6Tnl _lnk_ip6tnl; + NMPlatformLnkIpIp lnk_ipip; + NMPObjectLnkIpIp _lnk_ipip; - NMPlatformLnkMacsec lnk_macsec; - NMPObjectLnkMacsec _lnk_macsec; + NMPlatformLnkIp6Tnl lnk_ip6tnl; + NMPObjectLnkIp6Tnl _lnk_ip6tnl; - NMPlatformLnkMacvlan lnk_macvlan; - NMPObjectLnkMacvlan _lnk_macvlan; + NMPlatformLnkMacsec lnk_macsec; + NMPObjectLnkMacsec _lnk_macsec; - NMPlatformLnkSit lnk_sit; - NMPObjectLnkSit _lnk_sit; + NMPlatformLnkMacvlan lnk_macvlan; + NMPObjectLnkMacvlan _lnk_macvlan; - NMPlatformLnkTun lnk_tun; - NMPObjectLnkTun _lnk_tun; + NMPlatformLnkSit lnk_sit; + NMPObjectLnkSit _lnk_sit; - NMPlatformLnkVlan lnk_vlan; - NMPObjectLnkVlan _lnk_vlan; + NMPlatformLnkTun lnk_tun; + NMPObjectLnkTun _lnk_tun; - NMPlatformLnkVrf lnk_vrf; - NMPObjectLnkVrf _lnk_vrf; + NMPlatformLnkVlan lnk_vlan; + NMPObjectLnkVlan _lnk_vlan; - NMPlatformLnkVxlan lnk_vxlan; - NMPObjectLnkVxlan _lnk_vxlan; + NMPlatformLnkVrf lnk_vrf; + NMPObjectLnkVrf _lnk_vrf; - NMPlatformLnkWireGuard lnk_wireguard; - NMPObjectLnkWireGuard _lnk_wireguard; + NMPlatformLnkVxlan lnk_vxlan; + NMPObjectLnkVxlan _lnk_vxlan; - NMPlatformIPAddress ip_address; - NMPlatformIPXAddress ipx_address; - NMPlatformIP4Address ip4_address; - NMPlatformIP6Address ip6_address; - NMPObjectIP4Address _ip4_address; - NMPObjectIP6Address _ip6_address; + NMPlatformLnkWireGuard lnk_wireguard; + NMPObjectLnkWireGuard _lnk_wireguard; - NMPlatformIPRoute ip_route; - NMPlatformIPXRoute ipx_route; - NMPlatformIP4Route ip4_route; - NMPlatformIP6Route ip6_route; - NMPObjectIP4Route _ip4_route; - NMPObjectIP6Route _ip6_route; + NMPlatformIPAddress ip_address; + NMPlatformIPXAddress ipx_address; + NMPlatformIP4Address ip4_address; + NMPlatformIP6Address ip6_address; + NMPObjectIP4Address _ip4_address; + NMPObjectIP6Address _ip6_address; - NMPlatformRoutingRule routing_rule; - NMPObjectRoutingRule _routing_rule; + NMPlatformIPRoute ip_route; + NMPlatformIPXRoute ipx_route; + NMPlatformIP4Route ip4_route; + NMPlatformIP6Route ip6_route; + NMPObjectIP4Route _ip4_route; + NMPObjectIP6Route _ip6_route; - NMPlatformQdisc qdisc; - NMPObjectQdisc _qdisc; - NMPlatformTfilter tfilter; - NMPObjectTfilter _tfilter; - }; + NMPlatformRoutingRule routing_rule; + NMPObjectRoutingRule _routing_rule; + + NMPlatformQdisc qdisc; + NMPObjectQdisc _qdisc; + NMPlatformTfilter tfilter; + NMPObjectTfilter _tfilter; + }; }; /*****************************************************************************/ static inline gboolean -NMP_CLASS_IS_VALID (const NMPClass *klass) +NMP_CLASS_IS_VALID(const NMPClass *klass) { - return klass >= &_nmp_classes[0] - && klass <= &_nmp_classes[G_N_ELEMENTS (_nmp_classes)] - && ((((char *) klass) - ((char *) _nmp_classes)) % (sizeof (_nmp_classes[0]))) == 0; + return klass >= &_nmp_classes[0] && klass <= &_nmp_classes[G_N_ELEMENTS(_nmp_classes)] + && ((((char *) klass) - ((char *) _nmp_classes)) % (sizeof(_nmp_classes[0]))) == 0; } static inline const NMPClass * -nmp_class_from_type (NMPObjectType obj_type) +nmp_class_from_type(NMPObjectType obj_type) { - nm_assert (obj_type > 0); - nm_assert (obj_type <= G_N_ELEMENTS (_nmp_classes)); - nm_assert (_nmp_classes[obj_type - 1].obj_type == obj_type); - nm_assert (NMP_CLASS_IS_VALID (&_nmp_classes[obj_type - 1])); + nm_assert(obj_type > 0); + nm_assert(obj_type <= G_N_ELEMENTS(_nmp_classes)); + nm_assert(_nmp_classes[obj_type - 1].obj_type == obj_type); + nm_assert(NMP_CLASS_IS_VALID(&_nmp_classes[obj_type - 1])); - return &_nmp_classes[obj_type - 1]; + return &_nmp_classes[obj_type - 1]; } static inline NMPObject * NMP_OBJECT_UP_CAST(const NMPlatformObject *plobj) { - NMPObject *obj; + NMPObject *obj; - obj = plobj - ? (NMPObject *) ( &(((char *) plobj)[-((int) G_STRUCT_OFFSET (NMPObject, object))]) ) - : NULL; - nm_assert (!obj || (obj->parent._ref_count > 0 && NMP_CLASS_IS_VALID (obj->_class))); - return obj; + obj = plobj ? (NMPObject *) (&(((char *) plobj)[-((int) G_STRUCT_OFFSET(NMPObject, object))])) + : NULL; + nm_assert(!obj || (obj->parent._ref_count > 0 && NMP_CLASS_IS_VALID(obj->_class))); + return obj; } -#define NMP_OBJECT_UP_CAST(plobj) (NMP_OBJECT_UP_CAST ((const NMPlatformObject *) (plobj))) +#define NMP_OBJECT_UP_CAST(plobj) (NMP_OBJECT_UP_CAST((const NMPlatformObject *) (plobj))) static inline gboolean -NMP_OBJECT_IS_VALID (const NMPObject *obj) +NMP_OBJECT_IS_VALID(const NMPObject *obj) { - nm_assert (!obj || ( obj - && obj->parent._ref_count > 0 - && NMP_CLASS_IS_VALID (obj->_class))); + nm_assert(!obj || (obj && obj->parent._ref_count > 0 && NMP_CLASS_IS_VALID(obj->_class))); - /* There isn't really much to check. Either @obj is NULL, or we must - * assume that it points to valid memory. */ - return obj != NULL; + /* There isn't really much to check. Either @obj is NULL, or we must + * assume that it points to valid memory. */ + return obj != NULL; } static inline gboolean -NMP_OBJECT_IS_STACKINIT (const NMPObject *obj) +NMP_OBJECT_IS_STACKINIT(const NMPObject *obj) { - nm_assert (!obj || NMP_OBJECT_IS_VALID (obj)); + nm_assert(!obj || NMP_OBJECT_IS_VALID(obj)); - return obj && obj->parent._ref_count == NM_OBJ_REF_COUNT_STACKINIT; + return obj && obj->parent._ref_count == NM_OBJ_REF_COUNT_STACKINIT; } static inline const NMPClass * -NMP_OBJECT_GET_CLASS (const NMPObject *obj) +NMP_OBJECT_GET_CLASS(const NMPObject *obj) { - nm_assert (NMP_OBJECT_IS_VALID (obj)); + nm_assert(NMP_OBJECT_IS_VALID(obj)); - return obj->_class; + return obj->_class; } static inline NMPObjectType -NMP_OBJECT_GET_TYPE (const NMPObject *obj) +NMP_OBJECT_GET_TYPE(const NMPObject *obj) { - nm_assert (!obj || NMP_OBJECT_IS_VALID (obj)); + nm_assert(!obj || NMP_OBJECT_IS_VALID(obj)); - return obj ? obj->_class->obj_type : NMP_OBJECT_TYPE_UNKNOWN; + return obj ? obj->_class->obj_type : NMP_OBJECT_TYPE_UNKNOWN; } static inline gboolean -_NMP_OBJECT_TYPE_IS_OBJ_WITH_IFINDEX (NMPObjectType obj_type) -{ - 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_QDISC: - - case NMP_OBJECT_TYPE_TFILTER: - - case NMP_OBJECT_TYPE_LNK_GRE: - case NMP_OBJECT_TYPE_LNK_GRETAP: - case NMP_OBJECT_TYPE_LNK_INFINIBAND: - case NMP_OBJECT_TYPE_LNK_IP6TNL: - case NMP_OBJECT_TYPE_LNK_IP6GRE: - case NMP_OBJECT_TYPE_LNK_IP6GRETAP: - case NMP_OBJECT_TYPE_LNK_IPIP: - case NMP_OBJECT_TYPE_LNK_MACSEC: - case NMP_OBJECT_TYPE_LNK_MACVLAN: - case NMP_OBJECT_TYPE_LNK_MACVTAP: - case NMP_OBJECT_TYPE_LNK_SIT: - case NMP_OBJECT_TYPE_LNK_TUN: - case NMP_OBJECT_TYPE_LNK_VLAN: - case NMP_OBJECT_TYPE_LNK_VRF: - case NMP_OBJECT_TYPE_LNK_VXLAN: - case NMP_OBJECT_TYPE_LNK_WIREGUARD: - return TRUE; - - case NMP_OBJECT_TYPE_ROUTING_RULE: - return FALSE; - - case NMP_OBJECT_TYPE_UNKNOWN: - case __NMP_OBJECT_TYPE_LAST: - break; - } - nm_assert_not_reached (); - return FALSE; -} - -#define NMP_OBJECT_CAST_OBJECT(obj) \ - ({ \ - typeof (obj) _obj = (obj); \ - \ - nm_assert ( !_obj \ - || nmp_class_from_type (NMP_OBJECT_GET_TYPE (_obj)))); \ - _obj ? &NM_CONSTCAST (NMPObject, _obj)->object : NULL; \ - }) - -#define NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(obj) \ - ({ \ - typeof (obj) _obj = (obj); \ - \ - nm_assert ( !_obj \ - || _NMP_OBJECT_TYPE_IS_OBJ_WITH_IFINDEX (NMP_OBJECT_GET_TYPE (_obj))); \ - _obj ? &NM_CONSTCAST (NMPObject, _obj)->obj_with_ifindex : NULL; \ - }) - -#define _NMP_OBJECT_CAST(obj, field, ...) \ - ({ \ - typeof (obj) _obj = (obj); \ - \ - nm_assert (!_obj || NM_IN_SET (NMP_OBJECT_GET_TYPE (_obj), __VA_ARGS__)); \ - _obj ? &NM_CONSTCAST (NMPObject, _obj)->field : NULL; \ - }) - -#define NMP_OBJECT_CAST_LINK(obj) _NMP_OBJECT_CAST (obj, link, NMP_OBJECT_TYPE_LINK) -#define NMP_OBJECT_CAST_IP_ADDRESS(obj) _NMP_OBJECT_CAST (obj, ip_address, NMP_OBJECT_TYPE_IP4_ADDRESS, NMP_OBJECT_TYPE_IP6_ADDRESS) -#define NMP_OBJECT_CAST_IPX_ADDRESS(obj) _NMP_OBJECT_CAST (obj, ipx_address, NMP_OBJECT_TYPE_IP4_ADDRESS, NMP_OBJECT_TYPE_IP6_ADDRESS) -#define NMP_OBJECT_CAST_IP4_ADDRESS(obj) _NMP_OBJECT_CAST (obj, ip4_address, NMP_OBJECT_TYPE_IP4_ADDRESS) -#define NMP_OBJECT_CAST_IP6_ADDRESS(obj) _NMP_OBJECT_CAST (obj, ip6_address, NMP_OBJECT_TYPE_IP6_ADDRESS) -#define NMP_OBJECT_CAST_IP_ROUTE(obj) _NMP_OBJECT_CAST (obj, ip_route, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE) -#define NMP_OBJECT_CAST_IPX_ROUTE(obj) _NMP_OBJECT_CAST (obj, ipx_route, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE) -#define NMP_OBJECT_CAST_IP4_ROUTE(obj) _NMP_OBJECT_CAST (obj, ip4_route, NMP_OBJECT_TYPE_IP4_ROUTE) -#define NMP_OBJECT_CAST_IP6_ROUTE(obj) _NMP_OBJECT_CAST (obj, ip6_route, NMP_OBJECT_TYPE_IP6_ROUTE) -#define NMP_OBJECT_CAST_ROUTING_RULE(obj) _NMP_OBJECT_CAST (obj, routing_rule, NMP_OBJECT_TYPE_ROUTING_RULE) -#define NMP_OBJECT_CAST_QDISC(obj) _NMP_OBJECT_CAST (obj, qdisc, NMP_OBJECT_TYPE_QDISC) -#define NMP_OBJECT_CAST_TFILTER(obj) _NMP_OBJECT_CAST (obj, tfilter, NMP_OBJECT_TYPE_TFILTER) -#define NMP_OBJECT_CAST_LNK_WIREGUARD(obj) _NMP_OBJECT_CAST (obj, lnk_wireguard, NMP_OBJECT_TYPE_LNK_WIREGUARD) +_NMP_OBJECT_TYPE_IS_OBJ_WITH_IFINDEX(NMPObjectType obj_type) +{ + 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_QDISC: + + case NMP_OBJECT_TYPE_TFILTER: + + case NMP_OBJECT_TYPE_LNK_BRIDGE: + case NMP_OBJECT_TYPE_LNK_GRE: + case NMP_OBJECT_TYPE_LNK_GRETAP: + case NMP_OBJECT_TYPE_LNK_INFINIBAND: + case NMP_OBJECT_TYPE_LNK_IP6TNL: + case NMP_OBJECT_TYPE_LNK_IP6GRE: + case NMP_OBJECT_TYPE_LNK_IP6GRETAP: + case NMP_OBJECT_TYPE_LNK_IPIP: + case NMP_OBJECT_TYPE_LNK_MACSEC: + case NMP_OBJECT_TYPE_LNK_MACVLAN: + case NMP_OBJECT_TYPE_LNK_MACVTAP: + case NMP_OBJECT_TYPE_LNK_SIT: + case NMP_OBJECT_TYPE_LNK_TUN: + case NMP_OBJECT_TYPE_LNK_VLAN: + case NMP_OBJECT_TYPE_LNK_VRF: + case NMP_OBJECT_TYPE_LNK_VXLAN: + case NMP_OBJECT_TYPE_LNK_WIREGUARD: + return TRUE; + + case NMP_OBJECT_TYPE_ROUTING_RULE: + return FALSE; + + case NMP_OBJECT_TYPE_UNKNOWN: + case __NMP_OBJECT_TYPE_LAST: + break; + } + nm_assert_not_reached(); + return FALSE; +} -static inline const NMPObject * -nmp_object_ref (const NMPObject *obj) +#define NMP_OBJECT_CAST_OBJECT(obj) \ + ({ \ + typeof(obj) _obj = (obj); \ + \ + nm_assert ( !_obj \ + || nmp_class_from_type (NMP_OBJECT_GET_TYPE (_obj)))); \ + _obj ? &NM_CONSTCAST(NMPObject, _obj)->object : NULL; \ + }) + +#define NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(obj) \ + ({ \ + typeof(obj) _obj = (obj); \ + \ + nm_assert(!_obj || _NMP_OBJECT_TYPE_IS_OBJ_WITH_IFINDEX(NMP_OBJECT_GET_TYPE(_obj))); \ + _obj ? &NM_CONSTCAST(NMPObject, _obj)->obj_with_ifindex : NULL; \ + }) + +#define _NMP_OBJECT_CAST(obj, field, ...) \ + ({ \ + typeof(obj) _obj = (obj); \ + \ + nm_assert(!_obj || NM_IN_SET(NMP_OBJECT_GET_TYPE(_obj), __VA_ARGS__)); \ + _obj ? &NM_CONSTCAST(NMPObject, _obj)->field : NULL; \ + }) + +#define NMP_OBJECT_CAST_LINK(obj) _NMP_OBJECT_CAST(obj, link, NMP_OBJECT_TYPE_LINK) +#define NMP_OBJECT_CAST_IP_ADDRESS(obj) \ + _NMP_OBJECT_CAST(obj, ip_address, NMP_OBJECT_TYPE_IP4_ADDRESS, NMP_OBJECT_TYPE_IP6_ADDRESS) +#define NMP_OBJECT_CAST_IPX_ADDRESS(obj) \ + _NMP_OBJECT_CAST(obj, ipx_address, NMP_OBJECT_TYPE_IP4_ADDRESS, NMP_OBJECT_TYPE_IP6_ADDRESS) +#define NMP_OBJECT_CAST_IP4_ADDRESS(obj) \ + _NMP_OBJECT_CAST(obj, ip4_address, NMP_OBJECT_TYPE_IP4_ADDRESS) +#define NMP_OBJECT_CAST_IP6_ADDRESS(obj) \ + _NMP_OBJECT_CAST(obj, ip6_address, NMP_OBJECT_TYPE_IP6_ADDRESS) +#define NMP_OBJECT_CAST_IP_ROUTE(obj) \ + _NMP_OBJECT_CAST(obj, ip_route, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE) +#define NMP_OBJECT_CAST_IPX_ROUTE(obj) \ + _NMP_OBJECT_CAST(obj, ipx_route, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE) +#define NMP_OBJECT_CAST_IP4_ROUTE(obj) _NMP_OBJECT_CAST(obj, ip4_route, NMP_OBJECT_TYPE_IP4_ROUTE) +#define NMP_OBJECT_CAST_IP6_ROUTE(obj) _NMP_OBJECT_CAST(obj, ip6_route, NMP_OBJECT_TYPE_IP6_ROUTE) +#define NMP_OBJECT_CAST_ROUTING_RULE(obj) \ + _NMP_OBJECT_CAST(obj, routing_rule, NMP_OBJECT_TYPE_ROUTING_RULE) +#define NMP_OBJECT_CAST_QDISC(obj) _NMP_OBJECT_CAST(obj, qdisc, NMP_OBJECT_TYPE_QDISC) +#define NMP_OBJECT_CAST_TFILTER(obj) _NMP_OBJECT_CAST(obj, tfilter, NMP_OBJECT_TYPE_TFILTER) +#define NMP_OBJECT_CAST_LNK_WIREGUARD(obj) \ + _NMP_OBJECT_CAST(obj, lnk_wireguard, NMP_OBJECT_TYPE_LNK_WIREGUARD) +#define NMP_OBJECT_CAST_LNK_BRIDGE(obj) \ + _NMP_OBJECT_CAST(obj, lnk_bridge, NMP_OBJECT_TYPE_LNK_BRIDGE) + +static inline int +NMP_OBJECT_TYPE_TO_ADDR_FAMILY(NMPObjectType obj_type) { - if (!obj) { - /* for convenience, allow NULL. */ - return NULL; - } + return nmp_class_from_type(obj_type)->addr_family; +} - /* ref and unref accept const pointers. NMPObject is supposed to be shared - * and kept immutable. Disallowing to take/return a reference to a const - * NMPObject is cumbersome, because callers are precisely expected to - * keep a ref on the otherwise immutable object. */ - g_return_val_if_fail (NMP_OBJECT_IS_VALID (obj), NULL); - g_return_val_if_fail (obj->parent._ref_count != NM_OBJ_REF_COUNT_STACKINIT, NULL); +static inline int +NMP_OBJECT_GET_ADDR_FAMILY(const NMPObject *obj) +{ + return NMP_OBJECT_GET_CLASS(obj)->addr_family; +} - return (const NMPObject *) nm_dedup_multi_obj_ref ((const NMDedupMultiObj *) obj); +static inline const NMPObject * +nmp_object_ref(const NMPObject *obj) +{ + if (!obj) { + /* for convenience, allow NULL. */ + return NULL; + } + + /* ref and unref accept const pointers. NMPObject is supposed to be shared + * and kept immutable. Disallowing to take/return a reference to a const + * NMPObject is cumbersome, because callers are precisely expected to + * keep a ref on the otherwise immutable object. */ + g_return_val_if_fail(NMP_OBJECT_IS_VALID(obj), NULL); + g_return_val_if_fail(obj->parent._ref_count != NM_OBJ_REF_COUNT_STACKINIT, NULL); + + return (const NMPObject *) nm_dedup_multi_obj_ref((const NMDedupMultiObj *) obj); } static inline void -nmp_object_unref (const NMPObject *obj) +nmp_object_unref(const NMPObject *obj) { - if (obj) { - nm_assert (NMP_OBJECT_IS_VALID (obj)); + if (obj) { + nm_assert(NMP_OBJECT_IS_VALID(obj)); - nm_dedup_multi_obj_unref ((const NMDedupMultiObj *) obj); - } + nm_dedup_multi_obj_unref((const NMDedupMultiObj *) obj); + } } -#define nm_clear_nmp_object(ptr) \ - ({ \ - typeof (ptr) _ptr = (ptr); \ - typeof (*_ptr) _pptr; \ - gboolean _changed = FALSE; \ - \ - if ( _ptr \ - && (_pptr = *_ptr)) { \ - *_ptr = NULL; \ - nmp_object_unref (_pptr); \ - _changed = TRUE; \ - } \ - _changed; \ - }) +#define nm_clear_nmp_object(ptr) \ + ({ \ + typeof(ptr) _ptr = (ptr); \ + typeof(*_ptr) _pptr; \ + gboolean _changed = FALSE; \ + \ + if (_ptr && (_pptr = *_ptr)) { \ + *_ptr = NULL; \ + nmp_object_unref(_pptr); \ + _changed = TRUE; \ + } \ + _changed; \ + }) + +static inline gboolean +nmp_object_ref_set(const NMPObject **pp, const NMPObject *obj) +{ + gboolean _changed = FALSE; + const NMPObject *p; + + nm_assert(!pp || !*pp || NMP_OBJECT_IS_VALID(*pp)); + nm_assert(!obj || NMP_OBJECT_IS_VALID(obj)); + + if (pp && ((p = *pp) != obj)) { + nmp_object_ref(obj); + *pp = obj; + nmp_object_unref(p); + _changed = TRUE; + } + return _changed; +} -NMPObject *nmp_object_new (NMPObjectType obj_type, gconstpointer plobj); -NMPObject *nmp_object_new_link (int ifindex); +NMPObject *nmp_object_new(NMPObjectType obj_type, gconstpointer plobj); +NMPObject *nmp_object_new_link(int ifindex); -const NMPObject *nmp_object_stackinit (NMPObject *obj, NMPObjectType obj_type, gconstpointer plobj); +const NMPObject *nmp_object_stackinit(NMPObject *obj, NMPObjectType obj_type, gconstpointer plobj); static inline NMPObject * -nmp_object_stackinit_obj (NMPObject *obj, const NMPObject *src) +nmp_object_stackinit_obj(NMPObject *obj, const NMPObject *src) { - return obj == src - ? obj - : (NMPObject *) nmp_object_stackinit (obj, NMP_OBJECT_GET_TYPE (src), &src->object); + return obj == src + ? obj + : (NMPObject *) nmp_object_stackinit(obj, NMP_OBJECT_GET_TYPE(src), &src->object); } -const NMPObject *nmp_object_stackinit_id (NMPObject *obj, const NMPObject *src); -const NMPObject *nmp_object_stackinit_id_link (NMPObject *obj, int ifindex); -const NMPObject *nmp_object_stackinit_id_ip4_address (NMPObject *obj, int ifindex, guint32 address, guint8 plen, guint32 peer_address); -const NMPObject *nmp_object_stackinit_id_ip6_address (NMPObject *obj, int ifindex, const struct in6_addr *address); - -const char *nmp_object_to_string (const NMPObject *obj, NMPObjectToStringMode to_string_mode, char *buf, gsize buf_size); -void nmp_object_hash_update (const NMPObject *obj, NMHashState *h); -int nmp_object_cmp (const NMPObject *obj1, const NMPObject *obj2); +const NMPObject *nmp_object_stackinit_id(NMPObject *obj, const NMPObject *src); +const NMPObject *nmp_object_stackinit_id_link(NMPObject *obj, int ifindex); +const NMPObject *nmp_object_stackinit_id_ip4_address(NMPObject *obj, + int ifindex, + guint32 address, + guint8 plen, + guint32 peer_address); +const NMPObject * +nmp_object_stackinit_id_ip6_address(NMPObject *obj, int ifindex, const struct in6_addr *address); + +const char *nmp_object_to_string(const NMPObject * obj, + NMPObjectToStringMode to_string_mode, + char * buf, + gsize buf_size); +void nmp_object_hash_update(const NMPObject *obj, NMHashState *h); +int nmp_object_cmp(const NMPObject *obj1, const NMPObject *obj2); static inline gboolean -nmp_object_equal (const NMPObject *obj1, const NMPObject *obj2) +nmp_object_equal(const NMPObject *obj1, const NMPObject *obj2) { - return nmp_object_cmp (obj1, obj2) == 0; + return nmp_object_cmp(obj1, obj2) == 0; } -void nmp_object_copy (NMPObject *dst, const NMPObject *src, gboolean id_only); -NMPObject *nmp_object_clone (const NMPObject *obj, gboolean id_only); +void nmp_object_copy(NMPObject *dst, const NMPObject *src, gboolean id_only); +NMPObject *nmp_object_clone(const NMPObject *obj, gboolean id_only); -int nmp_object_id_cmp (const NMPObject *obj1, const NMPObject *obj2); -void nmp_object_id_hash_update (const NMPObject *obj, NMHashState *h); -guint nmp_object_id_hash (const NMPObject *obj); +int nmp_object_id_cmp(const NMPObject *obj1, const NMPObject *obj2); +void nmp_object_id_hash_update(const NMPObject *obj, NMHashState *h); +guint nmp_object_id_hash(const NMPObject *obj); static inline gboolean -nmp_object_id_equal (const NMPObject *obj1, const NMPObject *obj2) +nmp_object_id_equal(const NMPObject *obj1, const NMPObject *obj2) { - return nmp_object_id_cmp (obj1, obj2) == 0; + return nmp_object_id_cmp(obj1, obj2) == 0; } -gboolean nmp_object_is_alive (const NMPObject *obj); -gboolean nmp_object_is_visible (const NMPObject *obj); +guint nmp_object_indirect_id_hash(gconstpointer a); +gboolean nmp_object_indirect_id_equal(gconstpointer a, gconstpointer b); + +gboolean nmp_object_is_alive(const NMPObject *obj); +gboolean nmp_object_is_visible(const NMPObject *obj); -void _nmp_object_fixup_link_udev_fields (NMPObject **obj_new, NMPObject *obj_orig, gboolean use_udev); +void +_nmp_object_fixup_link_udev_fields(NMPObject **obj_new, NMPObject *obj_orig, gboolean use_udev); static inline void -_nm_auto_nmpobj_cleanup (gpointer p) +_nm_auto_nmpobj_cleanup(gpointer p) { - nmp_object_unref (*((const NMPObject **) p)); + nmp_object_unref(*((const NMPObject **) p)); } #define nm_auto_nmpobj nm_auto(_nm_auto_nmpobj_cleanup) typedef struct _NMPCache NMPCache; -typedef void (*NMPCachePreHook) (NMPCache *cache, const NMPObject *old, const NMPObject *new, NMPCacheOpsType ops_type, gpointer user_data); -typedef gboolean (*NMPObjectMatchFn) (const NMPObject *obj, gpointer user_data); - -const NMDedupMultiEntry *nmp_cache_lookup_entry (const NMPCache *cache, - const NMPObject *obj); -const NMDedupMultiEntry *nmp_cache_lookup_entry_with_idx_type (const NMPCache *cache, - NMPCacheIdType cache_id_type, - const NMPObject *obj); -const NMDedupMultiEntry *nmp_cache_lookup_entry_link (const NMPCache *cache, - int ifindex); -const NMPObject *nmp_cache_lookup_obj (const NMPCache *cache, - const NMPObject *obj); -const NMPObject *nmp_cache_lookup_link (const NMPCache *cache, - int ifindex); +typedef void (*NMPCachePreHook)(NMPCache * cache, + const NMPObject *old, + const NMPObject *new, + NMPCacheOpsType ops_type, + gpointer user_data); +typedef gboolean (*NMPObjectMatchFn)(const NMPObject *obj, gpointer user_data); + +const NMDedupMultiEntry *nmp_cache_lookup_entry(const NMPCache *cache, const NMPObject *obj); +const NMDedupMultiEntry *nmp_cache_lookup_entry_with_idx_type(const NMPCache * cache, + NMPCacheIdType cache_id_type, + const NMPObject *obj); +const NMDedupMultiEntry *nmp_cache_lookup_entry_link(const NMPCache *cache, int ifindex); +const NMPObject * nmp_cache_lookup_obj(const NMPCache *cache, const NMPObject *obj); +const NMPObject * nmp_cache_lookup_link(const NMPCache *cache, int ifindex); typedef struct _NMPLookup NMPLookup; struct _NMPLookup { - NMPCacheIdType cache_id_type; - NMPObject selector_obj; + NMPCacheIdType cache_id_type; + NMPObject selector_obj; }; -const NMDedupMultiHeadEntry *nmp_cache_lookup_all (const NMPCache *cache, - NMPCacheIdType cache_id_type, - const NMPObject *select_obj); +const NMDedupMultiHeadEntry *nmp_cache_lookup_all(const NMPCache * cache, + NMPCacheIdType cache_id_type, + const NMPObject *select_obj); static inline const NMDedupMultiHeadEntry * -nmp_cache_lookup (const NMPCache *cache, - const NMPLookup *lookup) +nmp_cache_lookup(const NMPCache *cache, const NMPLookup *lookup) { - return nmp_cache_lookup_all (cache, lookup->cache_id_type, &lookup->selector_obj); + return nmp_cache_lookup_all(cache, lookup->cache_id_type, &lookup->selector_obj); } -const NMPLookup *nmp_lookup_init_obj_type (NMPLookup *lookup, - NMPObjectType obj_type); -const NMPLookup *nmp_lookup_init_link_by_ifname (NMPLookup *lookup, - const char *ifname); -const NMPLookup *nmp_lookup_init_object (NMPLookup *lookup, - NMPObjectType obj_type, - int ifindex); -const NMPLookup *nmp_lookup_init_route_default (NMPLookup *lookup, - NMPObjectType obj_type); -const NMPLookup *nmp_lookup_init_route_by_weak_id (NMPLookup *lookup, - const NMPObject *obj); -const NMPLookup *nmp_lookup_init_ip4_route_by_weak_id (NMPLookup *lookup, - in_addr_t network, - guint plen, - guint32 metric, - guint8 tos); -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); -const NMPLookup *nmp_lookup_init_object_by_addr_family (NMPLookup *lookup, - NMPObjectType obj_type, - int addr_family); - -GArray *nmp_cache_lookup_to_array (const NMDedupMultiHeadEntry *head_entry, - NMPObjectType obj_type, - gboolean visible_only); +const NMPLookup *nmp_lookup_init_obj_type(NMPLookup *lookup, NMPObjectType obj_type); +const NMPLookup *nmp_lookup_init_link_by_ifname(NMPLookup *lookup, const char *ifname); +const NMPLookup *nmp_lookup_init_object(NMPLookup *lookup, NMPObjectType obj_type, int ifindex); +const NMPLookup *nmp_lookup_init_route_default(NMPLookup *lookup, NMPObjectType obj_type); +const NMPLookup *nmp_lookup_init_route_by_weak_id(NMPLookup *lookup, const NMPObject *obj); +const NMPLookup *nmp_lookup_init_ip4_route_by_weak_id(NMPLookup *lookup, + in_addr_t network, + guint plen, + guint32 metric, + guint8 tos); +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); +const NMPLookup * +nmp_lookup_init_object_by_addr_family(NMPLookup *lookup, NMPObjectType obj_type, int addr_family); + +GArray *nmp_cache_lookup_to_array(const NMDedupMultiHeadEntry *head_entry, + NMPObjectType obj_type, + gboolean visible_only); static inline gboolean -nmp_cache_iter_next (NMDedupMultiIter *iter, const NMPObject **out_obj) +nmp_cache_iter_next(NMDedupMultiIter *iter, const NMPObject **out_obj) { - gboolean has_next; + gboolean has_next; - has_next = nm_dedup_multi_iter_next (iter); - nm_assert (!has_next || NMP_OBJECT_IS_VALID (iter->current->obj)); - if (out_obj) - *out_obj = has_next ? iter->current->obj : NULL; - return has_next; + has_next = nm_dedup_multi_iter_next(iter); + nm_assert(!has_next || NMP_OBJECT_IS_VALID(iter->current->obj)); + if (out_obj) + *out_obj = has_next ? iter->current->obj : NULL; + return has_next; } static inline gboolean -nmp_cache_iter_next_link (NMDedupMultiIter *iter, const NMPlatformLink **out_obj) +nmp_cache_iter_next_link(NMDedupMultiIter *iter, const NMPlatformLink **out_obj) { - gboolean has_next; + gboolean has_next; - has_next = nm_dedup_multi_iter_next (iter); - nm_assert (!has_next || NMP_OBJECT_GET_TYPE (iter->current->obj) == NMP_OBJECT_TYPE_LINK); - if (out_obj) - *out_obj = has_next ? &(((const NMPObject *) iter->current->obj)->link) : NULL; - return has_next; + has_next = nm_dedup_multi_iter_next(iter); + nm_assert(!has_next || NMP_OBJECT_GET_TYPE(iter->current->obj) == NMP_OBJECT_TYPE_LINK); + if (out_obj) + *out_obj = has_next ? &(((const NMPObject *) iter->current->obj)->link) : NULL; + return has_next; } #define nmp_cache_iter_for_each(iter, head, obj) \ - for (nm_dedup_multi_iter_init ((iter), \ - (head)); \ - nmp_cache_iter_next ((iter), (obj)); \ - ) + for (nm_dedup_multi_iter_init((iter), (head)); nmp_cache_iter_next((iter), (obj));) #define nmp_cache_iter_for_each_link(iter, head, obj) \ - for (nm_dedup_multi_iter_init ((iter), \ - (head)); \ - nmp_cache_iter_next_link ((iter), (obj)); \ - ) - -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); - -gboolean nmp_cache_link_connected_for_slave (int ifindex_master, const NMPObject *slave); -gboolean nmp_cache_link_connected_needs_toggle (const NMPCache *cache, const NMPObject *master, const NMPObject *potential_slave, const NMPObject *ignore_slave); -const NMPObject *nmp_cache_link_connected_needs_toggle_by_ifindex (const NMPCache *cache, int master_ifindex, const NMPObject *potential_slave, const NMPObject *ignore_slave); - -gboolean nmp_cache_use_udev_get (const NMPCache *cache); - -void ASSERT_nmp_cache_is_consistent (const NMPCache *cache); - -NMPCacheOpsType nmp_cache_remove (NMPCache *cache, - const NMPObject *obj_needle, - gboolean equals_by_ptr, - gboolean only_dirty, - const NMPObject **out_obj_old); -NMPCacheOpsType nmp_cache_remove_netlink (NMPCache *cache, - const NMPObject *obj_needle, - const NMPObject **out_obj_old, - const NMPObject **out_obj_new); -NMPCacheOpsType nmp_cache_update_netlink (NMPCache *cache, - NMPObject *obj_hand_over, - gboolean is_dump, - const NMPObject **out_obj_old, - const NMPObject **out_obj_new); -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); -NMPCacheOpsType nmp_cache_update_link_udev (NMPCache *cache, - int ifindex, - struct udev_device *udevice, - const NMPObject **out_obj_old, - const NMPObject **out_obj_new); -NMPCacheOpsType nmp_cache_update_link_master_connected (NMPCache *cache, - int ifindex, - const NMPObject **out_obj_old, - const NMPObject **out_obj_new); + for (nm_dedup_multi_iter_init((iter), (head)); nmp_cache_iter_next_link((iter), (obj));) + +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); + +gboolean nmp_cache_link_connected_for_slave(int ifindex_master, const NMPObject *slave); +gboolean nmp_cache_link_connected_needs_toggle(const NMPCache * cache, + const NMPObject *master, + const NMPObject *potential_slave, + const NMPObject *ignore_slave); +const NMPObject *nmp_cache_link_connected_needs_toggle_by_ifindex(const NMPCache * cache, + int master_ifindex, + const NMPObject *potential_slave, + const NMPObject *ignore_slave); + +gboolean nmp_cache_use_udev_get(const NMPCache *cache); + +void nmtst_assert_nmp_cache_is_consistent(const NMPCache *cache); + +NMPCacheOpsType nmp_cache_remove(NMPCache * cache, + const NMPObject * obj_needle, + gboolean equals_by_ptr, + gboolean only_dirty, + const NMPObject **out_obj_old); +NMPCacheOpsType nmp_cache_remove_netlink(NMPCache * cache, + const NMPObject * obj_needle, + const NMPObject **out_obj_old, + const NMPObject **out_obj_new); +NMPCacheOpsType nmp_cache_update_netlink(NMPCache * cache, + NMPObject * obj_hand_over, + gboolean is_dump, + const NMPObject **out_obj_old, + const NMPObject **out_obj_new); +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); +NMPCacheOpsType nmp_cache_update_link_udev(NMPCache * cache, + int ifindex, + struct udev_device *udevice, + const NMPObject ** out_obj_old, + const NMPObject ** out_obj_new); +NMPCacheOpsType nmp_cache_update_link_master_connected(NMPCache * cache, + int ifindex, + const NMPObject **out_obj_old, + const NMPObject **out_obj_new); static inline const NMDedupMultiEntry * -nmp_cache_reresolve_main_entry (NMPCache *cache, - const NMDedupMultiEntry *entry, - const NMPLookup *lookup) +nmp_cache_reresolve_main_entry(NMPCache * cache, + const NMDedupMultiEntry *entry, + const NMPLookup * lookup) { - const NMDedupMultiEntry *main_entry; + const NMDedupMultiEntry *main_entry; - nm_assert (cache); - nm_assert (entry); - nm_assert (lookup); + nm_assert(cache); + nm_assert(entry); + nm_assert(lookup); - if (lookup->cache_id_type == NMP_CACHE_ID_TYPE_OBJECT_TYPE) { - nm_assert (entry == nmp_cache_lookup_entry (cache, entry->obj)); - return entry; - } + if (lookup->cache_id_type == NMP_CACHE_ID_TYPE_OBJECT_TYPE) { + nm_assert(entry == nmp_cache_lookup_entry(cache, entry->obj)); + return entry; + } - /* we only track the dirty flag for the OBJECT-TYPE index. That means, - * for other lookup types we need to check the dirty flag of the main-entry. */ - main_entry = nmp_cache_lookup_entry (cache, entry->obj); + /* we only track the dirty flag for the OBJECT-TYPE index. That means, + * for other lookup types we need to check the dirty flag of the main-entry. */ + main_entry = nmp_cache_lookup_entry(cache, entry->obj); - nm_assert (main_entry); - nm_assert (main_entry->obj == entry->obj); + nm_assert(main_entry); + nm_assert(main_entry->obj == entry->obj); - return main_entry; + return main_entry; } -void nmp_cache_dirty_set_all_main (NMPCache *cache, - const NMPLookup *lookup); +void nmp_cache_dirty_set_all_main(NMPCache *cache, const NMPLookup *lookup); -NMPCache *nmp_cache_new (NMDedupMultiIndex *multi_idx, gboolean use_udev); -void nmp_cache_free (NMPCache *cache); +NMPCache *nmp_cache_new(NMDedupMultiIndex *multi_idx, gboolean use_udev); +void nmp_cache_free(NMPCache *cache); static inline void -ASSERT_nmp_cache_ops (const NMPCache *cache, - NMPCacheOpsType ops_type, - const NMPObject *obj_old, - const NMPObject *obj_new) +ASSERT_nmp_cache_ops(const NMPCache * cache, + NMPCacheOpsType ops_type, + const NMPObject *obj_old, + const NMPObject *obj_new) { #if NM_MORE_ASSERTS - nm_assert (cache); - nm_assert (obj_old || obj_new); - nm_assert (!obj_old || ( NMP_OBJECT_IS_VALID (obj_old) - && !NMP_OBJECT_IS_STACKINIT (obj_old) - && nmp_object_is_alive (obj_old))); - nm_assert (!obj_new || ( NMP_OBJECT_IS_VALID (obj_new) - && !NMP_OBJECT_IS_STACKINIT (obj_new) - && nmp_object_is_alive (obj_new))); - - switch (ops_type) { - case NMP_CACHE_OPS_UNCHANGED: - nm_assert (obj_old == obj_new); - break; - case NMP_CACHE_OPS_ADDED: - nm_assert (!obj_old && obj_new); - break; - case NMP_CACHE_OPS_UPDATED: - nm_assert (obj_old && obj_new && obj_old != obj_new); - break; - case NMP_CACHE_OPS_REMOVED: - nm_assert (obj_old && !obj_new); - break; - default: - nm_assert_not_reached (); - } - - nm_assert (obj_new == NULL || obj_old == NULL || nmp_object_id_equal (obj_new, obj_old)); - nm_assert (!obj_old || !obj_new || NMP_OBJECT_GET_CLASS (obj_old) == NMP_OBJECT_GET_CLASS (obj_new)); - - nm_assert (obj_new == nmp_cache_lookup_obj (cache, obj_new ?: obj_old)); + nm_assert(cache); + nm_assert(obj_old || obj_new); + nm_assert(!obj_old + || (NMP_OBJECT_IS_VALID(obj_old) && !NMP_OBJECT_IS_STACKINIT(obj_old) + && nmp_object_is_alive(obj_old))); + nm_assert(!obj_new + || (NMP_OBJECT_IS_VALID(obj_new) && !NMP_OBJECT_IS_STACKINIT(obj_new) + && nmp_object_is_alive(obj_new))); + + switch (ops_type) { + case NMP_CACHE_OPS_UNCHANGED: + nm_assert(obj_old == obj_new); + break; + case NMP_CACHE_OPS_ADDED: + nm_assert(!obj_old && obj_new); + break; + case NMP_CACHE_OPS_UPDATED: + nm_assert(obj_old && obj_new && obj_old != obj_new); + break; + case NMP_CACHE_OPS_REMOVED: + nm_assert(obj_old && !obj_new); + break; + default: + nm_assert_not_reached(); + } + + nm_assert(obj_new == NULL || obj_old == NULL || nmp_object_id_equal(obj_new, obj_old)); + nm_assert(!obj_old || !obj_new + || NMP_OBJECT_GET_CLASS(obj_old) == NMP_OBJECT_GET_CLASS(obj_new)); + + nm_assert(obj_new == nmp_cache_lookup_obj(cache, obj_new ?: obj_old)); #endif } -const NMDedupMultiHeadEntry *nm_platform_lookup_all (NMPlatform *platform, - NMPCacheIdType cache_id_type, - const NMPObject *obj); +const NMDedupMultiHeadEntry * +nm_platform_lookup_all(NMPlatform *platform, NMPCacheIdType cache_id_type, const NMPObject *obj); -const NMDedupMultiEntry *nm_platform_lookup_entry (NMPlatform *platform, - NMPCacheIdType cache_id_type, - const NMPObject *obj); +const NMDedupMultiEntry * +nm_platform_lookup_entry(NMPlatform *platform, NMPCacheIdType cache_id_type, const NMPObject *obj); static inline const NMPObject * -nm_platform_lookup_obj (NMPlatform *platform, - NMPCacheIdType cache_id_type, - const NMPObject *obj) +nm_platform_lookup_obj(NMPlatform *platform, NMPCacheIdType cache_id_type, const NMPObject *obj) { - return nm_dedup_multi_entry_get_obj (nm_platform_lookup_entry (platform, - cache_id_type, - obj)); + return nm_dedup_multi_entry_get_obj(nm_platform_lookup_entry(platform, cache_id_type, obj)); } static inline const NMDedupMultiHeadEntry * -nm_platform_lookup_obj_type (NMPlatform *platform, - NMPObjectType obj_type) +nm_platform_lookup_obj_type(NMPlatform *platform, NMPObjectType obj_type) { - NMPLookup lookup; + NMPLookup lookup; - nmp_lookup_init_obj_type (&lookup, obj_type); - return nm_platform_lookup (platform, &lookup); + nmp_lookup_init_obj_type(&lookup, obj_type); + return nm_platform_lookup(platform, &lookup); } static inline const NMDedupMultiHeadEntry * -nm_platform_lookup_link_by_ifname (NMPlatform *platform, - const char *ifname) +nm_platform_lookup_link_by_ifname(NMPlatform *platform, const char *ifname) { - NMPLookup lookup; + NMPLookup lookup; - nmp_lookup_init_link_by_ifname (&lookup, ifname); - return nm_platform_lookup (platform, &lookup); + nmp_lookup_init_link_by_ifname(&lookup, ifname); + return nm_platform_lookup(platform, &lookup); } static inline const NMDedupMultiHeadEntry * -nm_platform_lookup_object (NMPlatform *platform, - NMPObjectType obj_type, - int ifindex) +nm_platform_lookup_object(NMPlatform *platform, NMPObjectType obj_type, int ifindex) { - NMPLookup lookup; + NMPLookup lookup; - nmp_lookup_init_object (&lookup, obj_type, ifindex); - return nm_platform_lookup (platform, &lookup); + nmp_lookup_init_object(&lookup, obj_type, ifindex); + return nm_platform_lookup(platform, &lookup); } static inline GPtrArray * -nm_platform_lookup_object_clone (NMPlatform *platform, - NMPObjectType obj_type, - int ifindex, - NMPObjectPredicateFunc predicate, - gpointer user_data) +nm_platform_lookup_object_clone(NMPlatform * platform, + NMPObjectType obj_type, + int ifindex, + NMPObjectPredicateFunc predicate, + gpointer user_data) { - NMPLookup lookup; + NMPLookup lookup; - nmp_lookup_init_object (&lookup, obj_type, ifindex); - return nm_platform_lookup_clone (platform, &lookup, predicate, user_data); + nmp_lookup_init_object(&lookup, obj_type, ifindex); + return nm_platform_lookup_clone(platform, &lookup, predicate, user_data); } static inline const NMDedupMultiHeadEntry * -nm_platform_lookup_route_default (NMPlatform *platform, - NMPObjectType obj_type) +nm_platform_lookup_route_default(NMPlatform *platform, NMPObjectType obj_type) { - NMPLookup lookup; + NMPLookup lookup; - nmp_lookup_init_route_default (&lookup, obj_type); - return nm_platform_lookup (platform, &lookup); + nmp_lookup_init_route_default(&lookup, obj_type); + return nm_platform_lookup(platform, &lookup); } static inline GPtrArray * -nm_platform_lookup_route_default_clone (NMPlatform *platform, - NMPObjectType obj_type, - NMPObjectPredicateFunc predicate, - gpointer user_data) +nm_platform_lookup_route_default_clone(NMPlatform * platform, + NMPObjectType obj_type, + NMPObjectPredicateFunc predicate, + gpointer user_data) { - NMPLookup lookup; + NMPLookup lookup; - nmp_lookup_init_route_default (&lookup, obj_type); - return nm_platform_lookup_clone (platform, &lookup, predicate, user_data); + nmp_lookup_init_route_default(&lookup, obj_type); + return nm_platform_lookup_clone(platform, &lookup, predicate, user_data); } static inline const NMDedupMultiHeadEntry * -nm_platform_lookup_ip4_route_by_weak_id (NMPlatform *platform, - in_addr_t network, - guint plen, - guint32 metric, - guint8 tos) +nm_platform_lookup_ip4_route_by_weak_id(NMPlatform *platform, + in_addr_t network, + guint plen, + guint32 metric, + guint8 tos) { - NMPLookup lookup; + NMPLookup lookup; - nmp_lookup_init_ip4_route_by_weak_id (&lookup, network, plen, metric, tos); - return nm_platform_lookup (platform, &lookup); + nmp_lookup_init_ip4_route_by_weak_id(&lookup, network, plen, metric, tos); + return nm_platform_lookup(platform, &lookup); } static inline const NMDedupMultiHeadEntry * -nm_platform_lookup_ip6_route_by_weak_id (NMPlatform *platform, - const struct in6_addr *network, - guint plen, - guint32 metric, - const struct in6_addr *src, - guint8 src_plen) +nm_platform_lookup_ip6_route_by_weak_id(NMPlatform * platform, + const struct in6_addr *network, + guint plen, + guint32 metric, + const struct in6_addr *src, + guint8 src_plen) { - NMPLookup lookup; + NMPLookup lookup; - nmp_lookup_init_ip6_route_by_weak_id (&lookup, network, plen, metric, src, src_plen); - return nm_platform_lookup (platform, &lookup); + nmp_lookup_init_ip6_route_by_weak_id(&lookup, network, plen, metric, src, src_plen); + return nm_platform_lookup(platform, &lookup); } static inline const NMDedupMultiHeadEntry * -nm_platform_lookup_object_by_addr_family (NMPlatform *platform, - NMPObjectType obj_type, - int addr_family) +nm_platform_lookup_object_by_addr_family(NMPlatform * platform, + NMPObjectType obj_type, + int addr_family) +{ + NMPLookup lookup; + + nmp_lookup_init_object_by_addr_family(&lookup, obj_type, addr_family); + return nm_platform_lookup(platform, &lookup); +} + +/*****************************************************************************/ + +static inline const char * +nmp_object_link_get_ifname(const NMPObject *obj) +{ + if (!obj) + return NULL; + return NMP_OBJECT_CAST_LINK(obj)->name; +} + +static inline gboolean +nmp_object_ip_route_is_best_defaut_route(const NMPObject *obj) +{ + const NMPlatformIPRoute *r = NMP_OBJECT_CAST_IP_ROUTE(obj); + + /* return whether @obj is considered a default-route. + * + * NMIP4Config/NMIP6Config tracks the (best) default-route explicitly, because + * at various places we act differently depending on whether there is a default-route + * configured. + * + * Note that this only considers the main routing table. */ + return r && NM_PLATFORM_IP_ROUTE_IS_DEFAULT(r) + && nm_platform_route_table_is_main(r->table_coerced) + && r->type_coerced == nm_platform_route_type_coerce(1 /* RTN_UNICAST */); +} + +static inline gboolean +nmp_object_ip6_address_is_not_link_local(const NMPObject *obj) +{ + return !IN6_IS_ADDR_LINKLOCAL(&NMP_OBJECT_CAST_IP6_ADDRESS(obj)->address); +} + +/*****************************************************************************/ + +static inline gboolean +nm_platform_dedup_multi_iter_next_obj(NMDedupMultiIter *ipconf_iter, + const NMPObject **out_obj, + NMPObjectType assert_obj_type) +{ + gboolean has_next; + + has_next = nm_dedup_multi_iter_next(ipconf_iter); + nm_assert(assert_obj_type == NMP_OBJECT_TYPE_UNKNOWN || !has_next + || NMP_OBJECT_GET_TYPE(ipconf_iter->current->obj) == assert_obj_type); + NM_SET_OUT(out_obj, has_next ? ipconf_iter->current->obj : NULL); + return has_next; +} + +static inline gboolean +nm_platform_dedup_multi_iter_next_ip4_address(NMDedupMultiIter * ipconf_iter, + const NMPlatformIP4Address **out_address) +{ + gboolean has_next; + + has_next = nm_dedup_multi_iter_next(ipconf_iter); + if (out_address) + *out_address = has_next ? NMP_OBJECT_CAST_IP4_ADDRESS(ipconf_iter->current->obj) : NULL; + return has_next; +} + +static inline gboolean +nm_platform_dedup_multi_iter_next_ip4_route(NMDedupMultiIter * ipconf_iter, + const NMPlatformIP4Route **out_route) +{ + gboolean has_next; + + has_next = nm_dedup_multi_iter_next(ipconf_iter); + if (out_route) + *out_route = has_next ? NMP_OBJECT_CAST_IP4_ROUTE(ipconf_iter->current->obj) : NULL; + return has_next; +} + +static inline gboolean +nm_platform_dedup_multi_iter_next_ip6_address(NMDedupMultiIter * ipconf_iter, + const NMPlatformIP6Address **out_address) +{ + gboolean has_next; + + has_next = nm_dedup_multi_iter_next(ipconf_iter); + if (out_address) + *out_address = has_next ? NMP_OBJECT_CAST_IP6_ADDRESS(ipconf_iter->current->obj) : NULL; + return has_next; +} + +static inline gboolean +nm_platform_dedup_multi_iter_next_ip6_route(NMDedupMultiIter * ipconf_iter, + const NMPlatformIP6Route **out_route) { - NMPLookup lookup; + gboolean has_next; - nmp_lookup_init_object_by_addr_family (&lookup, obj_type, addr_family); - return nm_platform_lookup (platform, &lookup); + has_next = nm_dedup_multi_iter_next(ipconf_iter); + if (out_route) + *out_route = has_next ? NMP_OBJECT_CAST_IP6_ROUTE(ipconf_iter->current->obj) : NULL; + return has_next; } #endif /* __NMP_OBJECT_H__ */ |