about summary refs log tree commit diff
path: root/shared/nm-utils
diff options
context:
space:
mode:
Diffstat (limited to 'shared/nm-utils')
-rw-r--r--shared/nm-utils/c-list.h14
-rw-r--r--shared/nm-utils/nm-dedup-multi.c20
-rw-r--r--shared/nm-utils/nm-glib.h5
-rw-r--r--shared/nm-utils/nm-macros-internal.h182
-rw-r--r--shared/nm-utils/nm-random-utils.c2
-rw-r--r--shared/nm-utils/nm-shared-utils.c30
-rw-r--r--shared/nm-utils/nm-shared-utils.h77
7 files changed, 238 insertions, 92 deletions
diff --git a/shared/nm-utils/c-list.h b/shared/nm-utils/c-list.h
index 557862b6..a3c4053b 100644
--- a/shared/nm-utils/c-list.h
+++ b/shared/nm-utils/c-list.h
@@ -142,7 +142,7 @@ static inline void c_list_link_after(CList *where, CList *what) {
 #define c_list_link_front(_list, _what) c_list_link_after((_list), (_what))
 
 /**
- * c_list_unlink() - unlink element from list
+ * c_list_unlink_stale() - unlink element from list
  * @what:               element to unlink
  *
  * This unlinks @what. If @what was initialized via C_LIST_INIT(), it has no
@@ -150,9 +150,9 @@ static inline void c_list_link_after(CList *where, CList *what) {
  *
  * Note that this does not modify @what. It just modifies the previous and next
  * elements in the list to no longer reference @what. If you want to make sure
- * @what is re-initialized after removal, use c_list_unlink_init().
+ * @what is re-initialized after removal, use c_list_unlink().
  */
-static inline void c_list_unlink(CList *what) {
+static inline void c_list_unlink_stale(CList *what) {
         CList *prev = what->prev, *next = what->next;
 
         next->prev = prev;
@@ -160,15 +160,15 @@ static inline void c_list_unlink(CList *what) {
 }
 
 /**
- * c_list_unlink_init() - unlink element from list and re-initialize
+ * c_list_unlink() - unlink element from list and re-initialize
  * @what:               element to unlink
  *
- * This is like c_list_unlink() but re-initializes @what after removal.
+ * This is like c_list_unlink_stale() but re-initializes @what after removal.
  */
-static inline void c_list_unlink_init(CList *what) {
+static inline void c_list_unlink(CList *what) {
         /* condition is not needed, but avoids STOREs in fast-path */
         if (c_list_is_linked(what)) {
-                c_list_unlink(what);
+                c_list_unlink_stale(what);
                 *what = (CList)C_LIST_INIT(*what);
         }
 }
diff --git a/shared/nm-utils/nm-dedup-multi.c b/shared/nm-utils/nm-dedup-multi.c
index 8a59f1c4..ee310a7b 100644
--- a/shared/nm-utils/nm-dedup-multi.c
+++ b/shared/nm-utils/nm-dedup-multi.c
@@ -272,13 +272,13 @@ _add (NMDedupMultiIndex *self,
 			if (entry_order) {
 				if (   entry_order != entry
 				    && entry->lst_entries.next != &entry_order->lst_entries) {
-					c_list_unlink (&entry->lst_entries);
+					c_list_unlink_stale (&entry->lst_entries);
 					c_list_link_before ((CList *) &entry_order->lst_entries, &entry->lst_entries);
 					changed = TRUE;
 				}
 			} else {
 				if (entry->lst_entries.prev != &entry->head->lst_entries_head) {
-					c_list_unlink (&entry->lst_entries);
+					c_list_unlink_stale (&entry->lst_entries);
 					c_list_link_front ((CList *) &entry->head->lst_entries_head, &entry->lst_entries);
 					changed = TRUE;
 				}
@@ -288,13 +288,13 @@ _add (NMDedupMultiIndex *self,
 			if (entry_order) {
 				if (   entry_order != entry
 				    && entry->lst_entries.prev != &entry_order->lst_entries) {
-					c_list_unlink (&entry->lst_entries);
+					c_list_unlink_stale (&entry->lst_entries);
 					c_list_link_after ((CList *) &entry_order->lst_entries, &entry->lst_entries);
 					changed = TRUE;
 				}
 			} else {
 				if (entry->lst_entries.next != &entry->head->lst_entries_head) {
-					c_list_unlink (&entry->lst_entries);
+					c_list_unlink_stale (&entry->lst_entries);
 					c_list_link_tail ((CList *) &entry->head->lst_entries_head, &entry->lst_entries);
 					changed = TRUE;
 				}
@@ -541,12 +541,12 @@ _remove_entry (NMDedupMultiIndex *self,
 	    && !g_hash_table_remove (self->idx_entries, head_entry))
 		nm_assert_not_reached ();
 
-	c_list_unlink (&entry->lst_entries);
+	c_list_unlink_stale (&entry->lst_entries);
 	g_slice_free (NMDedupMultiEntry, entry);
 
 	if (head_entry) {
 		nm_assert (c_list_is_empty (&head_entry->lst_entries_head));
-		c_list_unlink (&head_entry->lst_idx);
+		c_list_unlink_stale (&head_entry->lst_idx);
 		g_slice_free (NMDedupMultiHeadEntry, head_entry);
 	}
 
@@ -1027,13 +1027,13 @@ nm_dedup_multi_entry_reorder (const NMDedupMultiEntry *entry,
 		nm_assert (c_list_contains (&head_entry->lst_entries_head, &entry->lst_entries));
 		if (order_after) {
 			if (head_entry->lst_entries_head.prev != &entry->lst_entries) {
-				c_list_unlink ((CList *) &entry->lst_entries);
+				c_list_unlink_stale ((CList *) &entry->lst_entries);
 				c_list_link_tail ((CList *) &head_entry->lst_entries_head, (CList *) &entry->lst_entries);
 				return TRUE;
 			}
 		} else {
 			if (head_entry->lst_entries_head.next != &entry->lst_entries) {
-				c_list_unlink ((CList *) &entry->lst_entries);
+				c_list_unlink_stale ((CList *) &entry->lst_entries);
 				c_list_link_front ((CList *) &head_entry->lst_entries_head, (CList *) &entry->lst_entries);
 				return TRUE;
 			}
@@ -1041,13 +1041,13 @@ nm_dedup_multi_entry_reorder (const NMDedupMultiEntry *entry,
 	} else if (entry != entry_order) {
 		if (order_after) {
 			if (entry_order->lst_entries.next != &entry->lst_entries) {
-				c_list_unlink ((CList *) &entry->lst_entries);
+				c_list_unlink_stale ((CList *) &entry->lst_entries);
 				c_list_link_after ((CList *) &entry_order->lst_entries, (CList *) &entry->lst_entries);
 				return TRUE;
 			}
 		} else {
 			if (entry_order->lst_entries.prev != &entry->lst_entries) {
-				c_list_unlink ((CList *) &entry->lst_entries);
+				c_list_unlink_stale ((CList *) &entry->lst_entries);
 				c_list_link_before ((CList *) &entry_order->lst_entries, (CList *) &entry->lst_entries);
 				return TRUE;
 			}
diff --git a/shared/nm-utils/nm-glib.h b/shared/nm-utils/nm-glib.h
index 4ef538e4..599890e0 100644
--- a/shared/nm-utils/nm-glib.h
+++ b/shared/nm-utils/nm-glib.h
@@ -481,4 +481,9 @@ _nm_g_variant_new_printf (const char *format_string, ...)
 	})
 #endif
 
+#if !GLIB_CHECK_VERSION (2, 56, 0)
+#define g_object_ref(Obj)      ((typeof(Obj)) g_object_ref (Obj))
+#define g_object_ref_sink(Obj) ((typeof(Obj)) g_object_ref_sink (Obj))
+#endif
+
 #endif  /* __NM_GLIB_H__ */
diff --git a/shared/nm-utils/nm-macros-internal.h b/shared/nm-utils/nm-macros-internal.h
index d9dab83d..5bd9eac4 100644
--- a/shared/nm-utils/nm-macros-internal.h
+++ b/shared/nm-utils/nm-macros-internal.h
@@ -263,33 +263,117 @@ NM_G_ERROR_MSG (GError *error)
 
 /*****************************************************************************/
 
-#if (defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 9 ))) || (defined (__clang__))
+#ifndef _NM_CC_SUPPORT_AUTO_TYPE
+#if (defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9 )))
+#define _NM_CC_SUPPORT_AUTO_TYPE 1
+#else
+#define _NM_CC_SUPPORT_AUTO_TYPE 0
+#endif
+#endif
+
+#ifndef _NM_CC_SUPPORT_GENERIC
+#if (defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9 ))) || (defined (__clang__))
 #define _NM_CC_SUPPORT_GENERIC 1
 #else
 #define _NM_CC_SUPPORT_GENERIC 0
 #endif
+#endif
+
+#if _NM_CC_SUPPORT_AUTO_TYPE
+#define _nm_auto_type __auto_type
+#endif
 
 #if _NM_CC_SUPPORT_GENERIC
-#define _NM_CONSTCAST(type, obj) \
-	(_Generic ((obj), \
-	           void *           : ((type *) (obj)), \
-	           void *const      : ((type *) (obj)), \
-	           const void *     : ((const type *) (obj)), \
-	           const void *const: ((const type *) (obj)), \
-	           const type *     : (obj), \
-	           const type *const: (obj), \
-	           type *           : (obj), \
-	           type *const      : (obj)))
+#define _NM_CONSTCAST_FULL_1(type, obj_expr, obj) \
+	(_Generic ((obj_expr), \
+	           const void        *const: ((const type *) (obj)), \
+	           const void        *     : ((const type *) (obj)), \
+	                 void        *const: ((      type *) (obj)), \
+	                 void        *     : ((      type *) (obj)), \
+	           const type        *const: ((const type *) (obj)), \
+	           const type        *     : ((const type *) (obj)), \
+	                 type        *const: ((      type *) (obj)), \
+	                 type        *     : ((      type *) (obj))))
+#define _NM_CONSTCAST_FULL_2(type, obj_expr, obj, alias_type2) \
+	(_Generic ((obj_expr), \
+	           const void        *const: ((const type *) (obj)), \
+	           const void        *     : ((const type *) (obj)), \
+	                 void        *const: ((      type *) (obj)), \
+	                 void        *     : ((      type *) (obj)), \
+	           const alias_type2 *const: ((const type *) (obj)), \
+	           const alias_type2 *     : ((const type *) (obj)), \
+	                 alias_type2 *const: ((      type *) (obj)), \
+	                 alias_type2 *     : ((      type *) (obj)), \
+	           const type        *const: ((const type *) (obj)), \
+	           const type        *     : ((const type *) (obj)), \
+	                 type        *const: ((      type *) (obj)), \
+	                 type        *     : ((      type *) (obj))))
+#define _NM_CONSTCAST_FULL_3(type, obj_expr, obj, alias_type2, alias_type3) \
+	(_Generic ((obj_expr), \
+	           const void        *const: ((const type *) (obj)), \
+	           const void        *     : ((const type *) (obj)), \
+	                 void        *const: ((      type *) (obj)), \
+	                 void        *     : ((      type *) (obj)), \
+	           const alias_type2 *const: ((const type *) (obj)), \
+	           const alias_type2 *     : ((const type *) (obj)), \
+	                 alias_type2 *const: ((      type *) (obj)), \
+	                 alias_type2 *     : ((      type *) (obj)), \
+	           const alias_type3 *const: ((const type *) (obj)), \
+	           const alias_type3 *     : ((const type *) (obj)), \
+	                 alias_type3 *const: ((      type *) (obj)), \
+	                 alias_type3 *     : ((      type *) (obj)), \
+	           const type        *const: ((const type *) (obj)), \
+	           const type        *     : ((const type *) (obj)), \
+	                 type        *const: ((      type *) (obj)), \
+	                 type        *     : ((      type *) (obj))))
+#define _NM_CONSTCAST_FULL_4(type, obj_expr, obj, alias_type2, alias_type3, alias_type4) \
+	(_Generic ((obj_expr), \
+	           const void        *const: ((const type *) (obj)), \
+	           const void        *     : ((const type *) (obj)), \
+	                 void        *const: ((      type *) (obj)), \
+	                 void        *     : ((      type *) (obj)), \
+	           const alias_type2 *const: ((const type *) (obj)), \
+	           const alias_type2 *     : ((const type *) (obj)), \
+	                 alias_type2 *const: ((      type *) (obj)), \
+	                 alias_type2 *     : ((      type *) (obj)), \
+	           const alias_type3 *const: ((const type *) (obj)), \
+	           const alias_type3 *     : ((const type *) (obj)), \
+	                 alias_type3 *const: ((      type *) (obj)), \
+	                 alias_type3 *     : ((      type *) (obj)), \
+	           const alias_type4 *const: ((const type *) (obj)), \
+	           const alias_type4 *     : ((const type *) (obj)), \
+	                 alias_type4 *const: ((      type *) (obj)), \
+	                 alias_type4 *     : ((      type *) (obj)), \
+	           const type        *const: ((const type *) (obj)), \
+	           const type        *     : ((const type *) (obj)), \
+	                 type        *const: ((      type *) (obj)), \
+	                 type        *     : ((      type *) (obj))))
+#define _NM_CONSTCAST_FULL_x(type, obj_expr, obj, n, ...)   (_NM_CONSTCAST_FULL_##n (type, obj_expr, obj,                        ##__VA_ARGS__))
+#define _NM_CONSTCAST_FULL_y(type, obj_expr, obj, n, ...)   (_NM_CONSTCAST_FULL_x   (type, obj_expr, obj, n,                     ##__VA_ARGS__))
+#define NM_CONSTCAST_FULL(   type, obj_expr, obj,    ...)   (_NM_CONSTCAST_FULL_y   (type, obj_expr, obj, NM_NARG (dummy, ##__VA_ARGS__), ##__VA_ARGS__))
 #else
-/* _NM_CONSTCAST() is there to preserve constness of a pointer.
- * It uses C11's _Generic(). If that is not supported, we fall back
- * to casting away constness. So, with _Generic, we get some additional
- * static type checking by preserving constness, without, we cast it
- * to a non-const pointer. */
-#define _NM_CONSTCAST(type, obj) \
-	((type *) (obj))
+#define NM_CONSTCAST_FULL(   type, obj_expr, obj,    ...)   ((type *) (obj))
 #endif
 
+#define NM_CONSTCAST(type, obj, ...) \
+	NM_CONSTCAST_FULL(type, (obj), (obj), ##__VA_ARGS__)
+
+#define NM_GOBJECT_CAST(type, obj, is_check, ...) \
+	({ \
+		const void *_obj = (obj); \
+		\
+		nm_assert (_obj || (is_check (_obj))); \
+		NM_CONSTCAST_FULL (type, (obj), _obj, GObject, ##__VA_ARGS__); \
+	})
+
+#define NM_GOBJECT_CAST_NON_NULL(type, obj, is_check, ...) \
+	({ \
+		const void *_obj = (obj); \
+		\
+		nm_assert (is_check (_obj)); \
+		NM_CONSTCAST_FULL (type, (obj), _obj, GObject, ##__VA_ARGS__); \
+	})
+
 #if _NM_CC_SUPPORT_GENERIC
 /* returns @value, if the type of @value matches @type.
  * This requires support for C11 _Generic(). If no support is
@@ -302,6 +386,16 @@ NM_G_ERROR_MSG (GError *error)
 #define _NM_ENSURE_TYPE(type, value) (value)
 #endif
 
+#if _NM_CC_SUPPORT_GENERIC
+#define NM_PROPAGATE_CONST(test_expr, ptr) \
+	(_Generic ((test_expr), \
+	           const typeof (*(test_expr)) *: ((const typeof (*(ptr)) *) (ptr)), \
+	                                 default: (_Generic ((test_expr), \
+	                                                     typeof (*(test_expr)) *: (ptr)))))
+#else
+#define NM_PROPAGATE_CONST(test_expr, ptr) (ptr)
+#endif
+
 /*****************************************************************************/
 
 #define _NM_IN_SET_EVAL_1( op, _x, y)           (_x == (y))
@@ -459,7 +553,7 @@ _NM_IN_STRSET_streq (const char *x, const char *s)
 
 /* NM_CACHED_QUARK_FCN() is essentially the same as G_DEFINE_QUARK
  * with two differences:
- * - @string must be a quited string-literal
+ * - @string must be a quoted string-literal
  * - @fcn must be the full function name, while G_DEFINE_QUARK() appends
  *   "_quark" to the function name.
  * Both properties of G_DEFINE_QUARK() are non favorable, because you can no
@@ -581,39 +675,17 @@ _notify (obj_type *obj, _PropertyEnums prop) \
 
 /*****************************************************************************/
 
-/* these are implemented as a macro, because they accept self
- * as both (type*) and (const type*), and return a const
- * private pointer accordingly. */
-#define __NM_GET_PRIVATE(self, type, is_check, addrop) \
-	({ \
-		/* preserve the const-ness of self. Unfortunately, that
-		 * way, @self cannot be a void pointer */ \
-		typeof (self) _self = (self); \
-		\
-		/* Get compiler error if variable is of wrong type */ \
-		_nm_unused const type *const _self2 = (_self); \
-		\
-		nm_assert (is_check (_self)); \
-		( addrop ( _NM_CONSTCAST (type, _self)->_priv) ); \
-	})
-
-#define _NM_GET_PRIVATE(self, type, is_check)     __NM_GET_PRIVATE(self, type, is_check, &)
-#define _NM_GET_PRIVATE_PTR(self, type, is_check) __NM_GET_PRIVATE(self, type, is_check,  )
-
-#define __NM_GET_PRIVATE_VOID(self, type, is_check, result_cmd) \
+#define _NM_GET_PRIVATE(self, type, is_check, ...) (&(NM_GOBJECT_CAST_NON_NULL (type, (self), is_check, ##__VA_ARGS__)->_priv))
+#if _NM_CC_SUPPORT_AUTO_TYPE
+#define _NM_GET_PRIVATE_PTR(self, type, is_check, ...) \
 	({ \
-		/* (self) can be any non-const pointer. It will be cast to "type *".
-		 * We don't explicitly cast but assign first to (void *) which
-		 * will fail if @self is pointing to const. */ \
-		void *const _self1 = (self); \
-		type *const _self = _self1; \
+		_nm_auto_type _self = NM_GOBJECT_CAST_NON_NULL (type, (self), is_check, ##__VA_ARGS__); \
 		\
-		nm_assert (is_check (_self)); \
-		( result_cmd ); \
+		NM_PROPAGATE_CONST (_self, _self->_priv); \
 	})
-
-#define _NM_GET_PRIVATE_VOID(self, type, is_check)     __NM_GET_PRIVATE_VOID(self, type, is_check, &_self->_priv)
-#define _NM_GET_PRIVATE_PTR_VOID(self, type, is_check) __NM_GET_PRIVATE_VOID(self, type, is_check,  _self->_priv)
+#else
+#define _NM_GET_PRIVATE_PTR(self, type, is_check, ...) (NM_GOBJECT_CAST_NON_NULL (type, (self), is_check, ##__VA_ARGS__)->_priv)
+#endif
 
 /*****************************************************************************/
 
@@ -625,6 +697,7 @@ nm_g_object_ref (gpointer obj)
 		g_object_ref (obj);
 	return obj;
 }
+#define nm_g_object_ref(obj) ((typeof (obj)) nm_g_object_ref (obj))
 
 static inline void
 nm_g_object_unref (gpointer obj)
@@ -1174,12 +1247,11 @@ nm_steal_fd (int *p_fd)
 static inline int
 nm_close (int fd)
 {
-	if (fd >= 0) {
-		if (close (fd) == 0)
-			return 0;
-		nm_assert (errno != EBADF);
-	}
-	return -1;
+	int r;
+
+	r = close (fd);
+	nm_assert (r != -1 || fd < 0 || errno != EBADF);
+	return r;
 }
 
 #endif /* __NM_MACROS_INTERNAL_H__ */
diff --git a/shared/nm-utils/nm-random-utils.c b/shared/nm-utils/nm-random-utils.c
index 5d9e29da..65986b3d 100644
--- a/shared/nm-utils/nm-random-utils.c
+++ b/shared/nm-utils/nm-random-utils.c
@@ -120,7 +120,7 @@ fd_open:
 				goto fd_open;
 		} else {
 			r = nm_utils_fd_read_loop_exact (fd, buf, n, TRUE);
-			close (fd);
+			nm_close (fd);
 			if (r >= 0)
 				urandom_success = TRUE;
 		}
diff --git a/shared/nm-utils/nm-shared-utils.c b/shared/nm-utils/nm-shared-utils.c
index cea60edf..0b343afd 100644
--- a/shared/nm-utils/nm-shared-utils.c
+++ b/shared/nm-utils/nm-shared-utils.c
@@ -151,7 +151,7 @@ nm_strquote (char *buf, gsize buf_len, const char *str)
 		switch (buf_len) {
 		case 2:
 			*(buf++) = '^';
-			/* fall-through*/
+			/* fall-through */
 		case 1:
 			*(buf++) = '\0';
 			break;
@@ -569,7 +569,7 @@ nm_utils_strsplit_set (const char *str, const char *delimiters)
 
 			/* reallocate the buffer. Note that for now the string
 			 * continues to be in ptr0/s0. We fix that at the end. */
-			alloc_size += 2;
+			alloc_size *= 2;
 			ptr = g_malloc ((sizeof (const char *) * (alloc_size + 1)) + str_len);
 			memcpy (ptr, ptr_old, sizeof (const char *) * plen);
 			if (ptr_old != ptr0)
@@ -845,6 +845,32 @@ nm_g_object_set_property (GObject *object,
 	return TRUE;
 }
 
+gboolean
+nm_g_object_set_property_boolean (GObject *object,
+                                  const gchar  *property_name,
+                                  gboolean value,
+                                  GError **error)
+{
+	nm_auto_unset_gvalue GValue gvalue = { 0 };
+
+	g_value_init (&gvalue, G_TYPE_BOOLEAN);
+	g_value_set_boolean (&gvalue, !!value);
+	return nm_g_object_set_property (object, property_name, &gvalue, error);
+}
+
+gboolean
+nm_g_object_set_property_uint (GObject *object,
+                               const gchar  *property_name,
+                               guint value,
+                               GError **error)
+{
+	nm_auto_unset_gvalue GValue gvalue = { 0 };
+
+	g_value_init (&gvalue, G_TYPE_UINT);
+	g_value_set_uint (&gvalue, value);
+	return nm_g_object_set_property (object, property_name, &gvalue, error);
+}
+
 GParamSpec *
 nm_g_object_class_find_property_from_gtype (GType gtype,
                                             const char *property_name)
diff --git a/shared/nm-utils/nm-shared-utils.h b/shared/nm-utils/nm-shared-utils.h
index 96aab534..d6d829cd 100644
--- a/shared/nm-utils/nm-shared-utils.h
+++ b/shared/nm-utils/nm-shared-utils.h
@@ -26,23 +26,6 @@
 
 /*****************************************************************************/
 
-typedef struct {
-	union {
-		guint8 addr_ptr[1];
-		in_addr_t addr4;
-		struct in6_addr addr6;
-
-		/* NMIPAddr is really a union for IP addresses.
-		 * However, as ethernet addresses fit in here nicely, use
-		 * it also for an ethernet MAC address. */
-		guint8 addr_eth[6 /*ETH_ALEN*/];
-	};
-} NMIPAddr;
-
-extern const NMIPAddr nm_ip_addr_zero;
-
-/*****************************************************************************/
-
 static inline char
 nm_utils_addr_family_to_char (int addr_family)
 {
@@ -68,6 +51,36 @@ nm_utils_addr_family_to_size (int addr_family)
 
 /*****************************************************************************/
 
+typedef struct {
+	union {
+		guint8 addr_ptr[1];
+		in_addr_t addr4;
+		struct in6_addr addr6;
+
+		/* NMIPAddr is really a union for IP addresses.
+		 * However, as ethernet addresses fit in here nicely, use
+		 * it also for an ethernet MAC address. */
+		guint8 addr_eth[6 /*ETH_ALEN*/];
+	};
+} NMIPAddr;
+
+extern const NMIPAddr nm_ip_addr_zero;
+
+static inline void
+nm_ip_addr_set (int addr_family, gpointer dst, const NMIPAddr *src)
+{
+	nm_assert_addr_family (addr_family);
+	nm_assert (dst);
+	nm_assert (src);
+
+	if (addr_family != AF_INET6)
+		*((in_addr_t *) dst) = src->addr4;
+	else
+		*((struct in6_addr *) dst) = src->addr6;
+}
+
+/*****************************************************************************/
+
 #define NM_CMP_RETURN(c) \
     G_STMT_START { \
         const int _cc = (c); \
@@ -373,6 +386,16 @@ gboolean nm_g_object_set_property (GObject *object,
                                    const GValue *value,
                                    GError **error);
 
+gboolean nm_g_object_set_property_boolean (GObject *object,
+                                           const gchar  *property_name,
+                                           gboolean value,
+                                           GError **error);
+
+gboolean nm_g_object_set_property_uint (GObject *object,
+                                        const gchar  *property_name,
+                                        guint value,
+                                        GError **error);
+
 GParamSpec *nm_g_object_class_find_property_from_gtype (GType gtype,
                                                         const char *property_name);
 
@@ -394,6 +417,26 @@ char *nm_utils_str_utf8safe_escape_take (char *str, NMUtilsStrUtf8SafeFlags flag
 
 /*****************************************************************************/
 
+typedef struct {
+	const char *name;
+} NMUtilsNamedEntry;
+
+typedef struct {
+	union {
+		NMUtilsNamedEntry named_entry;
+		const char *name;
+	};
+	union {
+		const char *value_str;
+		gconstpointer value_ptr;
+	};
+} NMUtilsNamedValue;
+
+#define nm_utils_named_entry_cmp           nm_strcmp_p
+#define nm_utils_named_entry_cmp_with_data nm_strcmp_p_with_data
+
+/*****************************************************************************/
+
 #define NM_UTILS_NS_PER_SECOND  ((gint64) 1000000000)
 #define NM_UTILS_NS_PER_MSEC    ((gint64) 1000000)
 #define NM_UTILS_NS_TO_MSEC_CEIL(nsec)      (((nsec) + (NM_UTILS_NS_PER_MSEC - 1)) / NM_UTILS_NS_PER_MSEC)