summaryrefslogtreecommitdiff
path: root/src/platform/nmp-object.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/platform/nmp-object.h')
-rw-r--r--src/platform/nmp-object.h241
1 files changed, 161 insertions, 80 deletions
diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h
index 7664a43817..bf3671d355 100644
--- a/src/platform/nmp-object.h
+++ b/src/platform/nmp-object.h
@@ -24,7 +24,6 @@
#include "nm-utils/nm-obj.h"
#include "nm-utils/nm-dedup-multi.h"
#include "nm-platform.h"
-#include "nm-multi-index.h"
struct udev_device;
@@ -60,7 +59,14 @@ typedef enum { /*< skip >*/
typedef enum { /*< skip >*/
NMP_CACHE_ID_TYPE_NONE,
- /* all the objects of a certain type */
+ /* 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). */
NMP_CACHE_ID_TYPE_OBJECT_TYPE,
/* index for the link objects by ifname. */
@@ -76,7 +82,7 @@ typedef enum { /*< skip >*/
/* all the visible addresses/routes (by object-type) for an ifindex. */
NMP_CACHE_ID_TYPE_ADDRROUTE_VISIBLE_BY_IFINDEX,
- /* three indeces for the visible routes, per ifindex. */
+ /* indeces for the visible routes, per ifindex. */
NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_BY_IFINDEX_NO_DEFAULT,
NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_BY_IFINDEX_ONLY_DEFAULT,
@@ -95,50 +101,6 @@ typedef enum { /*< skip >*/
NMP_CACHE_ID_TYPE_MAX = __NMP_CACHE_ID_TYPE_MAX - 1,
} NMPCacheIdType;
-typedef struct _NMPCacheId NMPCacheId;
-
-struct _NMPCacheId {
- union {
- NMMultiIndexId base;
- guint8 _id_type; /* NMPCacheIdType as guint8 */
- struct _nm_packed {
- /* NMP_CACHE_ID_TYPE_OBJECT_TYPE */
- /* NMP_CACHE_ID_TYPE_OBJECT_TYPE_VISIBLE_ONLY */
- /* NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_NO_DEFAULT */
- /* NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_ONLY_DEFAULT */
- guint8 _id_type;
- guint8 obj_type; /* NMPObjectType as guint8 */
- } object_type;
- struct _nm_packed {
- /* NMP_CACHE_ID_TYPE_ADDRROUTE_VISIBLE_BY_IFINDEX */
- /* NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_BY_IFINDEX_NO_DEFAULT */
- /* NMP_CACHE_ID_TYPE_ROUTES_VISIBLE_BY_IFINDEX_ONLY_DEFAULT */
- guint8 _id_type;
- guint8 obj_type; /* NMPObjectType as guint8 */
- int _misaligned_ifindex;
- } object_type_by_ifindex;
- struct _nm_packed {
- /* NMP_CACHE_ID_TYPE_LINK_BY_IFNAME */
- guint8 _id_type;
- char ifname_short[IFNAMSIZ - 1]; /* don't include the trailing NUL so the struct fits in 4 bytes. */
- } link_by_ifname;
- struct _nm_packed {
- /* NMP_CACHE_ID_TYPE_ROUTES_BY_DESTINATION_IP4 */
- guint8 _id_type;
- guint8 plen;
- guint32 _misaligned_metric;
- guint32 _misaligned_network;
- } routes_by_destination_ip4;
- struct _nm_packed {
- /* NMP_CACHE_ID_TYPE_ROUTES_BY_DESTINATION_IP6 */
- guint8 _id_type;
- guint8 plen;
- guint32 _misaligned_metric;
- struct in6_addr _misaligned_network;
- } routes_by_destination_ip6;
- };
-};
-
typedef struct {
NMDedupMultiObjClass parent;
const char *obj_type_name;
@@ -155,10 +117,6 @@ typedef struct {
/* Only for NMPObjectLnk* types. */
NMLinkType lnk_link_type;
- /* returns %FALSE, if the obj type would never have an entry for index type @id_type. If @obj has an index,
- * initialize @id and set @out_id to it. Otherwise, @out_id is NULL. */
- gboolean (*cmd_obj_init_cache_id) (const NMPObject *obj, NMPCacheIdType id_type, NMPCacheId *id, const NMPCacheId **out_id);
-
guint (*cmd_obj_hash) (const NMPObject *obj);
int (*cmd_obj_cmp) (const NMPObject *obj1, const NMPObject *obj2);
void (*cmd_obj_copy) (NMPObject *dst, const NMPObject *src);
@@ -276,7 +234,6 @@ struct _NMPObject {
const NMPClass *_class;
};
guint _ref_count;
- bool is_cached;
union {
NMPlatformObject object;
@@ -387,8 +344,8 @@ NMP_OBJECT_GET_TYPE (const NMPObject *obj)
const NMPClass *nmp_class_from_type (NMPObjectType obj_type);
-NMPObject *nmp_object_ref (NMPObject *object);
-void nmp_object_unref (NMPObject *object);
+const NMPObject *nmp_object_ref (const NMPObject *object);
+void nmp_object_unref (const NMPObject *object);
NMPObject *nmp_object_new (NMPObjectType obj_type, const NMPlatformObject *plob);
NMPObject *nmp_object_new_link (int ifindex);
@@ -411,13 +368,13 @@ guint nmp_object_id_hash (const NMPObject *obj);
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, gboolean use_udev);
+void _nmp_object_fixup_link_udev_fields (NMPObject **obj_new, NMPObject *obj_orig, gboolean use_udev);
#define nm_auto_nmpobj __attribute__((cleanup(_nm_auto_nmpobj_cleanup)))
static inline void
-_nm_auto_nmpobj_cleanup (NMPObject **pobj)
+_nm_auto_nmpobj_cleanup (gpointer p)
{
- nmp_object_unref (*pobj);
+ nmp_object_unref (*((const NMPObject **) p));
}
typedef struct _NMPCache NMPCache;
@@ -425,23 +382,92 @@ 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);
-gboolean nmp_cache_id_equal (const NMPCacheId *a, const NMPCacheId *b);
-guint nmp_cache_id_hash (const NMPCacheId *id);
-NMPCacheId *nmp_cache_id_clone (const NMPCacheId *id);
-void nmp_cache_id_destroy (NMPCacheId *id);
+const NMDedupMultiEntry *nmp_cache_lookup_entry_link (const NMPCache *cache, int ifindex);
-NMPCacheId *nmp_cache_id_init_object_type (NMPCacheId *id, NMPObjectType obj_type, gboolean visible_only);
-NMPCacheId *nmp_cache_id_init_addrroute_visible_by_ifindex (NMPCacheId *id, NMPObjectType obj_type, int ifindex);
-NMPCacheId *nmp_cache_id_init_routes_visible (NMPCacheId *id, NMPObjectType obj_type, gboolean with_default, gboolean with_non_default, int ifindex);
-NMPCacheId *nmp_cache_id_init_link_by_ifname (NMPCacheId *id, const char *ifname);
-NMPCacheId *nmp_cache_id_init_routes_by_destination_ip4 (NMPCacheId *id, guint32 network, guint8 plen, guint32 metric);
-NMPCacheId *nmp_cache_id_init_routes_by_destination_ip6 (NMPCacheId *id, const struct in6_addr *network, guint8 plen, guint32 metric);
-
-const NMPlatformObject *const *nmp_cache_lookup_multi (const NMPCache *cache, const NMPCacheId *cache_id, guint *out_len);
-GArray *nmp_cache_lookup_multi_to_array (const NMPCache *cache, NMPObjectType obj_type, const NMPCacheId *cache_id);
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 {
+ NMPCacheIdType cache_id_type;
+ NMPObject selector_obj;
+} NMPLookup;
+
+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)
+{
+ 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,
+ gboolean visible_only);
+const NMPLookup *nmp_lookup_init_link (NMPLookup *lookup,
+ gboolean visible_only);
+const NMPLookup *nmp_lookup_init_link_by_ifname (NMPLookup *lookup,
+ const char *ifname);
+const NMPLookup *nmp_lookup_init_addrroute (NMPLookup *lookup,
+ NMPObjectType obj_type,
+ int ifindex,
+ gboolean visible_only);
+const NMPLookup *nmp_lookup_init_route_visible (NMPLookup *lookup,
+ NMPObjectType obj_type,
+ int ifindex,
+ gboolean with_default,
+ gboolean with_non_default);
+const NMPLookup *nmp_lookup_init_route_by_dest (NMPLookup *lookup,
+ int addr_family,
+ gconstpointer network,
+ guint plen,
+ guint32 metric);
+
+GArray *nmp_cache_lookup_to_array (const NMDedupMultiHeadEntry *head_entry,
+ NMPObjectType obj_type);
+GHashTable *nmp_cache_lookup_to_hash (const NMDedupMultiHeadEntry *head_entry,
+ GHashTable *hash);
+
+static inline gboolean
+nmp_cache_iter_next (NMDedupMultiIter *iter, const NMPObject **out_obj)
+{
+ gboolean has_next;
+
+ has_next = nm_dedup_multi_iter_next (iter);
+ if (has_next) {
+ nm_assert (NMP_OBJECT_IS_VALID (iter->current->box->obj));
+ NM_SET_OUT (out_obj, iter->current->box->obj);
+ }
+ return has_next;
+}
+
+static inline gboolean
+nmp_cache_iter_next_link (NMDedupMultiIter *iter, const NMPlatformLink **out_obj)
+{
+ gboolean has_next;
+
+ has_next = nm_dedup_multi_iter_next (iter);
+ if (has_next) {
+ nm_assert (NMP_OBJECT_GET_TYPE (iter->current->box->obj) == NMP_OBJECT_TYPE_LINK);
+ NM_SET_OUT (out_obj, &(((const NMPObject *) iter->current->box->obj)->link));
+ }
+ 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)); \
+ )
+
+#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_find_other_route_for_same_destination (const NMPCache *cache, const NMPObject *route);
const NMPObject *nmp_cache_lookup_link_full (const NMPCache *cache,
@@ -451,9 +477,6 @@ const NMPObject *nmp_cache_lookup_link_full (const NMPCache *cache,
NMLinkType link_type,
NMPObjectMatchFn match_fn,
gpointer user_data);
-GHashTable *nmp_cache_lookup_all_to_hash (const NMPCache *cache,
- NMPCacheId *cache_id,
- GHashTable *hash);
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);
@@ -462,13 +485,71 @@ 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, gboolean equals_by_ptr, NMPObject **out_obj, gboolean *out_was_visible, NMPCachePreHook pre_hook, gpointer user_data);
-NMPCacheOpsType nmp_cache_remove_netlink (NMPCache *cache, const NMPObject *obj, NMPObject **out_obj, gboolean *out_was_visible, NMPCachePreHook pre_hook, gpointer user_data);
-NMPCacheOpsType nmp_cache_update_netlink (NMPCache *cache, NMPObject *obj, NMPObject **out_obj, gboolean *out_was_visible, NMPCachePreHook pre_hook, gpointer user_data);
-NMPCacheOpsType nmp_cache_update_link_udev (NMPCache *cache, int ifindex, struct udev_device *udevice, NMPObject **out_obj, gboolean *out_was_visible, NMPCachePreHook pre_hook, gpointer user_data);
-NMPCacheOpsType nmp_cache_update_link_master_connected (NMPCache *cache, int ifindex, NMPObject **out_obj, gboolean *out_was_visible, NMPCachePreHook pre_hook, gpointer user_data);
-
-NMPCache *nmp_cache_new (gboolean use_udev);
+NMPCacheOpsType nmp_cache_remove (NMPCache *cache,
+ const NMPObject *obj_needle,
+ gboolean equals_by_ptr,
+ 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,
+ const NMPObject **out_obj_old,
+ const NMPObject **out_obj_new);
+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);
+
+void nmp_cache_dirty_set_all (NMPCache *cache, NMPObjectType obj_type);
+
+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)
+{
+#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));
+#endif
+}
+
#endif /* __NMP_OBJECT_H__ */