summary refs log tree commit diff
path: root/src/libnm-platform/nmp-object.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/libnm-platform/nmp-object.h')
-rw-r--r--src/libnm-platform/nmp-object.h85
1 files changed, 73 insertions, 12 deletions
diff --git a/src/libnm-platform/nmp-object.h b/src/libnm-platform/nmp-object.h
index 25156fe2..0d5f84b3 100644
--- a/src/libnm-platform/nmp-object.h
+++ b/src/libnm-platform/nmp-object.h
@@ -183,25 +183,26 @@ typedef struct {
     /* 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);
+    void (*cmd_obj_copy)(NMPObject *dst, const NMPObject *src);
+    void (*cmd_obj_dispose)(NMPObject *obj);
+
+    void (*cmd_obj_hash_update)(const NMPObject *obj, gboolean for_id, NMHashState *h);
+    int (*cmd_obj_cmp)(const NMPObject *obj1, const NMPObject *obj2, gboolean for_id);
     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_hash_update)(const NMPlatformObject *obj, NMHashState *h);
+    int (*cmd_plobj_cmp)(const NMPlatformObject *obj1, const NMPlatformObject *obj2);
     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];
@@ -296,6 +297,14 @@ typedef struct {
 } NMPObjectLnkVrf;
 
 typedef struct {
+    NMPlatformLnkVti _public;
+} NMPObjectLnkVti;
+
+typedef struct {
+    NMPlatformLnkVti6 _public;
+} NMPObjectLnkVti6;
+
+typedef struct {
     NMPlatformLnkVxlan _public;
 } NMPObjectLnkVxlan;
 
@@ -313,6 +322,13 @@ typedef struct {
 
 typedef struct {
     NMPlatformIP4Route _public;
+
+    /* The first hop is embedded in _public (in the
+     * ifindex, gateway and weight fields).
+     * Only if _public.n_nexthops is greater than 1, then
+     * this contains the remaining(!!) (_public.n_nexthops - 1)
+     * extra hops for ECMP multihop routes. */
+    const NMPlatformIP4RtNextHop *extra_nexthops;
 } NMPObjectIP4Route;
 
 typedef struct {
@@ -388,6 +404,12 @@ struct _NMPObject {
         NMPlatformLnkVrf lnk_vrf;
         NMPObjectLnkVrf  _lnk_vrf;
 
+        NMPlatformLnkVti lnk_vti;
+        NMPObjectLnkVti  _lnk_vti;
+
+        NMPlatformLnkVti6 lnk_vti6;
+        NMPObjectLnkVti6  _lnk_vti6;
+
         NMPlatformLnkVxlan lnk_vxlan;
         NMPObjectLnkVxlan  _lnk_vxlan;
 
@@ -419,7 +441,7 @@ struct _NMPObject {
         NMPlatformMptcpAddr mptcp_addr;
         NMPObjectMptcpAddr  _mptcp_addr;
     };
-};
+} _nm_alignas(NMDedupMultiObj);
 
 /*****************************************************************************/
 
@@ -446,9 +468,12 @@ NMP_OBJECT_UP_CAST(const NMPlatformObject *plobj)
 {
     NMPObject *obj;
 
-    obj = plobj ? (NMPObject *) (&(((char *) plobj)[-((int) G_STRUCT_OFFSET(NMPObject, object))]))
+    obj = plobj ? NM_CAST_ALIGN(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)))
@@ -517,6 +542,8 @@ _NMP_OBJECT_TYPE_IS_OBJ_WITH_IFINDEX(NMPObjectType obj_type)
     case NMP_OBJECT_TYPE_LNK_TUN:
     case NMP_OBJECT_TYPE_LNK_VLAN:
     case NMP_OBJECT_TYPE_LNK_VRF:
+    case NMP_OBJECT_TYPE_LNK_VTI:
+    case NMP_OBJECT_TYPE_LNK_VTI6:
     case NMP_OBJECT_TYPE_LNK_VXLAN:
     case NMP_OBJECT_TYPE_LNK_WIREGUARD:
 
@@ -534,6 +561,8 @@ _NMP_OBJECT_TYPE_IS_OBJ_WITH_IFINDEX(NMPObjectType obj_type)
     return FALSE;
 }
 
+#define NMP_OBJECT_TYPE_NAME(obj_type) (nmp_class_from_type(obj_type)->obj_type_name)
+
 #define NMP_OBJECT_CAST_OBJECT(obj)                                       \
     ({                                                                    \
         typeof(obj) _obj = (obj);                                         \
@@ -717,14 +746,35 @@ 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);
+
+void nmp_object_hash_update_full(const NMPObject *obj, gboolean for_id, NMHashState *h);
+
+static inline void
+nmp_object_hash_update(const NMPObject *obj, NMHashState *h)
+{
+    return nmp_object_hash_update_full(obj, FALSE, h);
+}
 
 typedef enum {
     NMP_OBJECT_CMP_FLAGS_NONE = 0,
 
+    /* Only compare for the ID. This is what nmp_object_id_cmp() does.
+     *
+     * In most cases, the identity of an object is a (non-strict) subset
+     * of the attributes of the object.
+     *
+     * However, for some objects (like NMPObjectLnk) there is on concept
+     * of identity. They implement object identity based on pointer equality
+     * (in that case, the ID is not a subset of the object's attributes).
+     *
+     * That's why this flag (currently) cannot be meaningfully combined with
+     * other flags.
+     */
+    NMP_OBJECT_CMP_FLAGS_ID = NM_BIT(0),
+
     /* Warning: this flag is currently only implemented for certain object types
      * (address and routes). */
-    NMP_OBJECT_CMP_FLAGS_IGNORE_IFINDEX = (1llu << 0),
+    NMP_OBJECT_CMP_FLAGS_IGNORE_IFINDEX = NM_BIT(1),
 } NMPObjectCmpFlags;
 
 int nmp_object_cmp_full(const NMPObject *obj1, const NMPObject *obj2, NMPObjectCmpFlags flags);
@@ -744,8 +794,18 @@ nmp_object_equal(const NMPObject *obj1, const NMPObject *obj2)
 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);
+static inline int
+nmp_object_id_cmp(const NMPObject *obj1, const NMPObject *obj2)
+{
+    return nmp_object_cmp_full(obj1, obj2, NMP_OBJECT_CMP_FLAGS_ID);
+}
+
+static inline void
+nmp_object_id_hash_update(const NMPObject *obj, NMHashState *h)
+{
+    return nmp_object_hash_update_full(obj, TRUE, h);
+}
+
 guint nmp_object_id_hash(const NMPObject *obj);
 
 static inline gboolean
@@ -915,6 +975,7 @@ NMPCacheOpsType nmp_cache_update_netlink_route(NMPCache         *cache,
                                                NMPObject        *obj_hand_over,
                                                gboolean          is_dump,
                                                guint16           nlmsgflags,
+                                               gboolean          route_is_alive,
                                                const NMPObject **out_obj_old,
                                                const NMPObject **out_obj_new,
                                                const NMPObject **out_obj_replace,