diff --git a/include/nm-dbus-glib-types.h b/include/nm-dbus-glib-types.h index cfb08274c6..0f8c542e82 100644 --- a/include/nm-dbus-glib-types.h +++ b/include/nm-dbus-glib-types.h @@ -34,7 +34,7 @@ #define DBUS_TYPE_G_MAP_OF_STRING (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING)) #define DBUS_TYPE_G_LIST_OF_STRING (dbus_g_type_get_collection ("GSList", G_TYPE_STRING)) -#define DBUS_TYPE_G_IP6_ADDRESS (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, G_TYPE_INVALID)) +#define DBUS_TYPE_G_IP6_ADDRESS (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_INVALID)) #define DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_IP6_ADDRESS)) #define DBUS_TYPE_G_IP6_ROUTE (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, G_TYPE_INVALID)) #define DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_IP6_ROUTE)) diff --git a/libnm-util/Makefile.am b/libnm-util/Makefile.am index 8f6a0cc95d..bb4736f45b 100644 --- a/libnm-util/Makefile.am +++ b/libnm-util/Makefile.am @@ -59,7 +59,7 @@ libnm_util_la_SOURCES= \ libnm_util_la_LIBADD = $(GLIB_LIBS) $(DBUS_LIBS) $(UUID_LIBS) libnm_util_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-util.ver \ - -version-info "4:2:3" + -version-info "4:3:3" if WITH_GNUTLS libnm_util_la_SOURCES += crypto_gnutls.c diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index 44d9ac5aec..1c8446ba2e 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -177,6 +177,8 @@ global: nm_ip6_address_compare; nm_ip6_address_get_address; nm_ip6_address_set_address; + nm_ip6_address_get_gateway; + nm_ip6_address_set_gateway; nm_ip6_address_get_prefix; nm_ip6_address_set_prefix; nm_ip6_route_new; diff --git a/libnm-util/nm-setting-ip6-config.c b/libnm-util/nm-setting-ip6-config.c index 3fbf1a2bc4..c383b2d270 100644 --- a/libnm-util/nm-setting-ip6-config.c +++ b/libnm-util/nm-setting-ip6-config.c @@ -797,10 +797,13 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *setting_class) } +/********************************************************************/ + struct NMIP6Address { guint32 refcount; struct in6_addr address; guint32 prefix; + struct in6_addr gateway; }; NMIP6Address * @@ -902,6 +905,27 @@ nm_ip6_address_set_prefix (NMIP6Address *address, guint32 prefix) address->prefix = prefix; } +const struct in6_addr * +nm_ip6_address_get_gateway (NMIP6Address *address) +{ + g_return_val_if_fail (address != NULL, 0); + g_return_val_if_fail (address->refcount > 0, 0); + + return &address->gateway; +} + +void +nm_ip6_address_set_gateway (NMIP6Address *address, const struct in6_addr *gw) +{ + g_return_if_fail (address != NULL); + g_return_if_fail (address->refcount > 0); + g_return_if_fail (gw != NULL); + + memcpy (&address->gateway, gw, sizeof (struct in6_addr)); +} + +/********************************************************************/ + struct NMIP6Route { guint32 refcount; diff --git a/libnm-util/nm-setting-ip6-config.h b/libnm-util/nm-setting-ip6-config.h index b089679e4e..78617c4547 100644 --- a/libnm-util/nm-setting-ip6-config.h +++ b/libnm-util/nm-setting-ip6-config.h @@ -88,6 +88,10 @@ guint32 nm_ip6_address_get_prefix (NMIP6Address *address); void nm_ip6_address_set_prefix (NMIP6Address *address, guint32 prefix); +const struct in6_addr *nm_ip6_address_get_gateway (NMIP6Address *address); +void nm_ip6_address_set_gateway (NMIP6Address *address, + const struct in6_addr *gw); + typedef struct NMIP6Route NMIP6Route; NMIP6Route * nm_ip6_route_new (void); diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c index 5ca3014d79..405288d361 100644 --- a/libnm-util/nm-utils.c +++ b/libnm-util/nm-utils.c @@ -1459,8 +1459,8 @@ nm_utils_ip4_get_default_prefix (guint32 ip) * @value: gvalue containing a GPtrArray of GValueArrays of (GArray of guchars) and guint32 * * Utility function to convert a #GPtrArray of #GValueArrays of (#GArray of guchars) and guint32 - * representing a list of NetworkManager IPv6 addresses (which is a pair of address - * and prefix), into a GSList of #NMIP6Address objects. The specific format of + * representing a list of NetworkManager IPv6 addresses (which is a tuple of address, + * prefix, and gateway), into a GSList of #NMIP6Address objects. The specific format of * this serialization is not guaranteed to be stable and the #GValueArray may be * extended in the future. * @@ -1479,16 +1479,28 @@ nm_utils_ip6_addresses_from_gvalue (const GValue *value) GValueArray *elements = (GValueArray *) g_ptr_array_index (addresses, i); GValue *tmp; GByteArray *ba_addr; + GByteArray *ba_gw = NULL; NMIP6Address *addr; guint32 prefix; - if ( (elements->n_values != 2) - || (G_VALUE_TYPE (g_value_array_get_nth (elements, 0)) != DBUS_TYPE_G_UCHAR_ARRAY) + if (elements->n_values < 2 || elements->n_values > 3) { + nm_warning ("%s: ignoring invalid IP6 address structure", __func__); + continue; + } + + if ( (G_VALUE_TYPE (g_value_array_get_nth (elements, 0)) != DBUS_TYPE_G_UCHAR_ARRAY) || (G_VALUE_TYPE (g_value_array_get_nth (elements, 1)) != G_TYPE_UINT)) { nm_warning ("%s: ignoring invalid IP6 address structure", __func__); continue; } + /* Check optional 3rd element (gateway) */ + if ( elements->n_values == 3 + && (G_VALUE_TYPE (g_value_array_get_nth (elements, 2)) != DBUS_TYPE_G_UCHAR_ARRAY)) { + nm_warning ("%s: ignoring invalid IP6 address structure", __func__); + continue; + } + tmp = g_value_array_get_nth (elements, 0); ba_addr = g_value_get_boxed (tmp); if (ba_addr->len != 16) { @@ -1505,9 +1517,22 @@ nm_utils_ip6_addresses_from_gvalue (const GValue *value) continue; } + if (elements->n_values == 3) { + tmp = g_value_array_get_nth (elements, 2); + ba_gw = g_value_get_boxed (tmp); + if (ba_gw->len != 16) { + nm_warning ("%s: ignoring invalid IP6 gateway address of length %d", + __func__, ba_gw->len); + continue; + } + } + addr = nm_ip6_address_new (); nm_ip6_address_set_prefix (addr, prefix); nm_ip6_address_set_address (addr, (const struct in6_addr *) ba_addr->data); + if (ba_gw) + nm_ip6_address_set_gateway (addr, (const struct in6_addr *) ba_gw->data); + list = g_slist_prepend (list, addr); } @@ -1522,10 +1547,10 @@ nm_utils_ip6_addresses_from_gvalue (const GValue *value) * g_value_unset(). * * Utility function to convert a #GSList of #NMIP6Address objects into a - * GPtrArray of GValueArrays of (GArray or guchars) and guint32 representing a list - * of NetworkManager IPv6 addresses (which is a pair of address and prefix). - * The specific format of this serialization is not guaranteed to be stable and may be - * extended in the future. + * GPtrArray of GValueArrays representing a list of NetworkManager IPv6 addresses + * (which is a tuple of address, prefix, and gateway). The specific format of + * this serialization is not guaranteed to be stable and may be extended in the + * future. **/ void nm_utils_ip6_addresses_to_gvalue (GSList *list, GValue *value) @@ -1541,8 +1566,9 @@ nm_utils_ip6_addresses_to_gvalue (GSList *list, GValue *value) GValue element = {0, }; GByteArray *ba; - array = g_value_array_new (2); + array = g_value_array_new (3); + /* IP address */ g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); ba = g_byte_array_new (); g_byte_array_append (ba, (guint8 *) nm_ip6_address_get_address (addr), 16); @@ -1550,11 +1576,20 @@ nm_utils_ip6_addresses_to_gvalue (GSList *list, GValue *value) g_value_array_append (array, &element); g_value_unset (&element); + /* Prefix */ g_value_init (&element, G_TYPE_UINT); g_value_set_uint (&element, nm_ip6_address_get_prefix (addr)); g_value_array_append (array, &element); g_value_unset (&element); + /* Gateway */ + g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY); + ba = g_byte_array_new (); + g_byte_array_append (ba, (guint8 *) nm_ip6_address_get_gateway (addr), 16); + g_value_take_boxed (&element, ba); + g_value_array_append (array, &element); + g_value_unset (&element); + g_ptr_array_add (addresses, array); }